From: Frederic Riss Date: Wed, 5 Aug 2015 22:33:28 +0000 (+0000) Subject: [dsymutil] Add support for the -arch option. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1b709aa2a37739ffb4b8f9bf72e9db271b0430d7;p=oota-llvm.git [dsymutil] Add support for the -arch option. This option allows to select a subset of the architectures when performing a universal binary link. The filter is done completely in the mach-o specific part of the code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244160 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/dsymutil/Inputs/fat-test.arm.dylib b/test/tools/dsymutil/Inputs/fat-test.arm.dylib new file mode 100755 index 00000000000..a8d4f37be4d Binary files /dev/null and b/test/tools/dsymutil/Inputs/fat-test.arm.dylib differ diff --git a/test/tools/dsymutil/Inputs/fat-test.arm.o b/test/tools/dsymutil/Inputs/fat-test.arm.o new file mode 100644 index 00000000000..1cf16803e89 Binary files /dev/null and b/test/tools/dsymutil/Inputs/fat-test.arm.o differ diff --git a/test/tools/dsymutil/arch-option.test b/test/tools/dsymutil/arch-option.test new file mode 100644 index 00000000000..4068bc24c8f --- /dev/null +++ b/test/tools/dsymutil/arch-option.test @@ -0,0 +1,39 @@ +Processing of the -arch option happens at debug map parsing time, thus just +looking at the dumped debug maps is enough to validate their effects. + +RUN: llvm-dsymutil -oso-prepend-path %p -dump-debug-map %p/Inputs/fat-test.arm.dylib | FileCheck %s -check-prefix=ARM64 -check-prefix=ARMV7S -check-prefix=ARMV7 -check-prefix=CHECK +RUN: llvm-dsymutil -oso-prepend-path %p -dump-debug-map %p/Inputs/fat-test.arm.dylib -arch all | FileCheck %s -check-prefix=ARM64 -check-prefix=ARMV7S -check-prefix=ARMV7 -check-prefix=CHECK +RUN: llvm-dsymutil -oso-prepend-path %p -dump-debug-map %p/Inputs/fat-test.arm.dylib -arch '*' | FileCheck %s -check-prefix=ARM64 -check-prefix=ARMV7S -check-prefix=ARMV7 -check-prefix=CHECK +RUN: llvm-dsymutil -oso-prepend-path %p -dump-debug-map %p/Inputs/fat-test.arm.dylib -arch arm64 | FileCheck %s -check-prefix=ARM64 -check-prefix=CHECK +RUN: llvm-dsymutil -oso-prepend-path %p -dump-debug-map %p/Inputs/fat-test.arm.dylib -arch arm | FileCheck %s -check-prefix=ARMV7S -check-prefix=ARMV7 -check-prefix=CHECK +RUN: llvm-dsymutil -oso-prepend-path %p -dump-debug-map %p/Inputs/fat-test.arm.dylib -arch armv7 | FileCheck %s -check-prefix=ARMV7 -check-prefix=CHECK +RUN: llvm-dsymutil -oso-prepend-path %p -dump-debug-map %p/Inputs/fat-test.arm.dylib -arch arm64 -arch armv7s | FileCheck %s -check-prefix=ARM64 -check-prefix=ARMV7S -check-prefix=CHECK +RUN: not llvm-dsymutil -oso-prepend-path %p -dump-debug-map %p/Inputs/fat-test.arm.dylib -arch arm42 2>&1 | FileCheck %s -check-prefix=BADARCH +RUN: not llvm-dsymutil -oso-prepend-path %p -dump-debug-map %p/Inputs/fat-test.arm.dylib -arch i386 2>&1 | FileCheck %s -check-prefix=EMPTY + + +ARMV7: --- +ARMV7-NOT: ... +ARMV7: triple: 'thumbv7-apple-darwin' +ARMV7-NOT: ... +ARMV7: sym: _armv7_var +ARMV7-NOT: --- + +ARMV7S: --- +ARMV7S-NOT: ... +ARMV7S: triple: 'thumbv7s-apple-darwin' +ARMV7S-NOT: ... +ARMV7S: sym: _armv7s_var +ARMV7S-NOT: --- + +ARM64: --- +ARM64-NOT: ... +ARM64: triple: 'arm64-apple-darwin' +ARM64-NOT: ... +ARM64: sym: _arm64_var +ARM64-NOT: --- + +CHECK: ... + +BADARCH: error: Unsupported cpu architecture: 'arm42' +EMPTY: error: no architecture to link diff --git a/tools/dsymutil/MachODebugMapParser.cpp b/tools/dsymutil/MachODebugMapParser.cpp index aa034cb683c..cd427cb1d94 100644 --- a/tools/dsymutil/MachODebugMapParser.cpp +++ b/tools/dsymutil/MachODebugMapParser.cpp @@ -21,11 +21,11 @@ using namespace llvm::object; class MachODebugMapParser { public: - MachODebugMapParser(StringRef BinaryPath, StringRef PathPrefix = "", - bool Verbose = false) - : BinaryPath(BinaryPath), PathPrefix(PathPrefix), - MainBinaryHolder(Verbose), CurrentObjectHolder(Verbose), - CurrentDebugMapObject(nullptr) {} + MachODebugMapParser(StringRef BinaryPath, ArrayRef Archs, + StringRef PathPrefix = "", bool Verbose = false) + : BinaryPath(BinaryPath), Archs(Archs.begin(), Archs.end()), + PathPrefix(PathPrefix), MainBinaryHolder(Verbose), + CurrentObjectHolder(Verbose), CurrentDebugMapObject(nullptr) {} /// \brief Parses and returns the DebugMaps of the input binary. /// The binary contains multiple maps in case it is a universal @@ -36,6 +36,7 @@ public: private: std::string BinaryPath; + SmallVector Archs; std::string PathPrefix; /// Owns the MemoryBuffer for the main binary. @@ -133,6 +134,19 @@ MachODebugMapParser::parseOneBinary(const MachOObjectFile &MainBinary, return std::move(Result); } +static bool shouldLinkArch(SmallVectorImpl &Archs, StringRef Arch) { + if (Archs.empty() || + std::find(Archs.begin(), Archs.end(), "all") != Archs.end() || + std::find(Archs.begin(), Archs.end(), "*") != Archs.end()) + return true; + + if (Arch.startswith("arm") && Arch != "arm64" && + std::find(Archs.begin(), Archs.end(), "arm") != Archs.end()) + return true; + + return std::find(Archs.begin(), Archs.end(), Arch) != Archs.end(); +} + /// This main parsing routine tries to open the main binary and if /// successful iterates over the STAB entries. The real parsing is /// done in handleStabSymbolTableEntry. @@ -143,8 +157,10 @@ ErrorOr>> MachODebugMapParser::parse() { return Error; std::vector> Results; + Triple T; for (const auto *Binary : *MainBinOrError) - Results.push_back(parseOneBinary(*Binary, BinaryPath)); + if (shouldLinkArch(Archs, Binary->getArch(nullptr, &T).getArchName())) + Results.push_back(parseOneBinary(*Binary, BinaryPath)); return std::move(Results); } @@ -266,10 +282,10 @@ void MachODebugMapParser::loadMainBinarySymbols( namespace llvm { namespace dsymutil { llvm::ErrorOr>> -parseDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose, - bool InputIsYAML) { +parseDebugMap(StringRef InputFile, ArrayRef Archs, + StringRef PrependPath, bool Verbose, bool InputIsYAML) { if (!InputIsYAML) { - MachODebugMapParser Parser(InputFile, PrependPath, Verbose); + MachODebugMapParser Parser(InputFile, Archs, PrependPath, Verbose); return Parser.parse(); } else { return DebugMap::parseYAMLDebugMap(InputFile, PrependPath, Verbose); diff --git a/tools/dsymutil/dsymutil.cpp b/tools/dsymutil/dsymutil.cpp index 48eb9a14f0a..581da4ebfa0 100644 --- a/tools/dsymutil/dsymutil.cpp +++ b/tools/dsymutil/dsymutil.cpp @@ -15,6 +15,7 @@ #include "DebugMap.h" #include "MachOUtils.h" #include "dsymutil.h" +#include "llvm/Object/MachO.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Options.h" @@ -54,6 +55,14 @@ static opt desc("Do the link in memory, but do not emit the result file."), init(false), cat(DsymCategory)); +static list ArchFlags( + "arch", + desc("Link DWARF debug information only for specified CPU architecture\n" + "types. This option can be specified multiple times, once for each\n" + "desired architecture. All cpu architectures will be linked by\n" + "default."), + ZeroOrMore, cat(DsymCategory)); + static opt NoODR("no-odr", desc("Do not use ODR (One Definition Rule) for type uniquing."), @@ -138,9 +147,16 @@ int main(int argc, char **argv) { return 1; } + for (const auto &Arch : ArchFlags) + if (Arch != "*" && Arch != "all" && + !llvm::object::MachOObjectFile::isValidArch(Arch)) { + llvm::errs() << "error: Unsupported cpu architecture: '" << Arch << "'\n"; + exitDsymutil(1); + } + for (auto &InputFile : InputFiles) { - auto DebugMapPtrsOrErr = - parseDebugMap(InputFile, OsoPrependPath, Verbose, InputIsYAMLDebugMap); + auto DebugMapPtrsOrErr = parseDebugMap(InputFile, ArchFlags, OsoPrependPath, + Verbose, InputIsYAMLDebugMap); if (auto EC = DebugMapPtrsOrErr.getError()) { llvm::errs() << "error: cannot parse the debug map for \"" << InputFile @@ -148,6 +164,11 @@ int main(int argc, char **argv) { exitDsymutil(1); } + if (DebugMapPtrsOrErr->empty()) { + llvm::errs() << "error: no architecture to link\n"; + exitDsymutil(1); + } + // If there is more than one link to execute, we need to generate // temporary files. bool NeedsTempFiles = !DumpDebugMap && (*DebugMapPtrsOrErr).size() != 1; diff --git a/tools/dsymutil/dsymutil.h b/tools/dsymutil/dsymutil.h index 82f0deeb2e0..239439a6a86 100644 --- a/tools/dsymutil/dsymutil.h +++ b/tools/dsymutil/dsymutil.h @@ -36,8 +36,8 @@ struct LinkOptions { /// The file has to be a MachO object file. Multiple debug maps can be /// returned when the file is universal (aka fat) binary. llvm::ErrorOr>> -parseDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose, - bool InputIsYAML); +parseDebugMap(StringRef InputFile, ArrayRef Archs, + StringRef PrependPath, bool Verbose, bool InputIsYAML); /// \brief Link the Dwarf debuginfo as directed by the passed DebugMap /// \p DM into a DwarfFile named \p OutputFilename.