diff options
author | Robert Nagy <robert@cvs.openbsd.org> | 2022-01-13 19:05:01 +0000 |
---|---|---|
committer | Robert Nagy <robert@cvs.openbsd.org> | 2022-01-13 19:05:01 +0000 |
commit | 62b2e727a7fbb4cf4261e49c2c98430928bf3f59 (patch) | |
tree | d55f8ea8dffc96c7483d24de123a444933cf323a /gnu/llvm | |
parent | c03ef375994026f9e0831d8a7dfa49514973eeea (diff) |
add a dummy -t flag to llvm-ranlib to match binutils' ranlib's -t flag which
is a no-op; ok millert@
Diffstat (limited to 'gnu/llvm')
-rw-r--r-- | gnu/llvm/llvm/tools/llvm-ar/llvm-ar.cpp | 205 |
1 files changed, 139 insertions, 66 deletions
diff --git a/gnu/llvm/llvm/tools/llvm-ar/llvm-ar.cpp b/gnu/llvm/llvm/tools/llvm-ar/llvm-ar.cpp index 516cc2626b5..c2e553d9934 100644 --- a/gnu/llvm/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/gnu/llvm/llvm/tools/llvm-ar/llvm-ar.cpp @@ -14,17 +14,22 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/BinaryFormat/Magic.h" #include "llvm/IR/LLVMContext.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ArchiveWriter.h" +#include "llvm/Object/IRObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Object/SymbolicFile.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Errc.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/Host.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/LineIterator.h" #include "llvm/Support/MemoryBuffer.h" @@ -82,6 +87,9 @@ OPTIONS: =bsd - bsd --plugin=<string> - ignored for compatibility -h --help - display this help and exit + --rsp-quoting - quoting style for response files + =posix - posix + =windows - windows --version - print the version and exit @<file> - read options from <file> @@ -117,10 +125,10 @@ MODIFIERS: [V] - display the version and exit )"; -void printHelpMessage() { - if (Stem.contains_lower("ranlib")) +static void printHelpMessage() { + if (Stem.contains_insensitive("ranlib")) outs() << RanlibHelp; - else if (Stem.contains_lower("ar")) + else if (Stem.contains_insensitive("ar")) outs() << ArHelp; } @@ -262,7 +270,8 @@ static void getArchive() { } static object::Archive &readLibrary(const Twine &Library) { - auto BufOrErr = MemoryBuffer::getFile(Library, -1, false); + auto BufOrErr = MemoryBuffer::getFile(Library, /*IsText=*/false, + /*RequiresNullTerminator=*/false); failIfError(BufOrErr.getError(), "could not open library " + Library); ArchiveBuffers.push_back(std::move(*BufOrErr)); auto LibOrErr = @@ -512,13 +521,13 @@ static std::string normalizePath(StringRef Path) { static bool comparePaths(StringRef Path1, StringRef Path2) { // When on Windows this function calls CompareStringOrdinal -// as Windows file paths are case-insensitive. +// as Windows file paths are case-insensitive. // CompareStringOrdinal compares two Unicode strings for // binary equivalence and allows for case insensitivity. #ifdef _WIN32 SmallVector<wchar_t, 128> WPath1, WPath2; - failIfError(sys::path::widenPath(normalizePath(Path1), WPath1)); - failIfError(sys::path::widenPath(normalizePath(Path2), WPath2)); + failIfError(sys::windows::UTF8ToUTF16(normalizePath(Path1), WPath1)); + failIfError(sys::windows::UTF8ToUTF16(normalizePath(Path2), WPath2)); return CompareStringOrdinal(WPath1.data(), WPath1.size(), WPath2.data(), WPath2.size(), true) == CSTR_EQUAL; @@ -649,7 +658,7 @@ static void addChildMember(std::vector<NewArchiveMember> &Members, // the archive it's in, so the file resolves correctly. if (Thin && FlattenArchive) { StringSaver Saver(Alloc); - Expected<std::string> FileNameOrErr = M.getName(); + Expected<std::string> FileNameOrErr(M.getName()); failIfError(FileNameOrErr.takeError()); if (sys::path::is_absolute(*FileNameOrErr)) { NMOrErr->MemberName = Saver.save(sys::path::convert_to_slash(*FileNameOrErr)); @@ -791,7 +800,7 @@ computeNewArchiveMembers(ArchiveOperation Operation, int Pos = Ret.size(); Expected<StringRef> NameOrErr = Child.getName(); failIfError(NameOrErr.takeError()); - std::string Name = NameOrErr.get(); + std::string Name = std::string(NameOrErr.get()); if (comparePaths(Name, RelPos)) { assert(AddAfter || AddBefore); if (AddBefore) @@ -870,8 +879,9 @@ static object::Archive::Kind getDefaultForHost() { } static object::Archive::Kind getKindFromMember(const NewArchiveMember &Member) { + auto MemBufferRef = Member.Buf->getMemBufferRef(); Expected<std::unique_ptr<object::ObjectFile>> OptionalObject = - object::ObjectFile::createObjectFile(Member.Buf->getMemBufferRef()); + object::ObjectFile::createObjectFile(MemBufferRef); if (OptionalObject) return isa<object::MachOObjectFile>(**OptionalObject) @@ -880,6 +890,23 @@ static object::Archive::Kind getKindFromMember(const NewArchiveMember &Member) { // squelch the error in case we had a non-object file consumeError(OptionalObject.takeError()); + + // If we're adding a bitcode file to the archive, detect the Archive kind + // based on the target triple. + LLVMContext Context; + if (identify_magic(MemBufferRef.getBuffer()) == file_magic::bitcode) { + if (auto ObjOrErr = object::SymbolicFile::createSymbolicFile( + MemBufferRef, file_magic::bitcode, &Context)) { + auto &IRObject = cast<object::IRObjectFile>(**ObjOrErr); + return Triple(IRObject.getTargetTriple()).isOSDarwin() + ? object::Archive::K_DARWIN + : object::Archive::K_GNU; + } else { + // Squelch the error in case this was not a SymbolicFile. + consumeError(ObjOrErr.takeError()); + } + } + return getDefaultForHost(); } @@ -969,11 +996,11 @@ static void performOperation(ArchiveOperation Operation, static int performOperation(ArchiveOperation Operation, std::vector<NewArchiveMember> *NewMembers) { // Create or open the archive object. - ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = - MemoryBuffer::getFile(ArchiveName, -1, false); + ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFile( + ArchiveName, /*IsText=*/false, /*RequiresNullTerminator=*/false); std::error_code EC = Buf.getError(); if (EC && EC != errc::no_such_file_or_directory) - fail("error opening '" + ArchiveName + "': " + EC.message()); + fail("unable to open '" + ArchiveName + "': " + EC.message()); if (!EC) { Error Err = Error::success(); @@ -988,7 +1015,7 @@ static int performOperation(ArchiveOperation Operation, assert(EC == errc::no_such_file_or_directory); if (!shouldCreateArchive(Operation)) { - failIfError(EC, Twine("error loading '") + ArchiveName + "'"); + failIfError(EC, Twine("unable to load '") + ArchiveName + "'"); } else { if (!Create) { // Produce a warning if we should and we're creating the archive @@ -1057,7 +1084,7 @@ static void runMRIScript() { fail("editing multiple archives not supported"); if (Saved) fail("file already saved"); - ArchiveName = Rest; + ArchiveName = std::string(Rest); break; case MRICommand::Delete: { llvm::erase_if(NewMembers, [=](NewArchiveMember &M) { @@ -1074,9 +1101,9 @@ static void runMRIScript() { fail("unknown command: " + CommandStr); } } - + ParsingMRIScript = false; - + // Nothing to do if not saved. if (Saved) performOperation(ReplaceOrInsert, &NewMembers); @@ -1095,61 +1122,103 @@ static bool handleGenericOption(StringRef arg) { return false; } +static const char *matchFlagWithArg(StringRef Expected, + ArrayRef<const char *>::iterator &ArgIt, + ArrayRef<const char *> Args) { + StringRef Arg = *ArgIt; + + if (Arg.startswith("--")) + Arg = Arg.substr(2); + else if (Arg.startswith("-")) + Arg = Arg.substr(1); + + size_t len = Expected.size(); + if (Arg == Expected) { + if (++ArgIt == Args.end()) + fail(std::string(Expected) + " requires an argument"); + + return *ArgIt; + } + if (Arg.startswith(Expected) && Arg.size() > len && Arg[len] == '=') + return Arg.data() + len + 1; + + return nullptr; +} + +static cl::TokenizerCallback getRspQuoting(ArrayRef<const char *> ArgsArr) { + cl::TokenizerCallback Ret = + Triple(sys::getProcessTriple()).getOS() == Triple::Win32 + ? cl::TokenizeWindowsCommandLine + : cl::TokenizeGNUCommandLine; + + for (ArrayRef<const char *>::iterator ArgIt = ArgsArr.begin(); + ArgIt != ArgsArr.end(); ++ArgIt) { + if (const char *Match = matchFlagWithArg("rsp-quoting", ArgIt, ArgsArr)) { + StringRef MatchRef = Match; + if (MatchRef == "posix") + Ret = cl::TokenizeGNUCommandLine; + else if (MatchRef == "windows") + Ret = cl::TokenizeWindowsCommandLine; + else + fail(std::string("Invalid response file quoting style ") + Match); + } + } + + return Ret; +} + static int ar_main(int argc, char **argv) { - SmallVector<const char *, 0> Argv(argv, argv + argc); + SmallVector<const char *, 0> Argv(argv + 1, argv + argc); StringSaver Saver(Alloc); - cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv); - for (size_t i = 1; i < Argv.size(); ++i) { - StringRef Arg = Argv[i]; - const char *match = nullptr; - auto MatchFlagWithArg = [&](const char *expected) { - size_t len = strlen(expected); - if (Arg == expected) { - if (++i >= Argv.size()) - fail(std::string(expected) + " requires an argument"); - match = Argv[i]; - return true; - } - if (Arg.startswith(expected) && Arg.size() > len && Arg[len] == '=') { - match = Arg.data() + len + 1; - return true; - } - return false; - }; - if (handleGenericOption(Argv[i])) + + cl::ExpandResponseFiles(Saver, getRspQuoting(makeArrayRef(argv, argc)), Argv); + + for (ArrayRef<const char *>::iterator ArgIt = Argv.begin(); + ArgIt != Argv.end(); ++ArgIt) { + const char *Match = nullptr; + + if (handleGenericOption(*ArgIt)) return 0; - if (Arg == "--") { - for (; i < Argv.size(); ++i) - PositionalArgs.push_back(Argv[i]); + if (strcmp(*ArgIt, "--") == 0) { + ++ArgIt; + for (; ArgIt != Argv.end(); ++ArgIt) + PositionalArgs.push_back(*ArgIt); break; } - if (Arg[0] == '-') { - if (Arg.startswith("--")) - Arg = Argv[i] + 2; + + if (*ArgIt[0] != '-') { + if (Options.empty()) + Options += *ArgIt; else - Arg = Argv[i] + 1; - if (Arg == "M") { - MRI = true; - } else if (MatchFlagWithArg("format")) { - FormatType = StringSwitch<Format>(match) - .Case("default", Default) - .Case("gnu", GNU) - .Case("darwin", DARWIN) - .Case("bsd", BSD) - .Default(Unknown); - if (FormatType == Unknown) - fail(std::string("Invalid format ") + match); - } else if (MatchFlagWithArg("plugin")) { - // Ignored. - } else { - Options += Argv[i] + 1; - } - } else if (Options.empty()) { - Options += Argv[i]; - } else { - PositionalArgs.push_back(Argv[i]); + PositionalArgs.push_back(*ArgIt); + continue; + } + + if (strcmp(*ArgIt, "-M") == 0) { + MRI = true; + continue; + } + + Match = matchFlagWithArg("format", ArgIt, Argv); + if (Match) { + FormatType = StringSwitch<Format>(Match) + .Case("default", Default) + .Case("gnu", GNU) + .Case("darwin", DARWIN) + .Case("bsd", BSD) + .Default(Unknown); + if (FormatType == Unknown) + fail(std::string("Invalid format ") + Match); + continue; } + + if (matchFlagWithArg("plugin", ArgIt, Argv) || + matchFlagWithArg("rsp-quoting", ArgIt, Argv)) + continue; + + Options += *ArgIt + 1; } + ArchiveOperation Operation = parseCommandLine(); return performOperation(Operation, nullptr); } @@ -1173,8 +1242,12 @@ static int ranlib_main(int argc, char **argv) { } else if (arg.front() == 'v') { cl::PrintVersionMessage(); return 0; + } else if (arg.front() == 't') { + // GNU ranlib also supports a -t flag, but does nothing + // because it just returns true without touching the + // timestamp, so simulate the same behaviour. + return 0; } else { - // TODO: GNU ranlib also supports a -t flag fail("Invalid option: '-" + arg + "'"); } arg = arg.drop_front(1); @@ -1207,7 +1280,7 @@ int main(int argc, char **argv) { // Lib.exe -> lib (see D44808, MSBuild runs Lib.exe) // dlltool.exe -> dlltool // arm-pokymllib32-linux-gnueabi-llvm-ar-10 -> ar - auto I = Stem.rfind_lower(Tool); + auto I = Stem.rfind_insensitive(Tool); return I != StringRef::npos && (I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()])); }; |