[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
This commit is contained in:
Frederic Riss 2015-08-05 22:33:28 +00:00
parent 0f57ff737c
commit 1b709aa2a3
6 changed files with 89 additions and 13 deletions

Binary file not shown.

Binary file not shown.

View File

@ -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

View File

@ -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<std::string> 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<StringRef, 1> 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<StringRef> &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<std::vector<std::unique_ptr<DebugMap>>> MachODebugMapParser::parse() {
return Error;
std::vector<std::unique_ptr<DebugMap>> 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<std::vector<std::unique_ptr<DebugMap>>>
parseDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose,
bool InputIsYAML) {
parseDebugMap(StringRef InputFile, ArrayRef<std::string> 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);

View File

@ -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<bool>
desc("Do the link in memory, but do not emit the result file."),
init(false), cat(DsymCategory));
static list<std::string> 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<bool>
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;

View File

@ -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<std::vector<std::unique_ptr<DebugMap>>>
parseDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose,
bool InputIsYAML);
parseDebugMap(StringRef InputFile, ArrayRef<std::string> 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.