From ae0d4365454456203a6f284c5d0e6ed994883c86 Mon Sep 17 00:00:00 2001 From: Frederic Riss Date: Wed, 5 Aug 2015 22:33:28 +0000 Subject: [PATCH] [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. llvm-svn: 244160 --- llvm/test/tools/dsymutil/Inputs/fat-test.arm.dylib | Bin 0 -> 25180 bytes llvm/test/tools/dsymutil/Inputs/fat-test.arm.o | Bin 0 -> 50736 bytes llvm/test/tools/dsymutil/arch-option.test | 39 +++++++++++++++++++++ llvm/tools/dsymutil/MachODebugMapParser.cpp | 34 +++++++++++++----- llvm/tools/dsymutil/dsymutil.cpp | 25 +++++++++++-- llvm/tools/dsymutil/dsymutil.h | 4 +-- 6 files changed, 89 insertions(+), 13 deletions(-) create mode 100755 llvm/test/tools/dsymutil/Inputs/fat-test.arm.dylib create mode 100644 llvm/test/tools/dsymutil/Inputs/fat-test.arm.o create mode 100644 llvm/test/tools/dsymutil/arch-option.test diff --git a/llvm/test/tools/dsymutil/Inputs/fat-test.arm.dylib b/llvm/test/tools/dsymutil/Inputs/fat-test.arm.dylib new file mode 100755 index 0000000000000000000000000000000000000000..a8d4f37be4dea45ec9e97186b332a5826a9b3880 GIT binary patch literal 25180 zcmeI4&r4N76vxj?v&2dlQbwDnP+;T_qF;j46`tV3=m#jZyO~cRNG*MdL5mmBpHR3g za?vW>1ua^HD;Kp0TDU2MRuQyn(L(xu@4a*1^c1ziNcbK&cjnBSGc)%yt2yu7SzLMb z+RUn;d!V(@KC^~7udNRDH|TS=W#WFQHqV*`3rRnF`{V118=wY_aI)?lW)H2w;A8io zVK~rxbpRD#8WIELPE@JvPYJ`~$V@S=$99Fk=UeWDTD6s&U7kDFGtlE&QPS7>qe=kO z^4!A{V`CHJXo@5ZSNm5dzu`4gasF&z{R}h=&*v}n_vZ5M-Lq&+<|k7 zXdfLawiQRFitR&_W9@~zH*Z`wYcVTzqThys`5MuQYvs62u(?myQ07o_zb-*3{ywnJ zpU5FNah@y9bIl*_pIm<0n)y`oZ0X}+v|&mJXE8ehrQL`JdA24t*C!DH5fA|p5CIVo z0TB=Z5fA|p_zwwWLYzvcPlwY(leVwQO4)dgJZ~0~ibb2tqKgQ}C=k zk3}+{f^rZ#3tcm(f*k@rJPG2u|KC1aHq5a|{9qjcey(I^PkuZ9 zB8Z)tGvI`K=){jxu#M|t{9sj#ql89E5Ixg!Au-pAd3548<~I0q{1Smmax*wY%VzU4 zf_O~61INz7=DwFu=1^``en#Jc{s%7?&viW-o|!M?znm?{J$7MMv!hTy6~pDFSioP) z;_^6}0<+y{c6l6p4~YnffCz|y2#A0Ph=2%)fCz|y2#A0Ph=2%)fCz|y2#A0Ph=2%) zfCz|y2#A0Ph=2%)fCz|y2#A0Ph=2%)fCz|y2#A0Ph=2%)fCz|y2#A0Ph=2%)fCy}B z0?|DMr%uH8DdHphlK-`Ne2>4oOOfyC->pbHx?d4rsPleB+WsAjv^ko)XOTAV|BLQ0 X2x#H^^Ym`TP2RVdES1+7BvtzfTBz?% literal 0 HcmV?d00001 diff --git a/llvm/test/tools/dsymutil/Inputs/fat-test.arm.o b/llvm/test/tools/dsymutil/Inputs/fat-test.arm.o new file mode 100644 index 0000000000000000000000000000000000000000..1cf16803e892f1f0492cff72b12b3bcb7c388f34 GIT binary patch literal 50736 zcmeI5&u<$=6vtY4@ldMyQxB*wb|XI z1#$4PXT-69#0do45eF1bNF3mwXeBPaaiN5i@0*=<9DD6-QdRWuebW4%`R>eTXMKCm zzwP|=vr=jZsem-1)I5sp9b`o$>B}qCLXrIxS<#C6P~AexRiqDzMgk;20wh2JBtQZr zKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{ z0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JB=7_Tet-0E$2k5g`1Y$|q>4ooRt;d-ITNJ-G^vQrqo#TRvYrX zZjC1T=8(n(KI~dHVvlOiK77Z!=?1+T-{_S}T{jx0DMg2d(`?pV+jG`MqGunX@itN# zjmFA{8fy1h?qmHZ(!I3%XgalSjU%{IqOp}iBmB6Tc$P_Mya$c@12v*MR$ud6Ozq(j zK;sPh&)|J@S)1t?29D~%Xp#)Pf^;2CELU}uCWwZ5U(f5!WZproR>wssZMuH2*6>Qx z<+*aDG#>gJ-mTKP>h$dF%!FEX!l}>=!g5WWUG|zAVW1p;eRI~{bbPhuh01!-8Y>>l z4i%5)P9lg$rmBXD%g5d=oX@|N&peNyAfxDbC!d$^x{4GXdRT9_piY}Dmt|xInZyFI zte3O;YZ{tID?6-~E-x&}f;b5av8bKX_4BWNGA`ech)Dk_-K+Mjm9Fl!k71qqY37Lj zahV8{jan*)GK=56=+~>#x|^4?&g-%0P;wVxZy;sV>&PwZpW+M1t>_dG>0m8Wqu&G+ z1v4X~uc5umUr%C20wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2J zBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0$l`R|9|m* z6<<~HQ%&Rl{}m>S@4b}&m;e6-?Da|f|7E?{zuIFts++v+-yO#g=;!}08sfX0Mx&qq z|3_Fa{{IukSN$;l|KDQ0m}4}emd-oQGT8rLG{pZujYdEJ{|8t`CJ$pipc zz==}^09gO-kKr;ST;+TRdIc{{I#6nJ!6>QYVlSeC+j@WMAu* z@NG7J)^Yo=F#%%XSTAm)Y<1M}U+t0ab`biyyZb-nPi#SMt{jGu67y?!wSnr0*7zc03B_V*Wj*Uc+R+@FuXk#_?*|Kin! zOBbWX$iHvbqRRHZ=N%kdAl8fbmsYP|oPj^h{zgqXH^4_rw;oT~ot4`0(&P=FPC!7l1AS~C^*=4V}5eCZf z*JrAS3QHhyGop)qL~pmCPMf`!Wn>0f70I$rjI^VC49%k_WoUxiKm7ffe4`>H4>*M+ zwsd)6N!t3MC=1dFi~4fvG3=moWUagtG1;u8awxNi$s%tFp$J-c^KzJZB$+F9b6*b< gnn1@Z!TO@?xhO)$q>7Yjf9m$`d#Q)(%?if<103qn=Kufz literal 0 HcmV?d00001 diff --git a/llvm/test/tools/dsymutil/arch-option.test b/llvm/test/tools/dsymutil/arch-option.test new file mode 100644 index 0000000..4068bc2 --- /dev/null +++ b/llvm/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/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp index aa034cb..cd427cb 100644 --- a/llvm/tools/dsymutil/MachODebugMapParser.cpp +++ b/llvm/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/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index 48eb9a1..581da4e 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/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/llvm/tools/dsymutil/dsymutil.h b/llvm/tools/dsymutil/dsymutil.h index 82f0dee..239439a 100644 --- a/llvm/tools/dsymutil/dsymutil.h +++ b/llvm/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. -- 2.7.4