[llvm] ffecb64 - [objdump] Support finding --source via --dsym files
Francis Visoiu Mistrih via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 4 11:16:02 PDT 2022
Author: Jim Radford
Date: 2022-10-04T11:15:51-07:00
New Revision: ffecb643ee2c49e55e0689339b6d5921b5e6ff8b
URL: https://github.com/llvm/llvm-project/commit/ffecb643ee2c49e55e0689339b6d5921b5e6ff8b
DIFF: https://github.com/llvm/llvm-project/commit/ffecb643ee2c49e55e0689339b6d5921b5e6ff8b.diff
LOG: [objdump] Support finding --source via --dsym files
Add support for auto-detecting or specifying dSYM files/directories to
allow interleaving source with disassembly.
Differential Revision: https://reviews.llvm.org/D135117
Patch by Jim Radford.
Added:
llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test
Modified:
llvm/tools/llvm-objdump/MachODump.cpp
llvm/tools/llvm-objdump/MachODump.h
llvm/tools/llvm-objdump/llvm-objdump.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test b/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test
new file mode 100644
index 0000000000000..aaaf6bffe4a33
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test
@@ -0,0 +1,16 @@
+## objdump --source w/ explicit .dSYM
+# RUN: dsymutil -f %p/../../dsymutil/Inputs/basic.macho.x86_64 -o %t1.dSYM -oso-prepend-path=%p/../../dsymutil
+# RUN: llvm-objdump < %p/../../dsymutil/Inputs/basic.macho.x86_64 - --source --dsym=%t1.dSYM --prefix=%p/../../dsymutil | \
+# RUN: FileCheck --check-prefix=SOURCE %s
+
+## objdump --source w/ auto-detected .dSYM (dir)
+# RUN: cp -f %p/../../dsymutil/Inputs/basic.macho.x86_64 %t2
+# RUN: dsymutil -oso-prepend-path=%p/../../dsymutil/ %t2
+# RUN: llvm-objdump --source --prefix=%p/../../dsymutil %t2 | FileCheck --check-prefix=SOURCE %s
+
+## objdump --source w/ auto-detected .dSYM (file)
+# RUN: cp -f %p/../../dsymutil/Inputs/basic.macho.x86_64 %t3
+# RUN: dsymutil -f -oso-prepend-path=%p/../../dsymutil/ %t3 -o %t3.dSYM
+# RUN: llvm-objdump --source --prefix=%p/../../dsymutil %t3 | FileCheck --check-prefix=SOURCE %s
+
+# SOURCE: ; int bar(int arg) {
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index a5d611e99b38e..4637b09787b74 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -7387,6 +7387,108 @@ static void emitComments(raw_svector_ostream &CommentStream,
CommentsToEmit.clear();
}
+const MachOObjectFile *
+objdump::getMachODSymObject(const MachOObjectFile *MachOOF, StringRef Filename,
+ std::unique_ptr<Binary> &DSYMBinary,
+ std::unique_ptr<MemoryBuffer> &DSYMBuf) {
+ const MachOObjectFile *DbgObj = MachOOF;
+ std::string DSYMPath;
+
+ // Auto-detect w/o --dsym.
+ if (DSYMFile.empty()) {
+ sys::fs::file_status DSYMStatus;
+ Twine FilenameDSYM = Filename + ".dSYM";
+ if (!status(FilenameDSYM, DSYMStatus)) {
+ if (sys::fs::is_directory(DSYMStatus)) {
+ SmallString<1024> Path;
+ FilenameDSYM.toVector(Path);
+ sys::path::append(Path, "Contents", "Resources", "DWARF",
+ sys::path::filename(Filename));
+ DSYMPath = std::string(Path);
+ } else if (sys::fs::is_regular_file(DSYMStatus)) {
+ DSYMPath = FilenameDSYM.str();
+ }
+ }
+ }
+
+ if (DSYMPath.empty() && !DSYMFile.empty()) {
+ // If DSYMPath is a .dSYM directory, append the Mach-O file.
+ if (sys::fs::is_directory(DSYMFile) &&
+ sys::path::extension(DSYMFile) == ".dSYM") {
+ SmallString<128> ShortName(sys::path::filename(DSYMFile));
+ sys::path::replace_extension(ShortName, "");
+ SmallString<1024> FullPath(DSYMFile);
+ sys::path::append(FullPath, "Contents", "Resources", "DWARF", ShortName);
+ DSYMPath = FullPath.str();
+ } else {
+ DSYMPath = DSYMFile;
+ }
+ }
+
+ if (!DSYMPath.empty()) {
+ // Load the file.
+ ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
+ MemoryBuffer::getFileOrSTDIN(DSYMPath);
+ if (std::error_code EC = BufOrErr.getError()) {
+ reportError(errorCodeToError(EC), DSYMPath);
+ return nullptr;
+ }
+
+ // We need to keep the file alive, because we're replacing DbgObj with it.
+ DSYMBuf = std::move(BufOrErr.get());
+
+ Expected<std::unique_ptr<Binary>> BinaryOrErr =
+ createBinary(DSYMBuf.get()->getMemBufferRef());
+ if (!BinaryOrErr) {
+ reportError(BinaryOrErr.takeError(), DSYMPath);
+ return nullptr;
+ }
+
+ // We need to keep the Binary alive with the buffer
+ DSYMBinary = std::move(BinaryOrErr.get());
+ if (ObjectFile *O = dyn_cast<ObjectFile>(DSYMBinary.get())) {
+ // this is a Mach-O object file, use it
+ if (MachOObjectFile *MachDSYM = dyn_cast<MachOObjectFile>(&*O)) {
+ DbgObj = MachDSYM;
+ } else {
+ WithColor::error(errs(), "llvm-objdump")
+ << DSYMPath << " is not a Mach-O file type.\n";
+ return nullptr;
+ }
+ } else if (auto *UB = dyn_cast<MachOUniversalBinary>(DSYMBinary.get())) {
+ // this is a Universal Binary, find a Mach-O for this architecture
+ uint32_t CPUType, CPUSubType;
+ const char *ArchFlag;
+ if (MachOOF->is64Bit()) {
+ const MachO::mach_header_64 H_64 = MachOOF->getHeader64();
+ CPUType = H_64.cputype;
+ CPUSubType = H_64.cpusubtype;
+ } else {
+ const MachO::mach_header H = MachOOF->getHeader();
+ CPUType = H.cputype;
+ CPUSubType = H.cpusubtype;
+ }
+ Triple T = MachOObjectFile::getArchTriple(CPUType, CPUSubType, nullptr,
+ &ArchFlag);
+ Expected<std::unique_ptr<MachOObjectFile>> MachDSYM =
+ UB->getMachOObjectForArch(ArchFlag);
+ if (!MachDSYM) {
+ reportError(MachDSYM.takeError(), DSYMPath);
+ return nullptr;
+ }
+
+ // We need to keep the Binary alive with the buffer
+ DbgObj = &*MachDSYM.get();
+ DSYMBinary = std::move(*MachDSYM);
+ } else {
+ WithColor::error(errs(), "llvm-objdump")
+ << DSYMPath << " is not a Mach-O or Universal file type.\n";
+ return nullptr;
+ }
+ }
+ return DbgObj;
+}
+
static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
StringRef DisSegName, StringRef DisSectName) {
const char *McpuDefault = nullptr;
@@ -7561,90 +7663,15 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
std::unique_ptr<Binary> DSYMBinary;
std::unique_ptr<MemoryBuffer> DSYMBuf;
if (UseDbg) {
- ObjectFile *DbgObj = MachOOF;
-
- // A separate DSym file path was specified, parse it as a macho file,
+ // If separate DSym file path was specified, parse it as a macho file,
// get the sections and supply it to the section name parsing machinery.
- if (!DSYMFile.empty()) {
- std::string DSYMPath(DSYMFile);
-
- // If DSYMPath is a .dSYM directory, append the Mach-O file.
- if (llvm::sys::fs::is_directory(DSYMPath) &&
- llvm::sys::path::extension(DSYMPath) == ".dSYM") {
- SmallString<128> ShortName(llvm::sys::path::filename(DSYMPath));
- llvm::sys::path::replace_extension(ShortName, "");
- SmallString<1024> FullPath(DSYMPath);
- llvm::sys::path::append(FullPath, "Contents", "Resources", "DWARF",
- ShortName);
- DSYMPath = std::string(FullPath.str());
- }
-
- // Load the file.
- ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
- MemoryBuffer::getFileOrSTDIN(DSYMPath);
- if (std::error_code EC = BufOrErr.getError()) {
- reportError(errorCodeToError(EC), DSYMPath);
- return;
- }
-
- // We need to keep the file alive, because we're replacing DbgObj with it.
- DSYMBuf = std::move(BufOrErr.get());
-
- Expected<std::unique_ptr<Binary>> BinaryOrErr =
- createBinary(DSYMBuf.get()->getMemBufferRef());
- if (!BinaryOrErr) {
- reportError(BinaryOrErr.takeError(), DSYMPath);
- return;
- }
-
- // We need to keep the Binary alive with the buffer
- DSYMBinary = std::move(BinaryOrErr.get());
- if (ObjectFile *O = dyn_cast<ObjectFile>(DSYMBinary.get())) {
- // this is a Mach-O object file, use it
- if (MachOObjectFile *MachDSYM = dyn_cast<MachOObjectFile>(&*O)) {
- DbgObj = MachDSYM;
- }
- else {
- WithColor::error(errs(), "llvm-objdump")
- << DSYMPath << " is not a Mach-O file type.\n";
- return;
- }
- }
- else if (auto UB = dyn_cast<MachOUniversalBinary>(DSYMBinary.get())){
- // this is a Universal Binary, find a Mach-O for this architecture
- uint32_t CPUType, CPUSubType;
- const char *ArchFlag;
- if (MachOOF->is64Bit()) {
- const MachO::mach_header_64 H_64 = MachOOF->getHeader64();
- CPUType = H_64.cputype;
- CPUSubType = H_64.cpusubtype;
- } else {
- const MachO::mach_header H = MachOOF->getHeader();
- CPUType = H.cputype;
- CPUSubType = H.cpusubtype;
- }
- Triple T = MachOObjectFile::getArchTriple(CPUType, CPUSubType, nullptr,
- &ArchFlag);
- Expected<std::unique_ptr<MachOObjectFile>> MachDSYM =
- UB->getMachOObjectForArch(ArchFlag);
- if (!MachDSYM) {
- reportError(MachDSYM.takeError(), DSYMPath);
- return;
- }
-
- // We need to keep the Binary alive with the buffer
- DbgObj = &*MachDSYM.get();
- DSYMBinary = std::move(*MachDSYM);
- }
- else {
- WithColor::error(errs(), "llvm-objdump")
- << DSYMPath << " is not a Mach-O or Universal file type.\n";
- return;
- }
+ if (const ObjectFile *DbgObj =
+ getMachODSymObject(MachOOF, Filename, DSYMBinary, DSYMBuf)) {
+ // Setup the DIContext
+ diContext = DWARFContext::create(*DbgObj);
+ } else {
+ return;
}
-
- // Setup the DIContext
- diContext = DWARFContext::create(*DbgObj);
}
if (FilterSections.empty())
diff --git a/llvm/tools/llvm-objdump/MachODump.h b/llvm/tools/llvm-objdump/MachODump.h
index 32920425e80f3..2e2c2b8b7cc59 100644
--- a/llvm/tools/llvm-objdump/MachODump.h
+++ b/llvm/tools/llvm-objdump/MachODump.h
@@ -16,12 +16,14 @@ namespace llvm {
class Error;
class StringRef;
+class MemoryBuffer;
namespace object {
class MachOObjectFile;
class MachOUniversalBinary;
class ObjectFile;
class RelocationRef;
+class Binary;
} // namespace object
namespace opt {
@@ -61,6 +63,11 @@ Error getMachORelocationValueString(const object::MachOObjectFile *Obj,
const object::RelocationRef &RelRef,
llvm::SmallVectorImpl<char> &Result);
+const object::MachOObjectFile *
+getMachODSymObject(const object::MachOObjectFile *O, StringRef Filename,
+ std::unique_ptr<object::Binary> &DSYMBinary,
+ std::unique_ptr<MemoryBuffer> &DSYMBuf);
+
void parseInputMachO(StringRef Filename);
void parseInputMachO(object::MachOUniversalBinary *UB);
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index a06e644dec3b1..0c1bb0b29b87c 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1287,7 +1287,8 @@ fetchBinaryByBuildID(const ObjectFile &Obj) {
}
static void disassembleObject(const Target *TheTarget, ObjectFile &Obj,
- MCContext &Ctx, MCDisassembler *PrimaryDisAsm,
+ const ObjectFile &DbgObj, MCContext &Ctx,
+ MCDisassembler *PrimaryDisAsm,
MCDisassembler *SecondaryDisAsm,
const MCInstrAnalysis *MIA, MCInstPrinter *IP,
const MCSubtargetInfo *PrimarySTI,
@@ -1412,7 +1413,7 @@ static void disassembleObject(const Target *TheTarget, ObjectFile &Obj,
LiveVariablePrinter LVP(*Ctx.getRegisterInfo(), *STI);
if (DbgVariables != DVDisabled) {
- DICtx = DWARFContext::create(Obj);
+ DICtx = DWARFContext::create(DbgObj);
for (const std::unique_ptr<DWARFUnit> &CU : DICtx->compile_units())
LVP.addCompileUnit(CU->getUnitDIE(false));
}
@@ -2071,13 +2072,14 @@ static void disassembleObject(ObjectFile *Obj, bool InlineRelocs) {
IP->setMCInstrAnalysis(MIA.get());
PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
- ObjectFile *DbgObj = Obj;
+
+ const ObjectFile *DbgObj = Obj;
OwningBinary<Binary> DebugBinary;
- if (!Obj->hasDebugInfo()) {
+ if (!DbgObj->hasDebugInfo()) {
if (Optional<OwningBinary<Binary>> DebugBinaryOpt =
fetchBinaryByBuildID(*Obj)) {
- if (ObjectFile *FetchedObj =
- dyn_cast<ObjectFile>(DebugBinaryOpt->getBinary())) {
+ if (auto *FetchedObj =
+ dyn_cast<const ObjectFile>(DebugBinaryOpt->getBinary())) {
if (FetchedObj->hasDebugInfo()) {
DebugBinary = std::move(*DebugBinaryOpt);
DbgObj = FetchedObj;
@@ -2085,6 +2087,18 @@ static void disassembleObject(ObjectFile *Obj, bool InlineRelocs) {
}
}
}
+
+ std::unique_ptr<object::Binary> DSYMBinary;
+ std::unique_ptr<MemoryBuffer> DSYMBuf;
+ if (!DbgObj->hasDebugInfo()) {
+ if (const MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*Obj)) {
+ DbgObj = objdump::getMachODSymObject(MachOOF, Obj->getFileName(),
+ DSYMBinary, DSYMBuf);
+ if (!DbgObj)
+ return;
+ }
+ }
+
SourcePrinter SP(DbgObj, TheTarget->getName());
for (StringRef Opt : DisassemblerOptions)
@@ -2092,9 +2106,9 @@ static void disassembleObject(ObjectFile *Obj, bool InlineRelocs) {
reportError(Obj->getFileName(),
"Unrecognized disassembler option: " + Opt);
- disassembleObject(TheTarget, *Obj, Ctx, DisAsm.get(), SecondaryDisAsm.get(),
- MIA.get(), IP.get(), STI.get(), SecondarySTI.get(), PIP, SP,
- InlineRelocs);
+ disassembleObject(TheTarget, *Obj, *DbgObj, Ctx, DisAsm.get(),
+ SecondaryDisAsm.get(), MIA.get(), IP.get(), STI.get(),
+ SecondarySTI.get(), PIP, SP, InlineRelocs);
}
void objdump::printRelocations(const ObjectFile *Obj) {
More information about the llvm-commits
mailing list