summaryrefslogtreecommitdiff
path: root/tools/llvm-dwarfdump
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2017-09-21 16:26:18 +0000
committerAdrian Prantl <aprantl@apple.com>2017-09-21 16:26:18 +0000
commitab669421b20cbd5e5de2544d04781d0d1fc7c23b (patch)
tree148ff1055d3df10ee2a96ddca05b4ae96eb9c3a9 /tools/llvm-dwarfdump
parent2462b0299b02493822434ba165930c8feeb59dd1 (diff)
llvm-dwarfdump: Add support for the --arch command line option.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313888 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-dwarfdump')
-rw-r--r--tools/llvm-dwarfdump/llvm-dwarfdump.cpp73
1 files changed, 57 insertions, 16 deletions
diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 0f75f36af7e..5c9fe2421be 100644
--- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -126,6 +126,13 @@ static std::array<llvm::Optional<uint64_t>, (unsigned)DIDT_ID_Count>
static alias DumpDebugFrameAlias("eh-frame", desc("Alias for -debug-frame"),
NotHidden, cat(SectionCategory),
aliasopt(DumpDebugFrame));
+static list<std::string>
+ ArchFilters("arch",
+ desc("Dump debug information for the specified CPU "
+ "architecture only. Architectures may be specified by "
+ "name or by number. This option can be specified "
+ "multiple times, once for each desired architecture."),
+ cat(DwarfDumpCategory));
static opt<bool> DumpUUID("uuid", desc("Show the UUID for each architecture"),
cat(DwarfDumpCategory));
static alias DumpUUIDAlias("u", desc("Alias for -uuid"), aliasopt(DumpUUID));
@@ -190,28 +197,55 @@ static DIDumpOptions getDumpOpts() {
return DumpOpts;
}
-static bool dumpObjectFile(ObjectFile &Obj, Twine Filename) {
- std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(Obj);
- logAllUnhandledErrors(DICtx->loadRegisterInfo(Obj), errs(),
+static uint32_t getCPUType(MachOObjectFile &MachO) {
+ if (MachO.is64Bit())
+ return MachO.getHeader64().cputype;
+ else
+ return MachO.getHeader().cputype;
+}
+
+/// Return true if the object file has not been filtered by an --arch option.
+static bool filterArch(ObjectFile &Obj) {
+ if (ArchFilters.empty())
+ return true;
+ if (auto *MachO = dyn_cast<MachOObjectFile>(&Obj)) {
+ std::string ObjArch =
+ Triple::getArchTypeName(MachO->getArchTriple().getArch());
+ for (auto Arch : ArchFilters) {
+ if (Arch == ObjArch)
+ return true;
+ unsigned Value;
+ if (!StringRef(Arch).getAsInteger(0, Value))
+ if (Value == getCPUType(*MachO))
+ return true;
+ }
+ }
+ return false;
+}
+
+using HandlerFn = std::function<bool(ObjectFile &, DWARFContext &DICtx, Twine)>;
+
+static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
+ Twine Filename) {
+ logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
Filename.str() + ": ");
// The UUID dump already contains all the same information.
if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
outs() << Filename << ":\tfile format " << Obj.getFileFormatName() << '\n';
// Dump the complete DWARF structure.
- DICtx->dump(outs(), getDumpOpts(), DumpOffsets);
+ DICtx.dump(outs(), getDumpOpts(), DumpOffsets);
return true;
}
-static bool verifyObjectFile(ObjectFile &Obj, Twine Filename) {
- std::unique_ptr<DIContext> DICtx = DWARFContext::create(Obj);
-
+static bool verifyObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
+ Twine Filename) {
// Verify the DWARF and exit with non-zero exit status if verification
// fails.
raw_ostream &stream = Quiet ? nulls() : outs();
stream << "Verifying " << Filename.str() << ":\tfile format "
<< Obj.getFileFormatName() << "\n";
- bool Result = DICtx->verify(stream, getDumpOpts());
+ bool Result = DICtx.verify(stream, getDumpOpts());
if (Result)
stream << "No errors.\n";
else
@@ -220,10 +254,10 @@ static bool verifyObjectFile(ObjectFile &Obj, Twine Filename) {
}
static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
- std::function<bool(ObjectFile &, Twine)> HandleObj);
+ HandlerFn HandleObj);
static bool handleArchive(StringRef Filename, Archive &Arch,
- std::function<bool(ObjectFile &, Twine)> HandleObj) {
+ HandlerFn HandleObj) {
bool Result = true;
Error Err = Error::success();
for (auto Child : Arch.children(Err)) {
@@ -240,19 +274,27 @@ static bool handleArchive(StringRef Filename, Archive &Arch,
}
static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
- std::function<bool(ObjectFile &, Twine)> HandleObj) {
+ HandlerFn HandleObj) {
Expected<std::unique_ptr<Binary>> BinOrErr = object::createBinary(Buffer);
error(Filename, errorToErrorCode(BinOrErr.takeError()));
bool Result = true;
- if (auto *Obj = dyn_cast<ObjectFile>(BinOrErr->get()))
- Result = HandleObj(*Obj, Filename);
+ if (auto *Obj = dyn_cast<ObjectFile>(BinOrErr->get())) {
+ if (filterArch(*Obj)) {
+ std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(*Obj);
+ Result = HandleObj(*Obj, *DICtx, Filename);
+ }
+ }
else if (auto *Fat = dyn_cast<MachOUniversalBinary>(BinOrErr->get()))
for (auto &ObjForArch : Fat->objects()) {
std::string ObjName =
(Filename + "(" + ObjForArch.getArchFlagName() + ")").str();
if (auto MachOOrErr = ObjForArch.getAsObjectFile()) {
- Result &= HandleObj(**MachOOrErr, ObjName);
+ auto &Obj = **MachOOrErr;
+ if (filterArch(Obj)) {
+ std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(Obj);
+ Result &= HandleObj(Obj, *DICtx, ObjName);
+ }
continue;
} else
consumeError(MachOOrErr.takeError());
@@ -268,8 +310,7 @@ static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
return Result;
}
-static bool handleFile(StringRef Filename,
- std::function<bool(ObjectFile &, Twine)> HandleObj) {
+static bool handleFile(StringRef Filename, HandlerFn HandleObj) {
ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
MemoryBuffer::getFileOrSTDIN(Filename);
error(Filename, BuffOrErr.getError());