diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index da972a2433e..ed7aabd2c86 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -44,6 +44,11 @@ public: virtual unsigned getArch() const; virtual StringRef getLoadName() const; + // In a MachO file, sections have a segment name. This is used in the .o + // files. They have a single segment, but this field specifies which segment + // a section should be put in in the final object. + error_code getSectionFinalSegmentName(DataRefImpl Sec, StringRef &Res) const; + MachOObject *getObject() { return MachOObj.get(); } static inline bool classof(const Binary *v) { diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 40f5390a96f..3e29b2f9a41 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -473,28 +473,43 @@ static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { return false; } +static StringRef parseSegmentOrSectionName(const char *P) { + if (P[15] == 0) + // Null terminated. + return P; + // Not null terminated, so this is a 16 char string. + return StringRef(P, 16); +} + error_code MachOObjectFile::getSectionName(DataRefImpl DRI, StringRef &Result) const { - // FIXME: thread safety. - static char result[34]; if (is64BitLoadCommand(MachOObj.get(), DRI)) { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); InMemoryStruct Sect; MachOObj->ReadSection64(LCI, DRI.d.b, Sect); - - strcpy(result, Sect->SegmentName); - strcat(result, ","); - strcat(result, Sect->Name); + Result = parseSegmentOrSectionName(Sect->Name); } else { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); InMemoryStruct Sect; MachOObj->ReadSection(LCI, DRI.d.b, Sect); - - strcpy(result, Sect->SegmentName); - strcat(result, ","); - strcat(result, Sect->Name); + Result = parseSegmentOrSectionName(Sect->Name); + } + return object_error::success; +} + +error_code MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec, + StringRef &Res) const { + if (is64BitLoadCommand(MachOObj.get(), Sec)) { + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(Sec.d.a); + InMemoryStruct Sect; + MachOObj->ReadSection64(LCI, Sec.d.b, Sect); + Res = parseSegmentOrSectionName(Sect->SegmentName); + } else { + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(Sec.d.a); + InMemoryStruct Sect; + MachOObj->ReadSection(LCI, Sec.d.b, Sect); + Res = parseSegmentOrSectionName(Sect->SegmentName); } - Result = StringRef(result); return object_error::success; } diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 3a350382ae1..c324ff13a6b 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -334,9 +334,15 @@ void llvm::DisassembleInputMachO(StringRef Filename) { for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) { StringRef SectName; if (Sections[SectIdx].getName(SectName) || - SectName.compare("__TEXT,__text")) + SectName != "__text") continue; // Skip non-text sections + StringRef SegmentName; + DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl(); + if (MachOOF->getSectionFinalSegmentName(DR, SegmentName) || + SegmentName != "__TEXT") + continue; + // Insert the functions from the function starts segment into our map. uint64_t VMAddr; Sections[SectIdx].getAddress(VMAddr); diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 2838a2a2b30..24dc9c91a3b 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -28,6 +28,7 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Object/Archive.h" #include "llvm/Object/COFF.h" +#include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" @@ -72,9 +73,9 @@ static cl::opt SymbolTable("t", cl::desc("Display the symbol table")); static cl::opt -MachO("macho", cl::desc("Use MachO specific object file parser")); +MachOOpt("macho", cl::desc("Use MachO specific object file parser")); static cl::alias -MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO)); +MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachOOpt)); cl::opt llvm::TripleName("triple", cl::desc("Target triple to disassemble for, " @@ -241,9 +242,18 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { // Sort relocations by address. std::sort(Rels.begin(), Rels.end(), RelocAddressLess); + StringRef SegmentName = ""; + if (const MachOObjectFile *MachO = dyn_cast(Obj)) { + DataRefImpl DR = i->getRawDataRefImpl(); + if (error(MachO->getSectionFinalSegmentName(DR, SegmentName))) + break; + } StringRef name; if (error(i->getName(name))) break; - outs() << "Disassembly of section " << name << ':'; + outs() << "Disassembly of section "; + if (!SegmentName.empty()) + outs() << SegmentName << ","; + outs() << name << ':'; // If the section has no symbols just insert a dummy one and disassemble // the whole section. @@ -567,6 +577,13 @@ static void PrintSymbolTable(const ObjectFile *o) { else if (Section == o->end_sections()) outs() << "*UND*"; else { + if (const MachOObjectFile *MachO = dyn_cast(o)) { + StringRef SegmentName; + DataRefImpl DR = Section->getRawDataRefImpl(); + if (error(MachO->getSectionFinalSegmentName(DR, SegmentName))) + SegmentName = ""; + outs() << SegmentName << ","; + } StringRef SectionName; if (error(Section->getName(SectionName))) SectionName = ""; @@ -640,7 +657,7 @@ static void DumpInput(StringRef file) { return; } - if (MachO && Disassemble) { + if (MachOOpt && Disassemble) { DisassembleInputMachO(file); return; }