From d02ad93cf9ae153a9191485fadf950cc2b1a2878 Mon Sep 17 00:00:00 2001 From: Ryan Mansfield Date: Thu, 16 Oct 2025 09:06:52 -0400 Subject: [PATCH 1/2] [llvm-objdump] Fix --source with --macho flag The --source option was broken when using the --macho flag because DisassembleMachO() only initialized debug info when UseDbg was true, and would return early if no dSYM was found. --- .../MachO/disassemble-source-dsym.test | 12 +++++++ llvm/tools/llvm-objdump/MachODump.cpp | 32 +++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test b/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test index aaaf6bffe4a33..f7fb621244338 100644 --- a/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test +++ b/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test @@ -13,4 +13,16 @@ # 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 +## Test that --source works with --macho flag + +## --macho w/ explicit .dSYM +# RUN: llvm-objdump < %p/../../dsymutil/Inputs/basic.macho.x86_64 - --source --macho --dsym=%t1.dSYM --prefix=%p/../../dsymutil | \ +# RUN: FileCheck --check-prefix=SOURCE %s + +## --macho w/ auto-detected .dSYM (dir) +# RUN: llvm-objdump --source --macho --prefix=%p/../../dsymutil %t2 | FileCheck --check-prefix=SOURCE %s + +## --macho w/ auto-detected .dSYM (file) +# RUN: llvm-objdump --source --macho --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 8e9c91fde544d..2d1259191c580 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -13,6 +13,7 @@ #include "MachODump.h" #include "ObjdumpOptID.h" +#include "SourcePrinter.h" #include "llvm-objdump.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" @@ -7415,18 +7416,24 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, std::unique_ptr diContext; std::unique_ptr DSYMBinary; std::unique_ptr DSYMBuf; - if (UseDbg) { - // 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 (const ObjectFile *DbgObj = - getMachODSymObject(MachOOF, Filename, DSYMBinary, DSYMBuf)) { + const ObjectFile *DbgObj = MachOOF; + if (UseDbg || PrintSource || PrintLines) { + // Look for debug info in external dSYM file or embedded in the object. + // getMachODSymObject returns MachOOF by default if no external dSYM found. + const ObjectFile *DSym = + getMachODSymObject(MachOOF, Filename, DSYMBinary, DSYMBuf); + if (!DSym) + return; + DbgObj = DSym; + if (UseDbg) { // Setup the DIContext diContext = DWARFContext::create(*DbgObj); - } else { - return; } } + SourcePrinter SP(DbgObj, TheTarget->getName()); + LiveElementPrinter LEP(*MRI, *STI); + if (FilterSections.empty()) outs() << "(" << DisSegName << "," << DisSectName << ") section\n"; @@ -7605,6 +7612,12 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, outs() << SymName << ":\n"; uint64_t PC = SectAddress + Index; + + if (PrintSource || PrintLines) { + formatted_raw_ostream FOS(outs()); + SP.printSourceLine(FOS, {PC, SectIdx}, Filename, LEP); + } + if (LeadingAddr) { if (FullLeadingAddr) { if (MachOOF->is64Bit()) @@ -7696,6 +7709,11 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, uint64_t PC = SectAddress + Index; + if (PrintSource || PrintLines) { + formatted_raw_ostream FOS(outs()); + SP.printSourceLine(FOS, {PC, SectIdx}, Filename, LEP); + } + if (DumpAndSkipDataInCode(PC, Bytes.data() + Index, Dices, InstSize)) continue; From 3ac6dbfe5785f95b2400b8e06d30ffeea3e68f59 Mon Sep 17 00:00:00 2001 From: Ryan Mansfield Date: Mon, 20 Oct 2025 08:45:08 -0400 Subject: [PATCH 2/2] Address reviewer feedback. Fix --line-numbers with --macho and add test. Use std::optional to defer initialization of SourcePrinter/LiveElementPrinter. --- .../MachO/disassemble-source-dsym.test | 21 ++++++++++++++++++- llvm/tools/llvm-objdump/MachODump.cpp | 14 ++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test b/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test index f7fb621244338..9899dc5d41043 100644 --- a/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test +++ b/llvm/test/tools/llvm-objdump/MachO/disassemble-source-dsym.test @@ -13,7 +13,7 @@ # 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 -## Test that --source works with --macho flag +## Test that --source works with --macho flag. ## --macho w/ explicit .dSYM # RUN: llvm-objdump < %p/../../dsymutil/Inputs/basic.macho.x86_64 - --source --macho --dsym=%t1.dSYM --prefix=%p/../../dsymutil | \ @@ -26,3 +26,22 @@ # RUN: llvm-objdump --source --macho --prefix=%p/../../dsymutil %t3 | FileCheck --check-prefix=SOURCE %s # SOURCE: ; int bar(int arg) { + +## Test that --line-numbers works with --macho flag. + +## --macho -l w/ explicit .dSYM +# RUN: llvm-objdump -d -l --macho --dsym=%t1.dSYM %p/../../dsymutil/Inputs/basic.macho.x86_64 | FileCheck --check-prefix=LINE %s + +## --macho -l w/ object file (embedded debug info) +# RUN: llvm-objdump -d -l --macho %p/../../dsymutil/Inputs/basic1.macho.x86_64.o | FileCheck --check-prefix=LINE_OBJ %s + +# LINE: (__TEXT,__text) section +# LINE: _bar: +# LINE: ; bar(): +# LINE: ; {{.*}}basic3.c: + +# LINE_OBJ: (__TEXT,__text) section +# LINE_OBJ: _main: +# LINE_OBJ: ; main(): +# LINE_OBJ: ; {{.*}}basic1.c:23 +# LINE_OBJ: pushq %rbp ## basic1.c:23:0 diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 2d1259191c580..f633ed52943da 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -7425,14 +7425,18 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, if (!DSym) return; DbgObj = DSym; - if (UseDbg) { + if (UseDbg || PrintLines) { // Setup the DIContext diContext = DWARFContext::create(*DbgObj); } } - SourcePrinter SP(DbgObj, TheTarget->getName()); - LiveElementPrinter LEP(*MRI, *STI); + std::optional SP; + std::optional LEP; + if (PrintSource || PrintLines) { + SP.emplace(DbgObj, TheTarget->getName()); + LEP.emplace(*MRI, *STI); + } if (FilterSections.empty()) outs() << "(" << DisSegName << "," << DisSectName << ") section\n"; @@ -7615,7 +7619,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, if (PrintSource || PrintLines) { formatted_raw_ostream FOS(outs()); - SP.printSourceLine(FOS, {PC, SectIdx}, Filename, LEP); + SP->printSourceLine(FOS, {PC, SectIdx}, Filename, *LEP); } if (LeadingAddr) { @@ -7711,7 +7715,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, if (PrintSource || PrintLines) { formatted_raw_ostream FOS(outs()); - SP.printSourceLine(FOS, {PC, SectIdx}, Filename, LEP); + SP->printSourceLine(FOS, {PC, SectIdx}, Filename, *LEP); } if (DumpAndSkipDataInCode(PC, Bytes.data() + Index, Dices, InstSize))