Skip to content

Commit f72d001

Browse files
committed
llvm-objdump should ignore Mach-O stab symbols for disassembly.
Summary: llvm-objdump will commonly error out when disassembling a Mach-O binary with stab symbols, or when printing a Mach-O symbol table that includesstab symbols. That is because the Mach-O N_OSO symbol has been modified to include the bottom 8-bit value of the Mach-O's cpusubtype value in the section field. In general, one cannot blindly assume a stab symbol's section field is valid unless one has actually consulted the specification for the specific stab. Since objdump mostly just walks the symbol table to get mnemonics for code disassembly it's best for objdump to just ignore stab symbols. llvm-nm will do a more complete and correct job of displaying Mach-O symbol table contents. Reviewers: pete, lhames, ab, thegameg, jhenderson, MaskRay Reviewed By: thegameg, MaskRay Subscribers: MaskRay, rupprecht, seiya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71394
1 parent adf7a0a commit f72d001

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed
Binary file not shown.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# RUN: llvm-objdump --syms %p/Inputs/macho-stabs-x86_64
2+
# RUN: llvm-objdump -D %p/Inputs/macho-stabs-x86_64

llvm/tools/llvm-objdump/llvm-objdump.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,7 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
11341134
std::map<SectionRef, SectionSymbolsTy> AllSymbols;
11351135
SectionSymbolsTy AbsoluteSymbols;
11361136
const StringRef FileName = Obj->getFileName();
1137+
const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj);
11371138
for (const SymbolRef &Symbol : Obj->symbols()) {
11381139
uint64_t Address = unwrapOrError(Symbol.getAddress(), FileName);
11391140

@@ -1148,6 +1149,18 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
11481149
continue;
11491150
}
11501151

1152+
// Don't ask a Mach-O STAB symbol for its section unless you know that
1153+
// STAB symbol's section field refers to a valid section index. Otherwise
1154+
// the symbol may error trying to load a section that does not exist.
1155+
if (MachO) {
1156+
DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1157+
uint8_t NType = (MachO->is64Bit() ?
1158+
MachO->getSymbol64TableEntry(SymDRI).n_type:
1159+
MachO->getSymbolTableEntry(SymDRI).n_type);
1160+
if (NType & MachO::N_STAB)
1161+
continue;
1162+
}
1163+
11511164
section_iterator SecI = unwrapOrError(Symbol.getSection(), FileName);
11521165
if (SecI != Obj->section_end())
11531166
AllSymbols[*SecI].emplace_back(Address, Name, SymbolType);
@@ -1244,7 +1257,7 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
12441257
}
12451258

12461259
StringRef SegmentName = "";
1247-
if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) {
1260+
if (MachO) {
12481261
DataRefImpl DR = Section.getRawDataRefImpl();
12491262
SegmentName = MachO->getSectionFinalSegmentName(DR);
12501263
}
@@ -1804,6 +1817,7 @@ void printSymbolTable(const ObjectFile *O, StringRef ArchiveName,
18041817
}
18051818

18061819
const StringRef FileName = O->getFileName();
1820+
const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(O);
18071821
for (auto I = O->symbol_begin(), E = O->symbol_end(); I != E; ++I) {
18081822
const SymbolRef &Symbol = *I;
18091823
uint64_t Address = unwrapOrError(Symbol.getAddress(), FileName, ArchiveName,
@@ -1813,8 +1827,23 @@ void printSymbolTable(const ObjectFile *O, StringRef ArchiveName,
18131827
SymbolRef::Type Type = unwrapOrError(Symbol.getType(), FileName,
18141828
ArchiveName, ArchitectureName);
18151829
uint32_t Flags = Symbol.getFlags();
1816-
section_iterator Section = unwrapOrError(Symbol.getSection(), FileName,
1830+
1831+
// Don't ask a Mach-O STAB symbol for its section unless you know that
1832+
// STAB symbol's section field refers to a valid section index. Otherwise
1833+
// the symbol may error trying to load a section that does not exist.
1834+
bool isSTAB = false;
1835+
if (MachO) {
1836+
DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1837+
uint8_t NType = (MachO->is64Bit() ?
1838+
MachO->getSymbol64TableEntry(SymDRI).n_type:
1839+
MachO->getSymbolTableEntry(SymDRI).n_type);
1840+
if (NType & MachO::N_STAB)
1841+
isSTAB = true;
1842+
}
1843+
section_iterator Section = isSTAB ? O->section_end() :
1844+
unwrapOrError(Symbol.getSection(), FileName,
18171845
ArchiveName, ArchitectureName);
1846+
18181847
StringRef Name;
18191848
if (Type == SymbolRef::ST_Debug && Section != O->section_end()) {
18201849
if (Expected<StringRef> NameOrErr = Section->getName())

0 commit comments

Comments
 (0)