Finish templating MachObjectFile over endianness.

We are now able to handle big endian macho files in llvm-readobject. Thanks to
David Fang for providing the object files.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179440 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2013-04-13 01:45:40 +00:00
parent 3d60241c3e
commit da2a2372c6
10 changed files with 1352 additions and 592 deletions

File diff suppressed because it is too large Load Diff

View File

@ -29,30 +29,14 @@ using namespace object;
namespace llvm {
namespace object {
MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, bool Is64bits,
MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object,
bool IsLittleEndian, bool Is64bits,
error_code &ec)
: ObjectFile(getMachOType(true, Is64bits), Object) {
: ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
}
bool MachOObjectFileBase::is64Bit() const {
return isa<MachOObjectFile64Le>(this);
}
const MachOObjectFileBase::LoadCommand *
MachOObjectFileBase::getLoadCommandInfo(unsigned Index) const {
uint64_t Offset;
uint64_t NewOffset = getHeaderSize();
const LoadCommand *Load;
unsigned I = 0;
do {
Offset = NewOffset;
StringRef Data = getData(Offset, sizeof(LoadCommand));
Load = reinterpret_cast<const LoadCommand*>(Data.data());
NewOffset = Offset + Load->Size;
++I;
} while (I != Index + 1);
return Load;
return isa<MachOObjectFileLE64>(this) || isa<MachOObjectFileBE64>(this);
}
void MachOObjectFileBase::ReadULEB128s(uint64_t Index,
@ -67,11 +51,6 @@ void MachOObjectFileBase::ReadULEB128s(uint64_t Index,
}
}
const MachOObjectFileBase::Header *MachOObjectFileBase::getHeader() const {
StringRef Data = getData(0, sizeof(Header));
return reinterpret_cast<const Header*>(Data.data());
}
unsigned MachOObjectFileBase::getHeaderSize() const {
return is64Bit() ? macho::Header64Size : macho::Header32Size;
}
@ -80,55 +59,21 @@ StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const {
return ObjectFile::getData().substr(Offset, Size);
}
const MachOObjectFileBase::RelocationEntry *
MachOObjectFileBase::getRelocation(DataRefImpl Rel) const {
if (const MachOObjectFile32Le *O = dyn_cast<MachOObjectFile32Le>(this))
return O->getRelocation(Rel);
const MachOObjectFile64Le *O = dyn_cast<MachOObjectFile64Le>(this);
return O->getRelocation(Rel);
}
bool MachOObjectFileBase::isScattered(const RelocationEntry *RE) const {
unsigned Arch = getArch();
return (Arch != Triple::x86_64) && (RE->Address & macho::RF_Scattered);
}
bool MachOObjectFileBase::isPCRel(const RelocationEntry *RE) const {
if (isScattered(RE)) {
const ScatteredRelocationEntry *SRE =
reinterpret_cast<const ScatteredRelocationEntry *>(RE);
return SRE->getPCRel();
}
return RE->getPCRel();
}
unsigned MachOObjectFileBase::getLength(const RelocationEntry *RE) const {
if (isScattered(RE)) {
const ScatteredRelocationEntry *SRE =
reinterpret_cast<const ScatteredRelocationEntry *>(RE);
return SRE->getLength();
}
return RE->getLength();
}
unsigned MachOObjectFileBase::getType(const RelocationEntry *RE) const {
if (isScattered(RE)) {
const ScatteredRelocationEntry *SRE =
reinterpret_cast<const ScatteredRelocationEntry *>(RE);
return SRE->getType();
}
return RE->getType();
}
ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
StringRef Magic = Buffer->getBuffer().slice(0, 4);
error_code ec;
bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE";
ObjectFile *Ret;
if (Is64Bits)
Ret = new MachOObjectFile64Le(Buffer, ec);
if (Magic == "\xFE\xED\xFA\xCE")
Ret = new MachOObjectFileBE32(Buffer, ec);
else if (Magic == "\xCE\xFA\xED\xFE")
Ret = new MachOObjectFileLE32(Buffer, ec);
else if (Magic == "\xFE\xED\xFA\xCF")
Ret = new MachOObjectFileBE64(Buffer, ec);
else if (Magic == "\xCF\xFA\xED\xFE")
Ret = new MachOObjectFileLE64(Buffer, ec);
else
Ret = new MachOObjectFile32Le(Buffer, ec);
return NULL;
if (ec)
return NULL;
return Ret;
@ -136,183 +81,11 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
/*===-- Symbols -----------------------------------------------------------===*/
void MachOObjectFileBase::moveToNextSymbol(DataRefImpl &DRI) const {
uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
while (DRI.d.a < LoadCommandCount) {
const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
if (Command->Type == macho::LCT_Symtab) {
const SymtabLoadCommand *SymtabLoadCmd =
reinterpret_cast<const SymtabLoadCommand*>(Command);
if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries)
return;
}
DRI.d.a++;
DRI.d.b = 0;
}
}
const MachOObjectFileBase::SymbolTableEntryBase *
MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI) const {
const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
const SymtabLoadCommand *SymtabLoadCmd =
reinterpret_cast<const SymtabLoadCommand*>(Command);
return getSymbolTableEntryBase(DRI, SymtabLoadCmd);
}
const MachOObjectFileBase::SymbolTableEntryBase *
MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI,
const SymtabLoadCommand *SymtabLoadCmd) const {
uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset;
unsigned Index = DRI.d.b;
unsigned SymbolTableEntrySize = is64Bit() ?
sizeof(MachOObjectFile64Le::SymbolTableEntry) :
sizeof(MachOObjectFile32Le::SymbolTableEntry);
uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize;
StringRef Data = getData(Offset, SymbolTableEntrySize);
return reinterpret_cast<const SymbolTableEntryBase*>(Data.data());
}
error_code MachOObjectFileBase::getSymbolNext(DataRefImpl DRI,
SymbolRef &Result) const {
DRI.d.b++;
moveToNextSymbol(DRI);
Result = SymbolRef(DRI, this);
return object_error::success;
}
error_code MachOObjectFileBase::getSymbolName(DataRefImpl DRI,
StringRef &Result) const {
const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
const SymtabLoadCommand *SymtabLoadCmd =
reinterpret_cast<const SymtabLoadCommand*>(Command);
StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset,
SymtabLoadCmd->StringTableSize);
const SymbolTableEntryBase *Entry =
getSymbolTableEntryBase(DRI, SymtabLoadCmd);
uint32_t StringIndex = Entry->StringIndex;
const char *Start = &StringTable.data()[StringIndex];
Result = StringRef(Start);
return object_error::success;
}
error_code MachOObjectFileBase::getSymbolNMTypeChar(DataRefImpl DRI,
char &Result) const {
const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
uint8_t Type = Entry->Type;
uint16_t Flags = Entry->Flags;
char Char;
switch (Type & macho::STF_TypeMask) {
case macho::STT_Undefined:
Char = 'u';
break;
case macho::STT_Absolute:
case macho::STT_Section:
Char = 's';
break;
default:
Char = '?';
break;
}
if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
Char = toupper(static_cast<unsigned char>(Char));
Result = Char;
return object_error::success;
}
error_code MachOObjectFileBase::getSymbolFlags(DataRefImpl DRI,
uint32_t &Result) const {
const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
uint8_t MachOType = Entry->Type;
uint16_t MachOFlags = Entry->Flags;
// TODO: Correctly set SF_ThreadLocal
Result = SymbolRef::SF_None;
if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
Result |= SymbolRef::SF_Undefined;
if (MachOFlags & macho::STF_StabsEntryMask)
Result |= SymbolRef::SF_FormatSpecific;
if (MachOType & MachO::NlistMaskExternal) {
Result |= SymbolRef::SF_Global;
if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
Result |= SymbolRef::SF_Common;
}
if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
Result |= SymbolRef::SF_Weak;
if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)
Result |= SymbolRef::SF_Absolute;
return object_error::success;
}
error_code MachOObjectFileBase::getSymbolSection(DataRefImpl Symb,
section_iterator &Res) const {
const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
uint8_t index = Entry->SectionIndex;
if (index == 0)
Res = end_sections();
else
Res = section_iterator(SectionRef(Sections[index-1], this));
return object_error::success;
}
error_code MachOObjectFileBase::getSymbolType(DataRefImpl Symb,
SymbolRef::Type &Res) const {
const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
uint8_t n_type = Entry->Type;
Res = SymbolRef::ST_Other;
// If this is a STAB debugging symbol, we can do nothing more.
if (n_type & MachO::NlistMaskStab) {
Res = SymbolRef::ST_Debug;
return object_error::success;
}
switch (n_type & MachO::NlistMaskType) {
case MachO::NListTypeUndefined :
Res = SymbolRef::ST_Unknown;
break;
case MachO::NListTypeSection :
Res = SymbolRef::ST_Function;
break;
}
return object_error::success;
}
error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb,
uint64_t &Val) const {
report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase");
}
symbol_iterator MachOObjectFileBase::begin_symbols() const {
// DRI.d.a = segment number; DRI.d.b = symbol index.
DataRefImpl DRI;
moveToNextSymbol(DRI);
return symbol_iterator(SymbolRef(DRI, this));
}
symbol_iterator MachOObjectFileBase::end_symbols() const {
DataRefImpl DRI;
DRI.d.a = getHeader()->NumLoadCommands;
return symbol_iterator(SymbolRef(DRI, this));
}
symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const {
// TODO: implement
report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
@ -347,23 +120,7 @@ std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const {
return std::distance(Sections.begin(), loc);
}
const MachOObjectFileBase::SectionBase*
MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const {
const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(Command);
bool Is64 = is64Bit();
unsigned SegmentLoadSize =
Is64 ? sizeof(MachOObjectFile64Le::SegmentLoadCommand) :
sizeof(MachOObjectFile32Le::SegmentLoadCommand);
unsigned SectionSize = Is64 ? sizeof(MachOObjectFile64Le::Section) :
sizeof(MachOObjectFile32Le::Section);
uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
return reinterpret_cast<const SectionBase*>(SectionAddr);
}
static StringRef parseSegmentOrSectionName(const char *P) {
StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const {
if (P[15] == 0)
// Null terminated.
return P;
@ -371,30 +128,6 @@ static StringRef parseSegmentOrSectionName(const char *P) {
return StringRef(P, 16);
}
ArrayRef<char> MachOObjectFileBase::getSectionRawName(DataRefImpl DRI) const {
const SectionBase *Base = getSectionBase(DRI);
return ArrayRef<char>(Base->Name);
}
error_code MachOObjectFileBase::getSectionName(DataRefImpl DRI,
StringRef &Result) const {
ArrayRef<char> Raw = getSectionRawName(DRI);
Result = parseSegmentOrSectionName(Raw.data());
return object_error::success;
}
ArrayRef<char>
MachOObjectFileBase::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
const SectionBase *Base = getSectionBase(Sec);
return ArrayRef<char>(Base->SegmentName);
}
StringRef
MachOObjectFileBase::getSectionFinalSegmentName(DataRefImpl DRI) const {
ArrayRef<char> Raw = getSectionRawFinalSegmentName(DRI);
return parseSegmentOrSectionName(Raw.data());
}
error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI,
bool &Result) const {
// FIXME: Unimplemented.
@ -441,11 +174,6 @@ relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) con
return relocation_iterator(RelocationRef(ret, this));
}
section_iterator MachOObjectFileBase::end_sections() const {
DataRefImpl DRI;
DRI.d.a = getHeader()->NumLoadCommands;
return section_iterator(SectionRef(DRI, this));
}
/*===-- Relocations -------------------------------------------------------===*/
@ -456,88 +184,6 @@ error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel,
return object_error::success;
}
// Helper to advance a section or symbol iterator multiple increments at a time.
template<class T>
error_code advance(T &it, size_t Val) {
error_code ec;
while (Val--) {
it.increment(ec);
}
return ec;
}
template<class T>
void advanceTo(T &it, size_t Val) {
if (error_code ec = advance(it, Val))
report_fatal_error(ec.message());
}
void
MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE,
raw_string_ostream &fmt) const {
// Target of a scattered relocation is an address. In the interest of
// generating pretty output, scan through the symbol table looking for a
// symbol that aligns with that address. If we find one, print it.
// Otherwise, we just print the hex address of the target.
if (isScattered(RE)) {
uint32_t Val = RE->SymbolNum;
error_code ec;
for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
SI.increment(ec)) {
if (ec) report_fatal_error(ec.message());
uint64_t Addr;
StringRef Name;
if ((ec = SI->getAddress(Addr)))
report_fatal_error(ec.message());
if (Addr != Val) continue;
if ((ec = SI->getName(Name)))
report_fatal_error(ec.message());
fmt << Name;
return;
}
// If we couldn't find a symbol that this relocation refers to, try
// to find a section beginning instead.
for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;
SI.increment(ec)) {
if (ec) report_fatal_error(ec.message());
uint64_t Addr;
StringRef Name;
if ((ec = SI->getAddress(Addr)))
report_fatal_error(ec.message());
if (Addr != Val) continue;
if ((ec = SI->getName(Name)))
report_fatal_error(ec.message());
fmt << Name;
return;
}
fmt << format("0x%x", Val);
return;
}
StringRef S;
bool isExtern = RE->getExternal();
uint32_t Val = RE->Address;
if (isExtern) {
symbol_iterator SI = begin_symbols();
advanceTo(SI, Val);
SI->getName(S);
} else {
section_iterator SI = begin_sections();
advanceTo(SI, Val);
SI->getName(S);
}
fmt << S;
}
error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData,
LibraryRef &Res) const {
report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
@ -561,53 +207,5 @@ uint8_t MachOObjectFileBase::getBytesInAddress() const {
return is64Bit() ? 8 : 4;
}
StringRef MachOObjectFileBase::getFileFormatName() const {
if (!is64Bit()) {
switch (getHeader()->CPUType) {
case llvm::MachO::CPUTypeI386:
return "Mach-O 32-bit i386";
case llvm::MachO::CPUTypeARM:
return "Mach-O arm";
case llvm::MachO::CPUTypePowerPC:
return "Mach-O 32-bit ppc";
default:
assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64) == 0 &&
"64-bit object file when we're not 64-bit?");
return "Mach-O 32-bit unknown";
}
}
// Make sure the cpu type has the correct mask.
assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64)
== llvm::MachO::CPUArchABI64 &&
"32-bit object file when we're 64-bit?");
switch (getHeader()->CPUType) {
case llvm::MachO::CPUTypeX86_64:
return "Mach-O 64-bit x86-64";
case llvm::MachO::CPUTypePowerPC64:
return "Mach-O 64-bit ppc64";
default:
return "Mach-O 64-bit unknown";
}
}
unsigned MachOObjectFileBase::getArch() const {
switch (getHeader()->CPUType) {
case llvm::MachO::CPUTypeI386:
return Triple::x86;
case llvm::MachO::CPUTypeX86_64:
return Triple::x86_64;
case llvm::MachO::CPUTypeARM:
return Triple::arm;
case llvm::MachO::CPUTypePowerPC:
return Triple::ppc;
case llvm::MachO::CPUTypePowerPC64:
return Triple::ppc64;
default:
return Triple::UnknownArch;
}
}
} // end namespace object
} // end namespace llvm

Binary file not shown.

Binary file not shown.

View File

@ -6,6 +6,10 @@ RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-i386 \
RUN: | FileCheck %s -check-prefix MACHO-I386
RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-x86-64 \
RUN: | FileCheck %s -check-prefix MACHO-X86-64
RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-ppc \
RUN: | FileCheck %s -check-prefix MACHO-PPC
RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-ppc64 \
RUN: | FileCheck %s -check-prefix MACHO-PPC64
COFF: Relocations [
COFF-NEXT: Section (1) .text {
@ -40,3 +44,41 @@ MACHO-X86-64-NEXT: 0x9 1 2 1 X86_64_RELOC_BRANCH 0 _puts
MACHO-X86-64-NEXT: 0x4 1 2 1 X86_64_RELOC_SIGNED 0 L_.str
MACHO-X86-64-NEXT: }
MACHO-X86-64-NEXT:]
MACHO-PPC: Relocations [
MACHO-PPC-NEXT: Section __text {
MACHO-PPC-NEXT: 0x24 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
MACHO-PPC-NEXT: 0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
MACHO-PPC-NEXT: 0x1C 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
MACHO-PPC-NEXT: 0x58 0 2 n/a PPC_RELOC_PAIR 1 _b
MACHO-PPC-NEXT: 0x18 1 2 0 PPC_RELOC_BR24 0 _b
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section __picsymbolstub1 {
MACHO-PPC-NEXT: 0x14 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
MACHO-PPC-NEXT: 0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
MACHO-PPC-NEXT: 0xC 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
MACHO-PPC-NEXT: 0x20 0 2 n/a PPC_RELOC_PAIR 1 _b
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section __la_symbol_ptr {
MACHO-PPC-NEXT: 0x0 0 2 1 PPC_RELOC_VANILLA 0 dyld_stub_binding_helper
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: ]
MACHO-PPC64: Relocations [
MACHO-PPC64-NEXT: Section __text {
MACHO-PPC64-NEXT: 0x24 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x0 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x1C 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x58 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x18 1 2 0 0 _b
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section __picsymbolstub1 {
MACHO-PPC64-NEXT: 0x14 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x0 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0xC 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x24 0 2 n/a 1 _b
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section __la_symbol_ptr {
MACHO-PPC64-NEXT: 0x0 0 3 1 0 dyld_stub_binding_helper
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: ]

View File

@ -6,6 +6,10 @@ RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-i386 \
RUN: | FileCheck %s -check-prefix MACHO-I386
RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-x86-64 \
RUN: | FileCheck %s -check-prefix MACHO-X86-64
RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-ppc \
RUN: | FileCheck %s -check-prefix MACHO-PPC
RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-ppc64 \
RUN: | FileCheck %s -check-prefix MACHO-PPC64
COFF: Sections [
COFF-NEXT: Section {
@ -249,3 +253,312 @@ MACHO-X86-64-NEXT: 0000: 48656C6C 6F20576F 726C640A 00 |Hello World.
MACHO-X86-64-NEXT: )
MACHO-X86-64-NEXT: }
MACHO-X86-64-NEXT:]
MACHO-PPC: Sections [
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 0
MACHO-PPC-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x0
MACHO-PPC-NEXT: Size: 0x3C
MACHO-PPC-NEXT: Offset: 528
MACHO-PPC-NEXT: Alignment: 2
MACHO-PPC-NEXT: RelocationOffset: 0x27C
MACHO-PPC-NEXT: RelocationCount: 5
MACHO-PPC-NEXT: Type: 0x0
MACHO-PPC-NEXT: Attributes [ (0x800004)
MACHO-PPC-NEXT: PureInstructions (0x800000)
MACHO-PPC-NEXT: SomeInstructions (0x4)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x0
MACHO-PPC-NEXT: Reserved2: 0x0
MACHO-PPC-NEXT: Relocations [
MACHO-PPC-NEXT: 0x24 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
MACHO-PPC-NEXT: 0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
MACHO-PPC-NEXT: 0x1C 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
MACHO-PPC-NEXT: 0x58 0 2 n/a PPC_RELOC_PAIR 1 _b
MACHO-PPC-NEXT: 0x18 1 2 0 PPC_RELOC_BR24 0 _b
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Symbols [
MACHO-PPC-NEXT: Symbol {
MACHO-PPC-NEXT: Name: _f (4)
MACHO-PPC-NEXT: Type: 0xF
MACHO-PPC-NEXT: Section: __text (0x1)
MACHO-PPC-NEXT: RefType: UndefinedNonLazy (0x0)
MACHO-PPC-NEXT: Flags [ (0x0)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Value: 0x0
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: SectionData (
MACHO-PPC-NEXT: 0000: 7C0802A6 93E1FFFC 429F0005 7FE802A6 ||.......B.......|
MACHO-PPC-NEXT: 0010: 90010008 9421FFB0 48000029 3C5F0000 |.....!..H..)<_..|
MACHO-PPC-NEXT: 0020: 38210050 80420058 80010008 83E1FFFC |8!.P.B.X........|
MACHO-PPC-NEXT: 0030: 7C0803A6 80620000 4E800020 ||....b..N.. |
MACHO-PPC-NEXT: )
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 1
MACHO-PPC-NEXT: Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
MACHO-PPC-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x40
MACHO-PPC-NEXT: Size: 0x20
MACHO-PPC-NEXT: Offset: 592
MACHO-PPC-NEXT: Alignment: 5
MACHO-PPC-NEXT: RelocationOffset: 0x2A4
MACHO-PPC-NEXT: RelocationCount: 4
MACHO-PPC-NEXT: Type: 0x8
MACHO-PPC-NEXT: Attributes [ (0x800004)
MACHO-PPC-NEXT: PureInstructions (0x800000)
MACHO-PPC-NEXT: SomeInstructions (0x4)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x0
MACHO-PPC-NEXT: Reserved2: 0x20
MACHO-PPC-NEXT: Relocations [
MACHO-PPC-NEXT: 0x14 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
MACHO-PPC-NEXT: 0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
MACHO-PPC-NEXT: 0xC 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
MACHO-PPC-NEXT: 0x20 0 2 n/a PPC_RELOC_PAIR 1 _b
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Symbols [
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: SectionData (
MACHO-PPC-NEXT: 0000: 7C0802A6 429F0005 7D6802A6 3D6B0000 ||...B...}h..=k..|
MACHO-PPC-NEXT: 0010: 7C0803A6 858B0020 7D8903A6 4E800420 ||...... }...N.. |
MACHO-PPC-NEXT: )
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 2
MACHO-PPC-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x60
MACHO-PPC-NEXT: Size: 0x4
MACHO-PPC-NEXT: Offset: 624
MACHO-PPC-NEXT: Alignment: 2
MACHO-PPC-NEXT: RelocationOffset: 0x0
MACHO-PPC-NEXT: RelocationCount: 0
MACHO-PPC-NEXT: Type: 0x0
MACHO-PPC-NEXT: Attributes [ (0x0)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x0
MACHO-PPC-NEXT: Reserved2: 0x0
MACHO-PPC-NEXT: Relocations [
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Symbols [
MACHO-PPC-NEXT: Symbol {
MACHO-PPC-NEXT: Name: _b (1)
MACHO-PPC-NEXT: Type: 0xF
MACHO-PPC-NEXT: Section: __data (0x3)
MACHO-PPC-NEXT: RefType: UndefinedNonLazy (0x0)
MACHO-PPC-NEXT: Flags [ (0x0)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Value: 0x60
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: SectionData (
MACHO-PPC-NEXT: 0000: 0000002A |...*|
MACHO-PPC-NEXT: )
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 3
MACHO-PPC-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x64
MACHO-PPC-NEXT: Size: 0x4
MACHO-PPC-NEXT: Offset: 628
MACHO-PPC-NEXT: Alignment: 2
MACHO-PPC-NEXT: RelocationOffset: 0x0
MACHO-PPC-NEXT: RelocationCount: 0
MACHO-PPC-NEXT: Type: 0x6
MACHO-PPC-NEXT: Attributes [ (0x0)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x1
MACHO-PPC-NEXT: Reserved2: 0x0
MACHO-PPC-NEXT: Relocations [
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Symbols [
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: SectionData (
MACHO-PPC-NEXT: 0000: 00000000 |....|
MACHO-PPC-NEXT: )
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 4
MACHO-PPC-NEXT: Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x68
MACHO-PPC-NEXT: Size: 0x4
MACHO-PPC-NEXT: Offset: 632
MACHO-PPC-NEXT: Alignment: 2
MACHO-PPC-NEXT: RelocationOffset: 0x2C4
MACHO-PPC-NEXT: RelocationCount: 1
MACHO-PPC-NEXT: Type: 0x7
MACHO-PPC-NEXT: Attributes [ (0x0)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x2
MACHO-PPC-NEXT: Reserved2: 0x0
MACHO-PPC-NEXT: Relocations [
MACHO-PPC-NEXT: 0x0 0 2 1 PPC_RELOC_VANILLA 0 dyld_stub_binding_helper
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Symbols [
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: SectionData (
MACHO-PPC-NEXT: 0000: 00000000 |....|
MACHO-PPC-NEXT: )
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: ]
MACHO-PPC64: Sections [
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 0
MACHO-PPC64-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x0
MACHO-PPC64-NEXT: Size: 0x3C
MACHO-PPC64-NEXT: Offset: 608
MACHO-PPC64-NEXT: Alignment: 2
MACHO-PPC64-NEXT: RelocationOffset: 0x2D4
MACHO-PPC64-NEXT: RelocationCount: 5
MACHO-PPC64-NEXT: Type: 0x0
MACHO-PPC64-NEXT: Attributes [ (0x800004)
MACHO-PPC64-NEXT: PureInstructions (0x800000)
MACHO-PPC64-NEXT: SomeInstructions (0x4)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x0
MACHO-PPC64-NEXT: Reserved2: 0x0
MACHO-PPC64-NEXT: Relocations [
MACHO-PPC64-NEXT: 0x24 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x0 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x1C 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x58 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x18 1 2 0 0 _b
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Symbols [
MACHO-PPC64-NEXT: Symbol {
MACHO-PPC64-NEXT: Name: _f (4)
MACHO-PPC64-NEXT: Type: 0xF
MACHO-PPC64-NEXT: Section: __text (0x1)
MACHO-PPC64-NEXT: RefType: UndefinedNonLazy (0x0)
MACHO-PPC64-NEXT: Flags [ (0x0)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Value: 0x0
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: SectionData (
MACHO-PPC64-NEXT: 0000: 7C0802A6 FBE1FFF8 429F0005 7FE802A6 ||.......B.......|
MACHO-PPC64-NEXT: 0010: F8010010 F821FF81 48000029 3C5F0000 |.....!..H..)<_..|
MACHO-PPC64-NEXT: 0020: 38210080 E8420058 E8010010 EBE1FFF8 |8!...B.X........|
MACHO-PPC64-NEXT: 0030: 7C0803A6 E8620002 4E800020 ||....b..N.. |
MACHO-PPC64-NEXT: )
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 1
MACHO-PPC64-NEXT: Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
MACHO-PPC64-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x40
MACHO-PPC64-NEXT: Size: 0x20
MACHO-PPC64-NEXT: Offset: 672
MACHO-PPC64-NEXT: Alignment: 5
MACHO-PPC64-NEXT: RelocationOffset: 0x2FC
MACHO-PPC64-NEXT: RelocationCount: 4
MACHO-PPC64-NEXT: Type: 0x8
MACHO-PPC64-NEXT: Attributes [ (0x800004)
MACHO-PPC64-NEXT: PureInstructions (0x800000)
MACHO-PPC64-NEXT: SomeInstructions (0x4)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x0
MACHO-PPC64-NEXT: Reserved2: 0x20
MACHO-PPC64-NEXT: Relocations [
MACHO-PPC64-NEXT: 0x14 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x0 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0xC 0 2 n/a 1 _b
MACHO-PPC64-NEXT: 0x24 0 2 n/a 1 _b
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Symbols [
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: SectionData (
MACHO-PPC64-NEXT: 0000: 7C0802A6 429F0005 7D6802A6 3D6B0000 ||...B...}h..=k..|
MACHO-PPC64-NEXT: 0010: 7C0803A6 E98B0025 7D8903A6 4E800420 ||......%}...N.. |
MACHO-PPC64-NEXT: )
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 2
MACHO-PPC64-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x60
MACHO-PPC64-NEXT: Size: 0x4
MACHO-PPC64-NEXT: Offset: 704
MACHO-PPC64-NEXT: Alignment: 2
MACHO-PPC64-NEXT: RelocationOffset: 0x0
MACHO-PPC64-NEXT: RelocationCount: 0
MACHO-PPC64-NEXT: Type: 0x0
MACHO-PPC64-NEXT: Attributes [ (0x0)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x0
MACHO-PPC64-NEXT: Reserved2: 0x0
MACHO-PPC64-NEXT: Relocations [
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Symbols [
MACHO-PPC64-NEXT: Symbol {
MACHO-PPC64-NEXT: Name: _b (1)
MACHO-PPC64-NEXT: Type: 0xF
MACHO-PPC64-NEXT: Section: __data (0x3)
MACHO-PPC64-NEXT: RefType: UndefinedNonLazy (0x0)
MACHO-PPC64-NEXT: Flags [ (0x0)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Value: 0x60
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: SectionData (
MACHO-PPC64-NEXT: 0000: 0000002A |...*|
MACHO-PPC64-NEXT: )
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 3
MACHO-PPC64-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x64
MACHO-PPC64-NEXT: Size: 0x8
MACHO-PPC64-NEXT: Offset: 708
MACHO-PPC64-NEXT: Alignment: 2
MACHO-PPC64-NEXT: RelocationOffset: 0x0
MACHO-PPC64-NEXT: RelocationCount: 0
MACHO-PPC64-NEXT: Type: 0x6
MACHO-PPC64-NEXT: Attributes [ (0x0)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x1
MACHO-PPC64-NEXT: Reserved2: 0x0
MACHO-PPC64-NEXT: Relocations [
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Symbols [
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: SectionData (
MACHO-PPC64-NEXT: 0000: 00000000 00000000 |........|
MACHO-PPC64-NEXT: )
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 4
MACHO-PPC64-NEXT: Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x6C
MACHO-PPC64-NEXT: Size: 0x8
MACHO-PPC64-NEXT: Offset: 716
MACHO-PPC64-NEXT: Alignment: 2
MACHO-PPC64-NEXT: RelocationOffset: 0x31C
MACHO-PPC64-NEXT: RelocationCount: 1
MACHO-PPC64-NEXT: Type: 0x7
MACHO-PPC64-NEXT: Attributes [ (0x0)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x2
MACHO-PPC64-NEXT: Reserved2: 0x0
MACHO-PPC64-NEXT: Relocations [
MACHO-PPC64-NEXT: 0x0 0 3 1 0 dyld_stub_binding_helper
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Symbols [
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: SectionData (
MACHO-PPC64-NEXT: 0000: 00000000 00000000 |........|
MACHO-PPC64-NEXT: )
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: ]

View File

@ -6,6 +6,10 @@ RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-i386 \
RUN: | FileCheck %s -check-prefix MACHO-I386
RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-x86-64 \
RUN: | FileCheck %s -check-prefix MACHO-X86-64
RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc \
RUN: | FileCheck %s -check-prefix MACHO-PPC
RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc64 \
RUN: | FileCheck %s -check-prefix MACHO-PPC64
COFF: Sections [
COFF-NEXT: Section {
@ -151,3 +155,177 @@ MACHO-X86-64-NEXT: Reserved1: 0x0
MACHO-X86-64-NEXT: Reserved2: 0x0
MACHO-X86-64-NEXT: }
MACHO-X86-64-NEXT:]
MACHO-PPC: Sections [
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 0
MACHO-PPC-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x0
MACHO-PPC-NEXT: Size: 0x3C
MACHO-PPC-NEXT: Offset: 528
MACHO-PPC-NEXT: Alignment: 2
MACHO-PPC-NEXT: RelocationOffset: 0x27C
MACHO-PPC-NEXT: RelocationCount: 5
MACHO-PPC-NEXT: Type: 0x0
MACHO-PPC-NEXT: Attributes [ (0x800004)
MACHO-PPC-NEXT: PureInstructions (0x800000)
MACHO-PPC-NEXT: SomeInstructions (0x4)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x0
MACHO-PPC-NEXT: Reserved2: 0x0
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 1
MACHO-PPC-NEXT: Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
MACHO-PPC-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x40
MACHO-PPC-NEXT: Size: 0x20
MACHO-PPC-NEXT: Offset: 592
MACHO-PPC-NEXT: Alignment: 5
MACHO-PPC-NEXT: RelocationOffset: 0x2A4
MACHO-PPC-NEXT: RelocationCount: 4
MACHO-PPC-NEXT: Type: 0x8
MACHO-PPC-NEXT: Attributes [ (0x800004)
MACHO-PPC-NEXT: PureInstructions (0x800000)
MACHO-PPC-NEXT: SomeInstructions (0x4)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x0
MACHO-PPC-NEXT: Reserved2: 0x20
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 2
MACHO-PPC-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x60
MACHO-PPC-NEXT: Size: 0x4
MACHO-PPC-NEXT: Offset: 624
MACHO-PPC-NEXT: Alignment: 2
MACHO-PPC-NEXT: RelocationOffset: 0x0
MACHO-PPC-NEXT: RelocationCount: 0
MACHO-PPC-NEXT: Type: 0x0
MACHO-PPC-NEXT: Attributes [ (0x0)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x0
MACHO-PPC-NEXT: Reserved2: 0x0
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 3
MACHO-PPC-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x64
MACHO-PPC-NEXT: Size: 0x4
MACHO-PPC-NEXT: Offset: 628
MACHO-PPC-NEXT: Alignment: 2
MACHO-PPC-NEXT: RelocationOffset: 0x0
MACHO-PPC-NEXT: RelocationCount: 0
MACHO-PPC-NEXT: Type: 0x6
MACHO-PPC-NEXT: Attributes [ (0x0)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x1
MACHO-PPC-NEXT: Reserved2: 0x0
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: Section {
MACHO-PPC-NEXT: Index: 4
MACHO-PPC-NEXT: Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC-NEXT: Address: 0x68
MACHO-PPC-NEXT: Size: 0x4
MACHO-PPC-NEXT: Offset: 632
MACHO-PPC-NEXT: Alignment: 2
MACHO-PPC-NEXT: RelocationOffset: 0x2C4
MACHO-PPC-NEXT: RelocationCount: 1
MACHO-PPC-NEXT: Type: 0x7
MACHO-PPC-NEXT: Attributes [ (0x0)
MACHO-PPC-NEXT: ]
MACHO-PPC-NEXT: Reserved1: 0x2
MACHO-PPC-NEXT: Reserved2: 0x0
MACHO-PPC-NEXT: }
MACHO-PPC-NEXT: ]
MACHO-PPC64: Sections [
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 0
MACHO-PPC64-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x0
MACHO-PPC64-NEXT: Size: 0x3C
MACHO-PPC64-NEXT: Offset: 608
MACHO-PPC64-NEXT: Alignment: 2
MACHO-PPC64-NEXT: RelocationOffset: 0x2D4
MACHO-PPC64-NEXT: RelocationCount: 5
MACHO-PPC64-NEXT: Type: 0x0
MACHO-PPC64-NEXT: Attributes [ (0x800004)
MACHO-PPC64-NEXT: PureInstructions (0x800000)
MACHO-PPC64-NEXT: SomeInstructions (0x4)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x0
MACHO-PPC64-NEXT: Reserved2: 0x0
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 1
MACHO-PPC64-NEXT: Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
MACHO-PPC64-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x40
MACHO-PPC64-NEXT: Size: 0x20
MACHO-PPC64-NEXT: Offset: 672
MACHO-PPC64-NEXT: Alignment: 5
MACHO-PPC64-NEXT: RelocationOffset: 0x2FC
MACHO-PPC64-NEXT: RelocationCount: 4
MACHO-PPC64-NEXT: Type: 0x8
MACHO-PPC64-NEXT: Attributes [ (0x800004)
MACHO-PPC64-NEXT: PureInstructions (0x800000)
MACHO-PPC64-NEXT: SomeInstructions (0x4)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x0
MACHO-PPC64-NEXT: Reserved2: 0x20
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 2
MACHO-PPC64-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x60
MACHO-PPC64-NEXT: Size: 0x4
MACHO-PPC64-NEXT: Offset: 704
MACHO-PPC64-NEXT: Alignment: 2
MACHO-PPC64-NEXT: RelocationOffset: 0x0
MACHO-PPC64-NEXT: RelocationCount: 0
MACHO-PPC64-NEXT: Type: 0x0
MACHO-PPC64-NEXT: Attributes [ (0x0)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x0
MACHO-PPC64-NEXT: Reserved2: 0x0
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 3
MACHO-PPC64-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x64
MACHO-PPC64-NEXT: Size: 0x8
MACHO-PPC64-NEXT: Offset: 708
MACHO-PPC64-NEXT: Alignment: 2
MACHO-PPC64-NEXT: RelocationOffset: 0x0
MACHO-PPC64-NEXT: RelocationCount: 0
MACHO-PPC64-NEXT: Type: 0x6
MACHO-PPC64-NEXT: Attributes [ (0x0)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x1
MACHO-PPC64-NEXT: Reserved2: 0x0
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: Section {
MACHO-PPC64-NEXT: Index: 4
MACHO-PPC64-NEXT: Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
MACHO-PPC64-NEXT: Address: 0x6C
MACHO-PPC64-NEXT: Size: 0x8
MACHO-PPC64-NEXT: Offset: 716
MACHO-PPC64-NEXT: Alignment: 2
MACHO-PPC64-NEXT: RelocationOffset: 0x31C
MACHO-PPC64-NEXT: RelocationCount: 1
MACHO-PPC64-NEXT: Type: 0x7
MACHO-PPC64-NEXT: Attributes [ (0x0)
MACHO-PPC64-NEXT: ]
MACHO-PPC64-NEXT: Reserved1: 0x2
MACHO-PPC64-NEXT: Reserved2: 0x0
MACHO-PPC64-NEXT: }
MACHO-PPC64-NEXT: ]

View File

@ -27,6 +27,7 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
@ -183,11 +184,14 @@ static void emitDOTFile(const char *FileName, const MCFunction &f,
Out << "}\n";
}
static void getSectionsAndSymbols(const MachOObjectFileBase::Header *Header,
MachOObjectFileBase *MachOObj,
std::vector<SectionRef> &Sections,
std::vector<SymbolRef> &Symbols,
SmallVectorImpl<uint64_t> &FoundFns) {
template<endianness E>
static void
getSectionsAndSymbols(const typename MachOObjectFileMiddle<E>::Header *Header,
const MachOObjectFileMiddle<E> *MachOObj,
std::vector<SectionRef> &Sections,
std::vector<SymbolRef> &Symbols,
SmallVectorImpl<uint64_t> &FoundFns) {
typedef MachOObjectFileMiddle<E> ObjType;
error_code ec;
for (symbol_iterator SI = MachOObj->begin_symbols(),
SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
@ -202,19 +206,23 @@ static void getSectionsAndSymbols(const MachOObjectFileBase::Header *Header,
}
for (unsigned i = 0; i != Header->NumLoadCommands; ++i) {
const MachOObjectFileBase::LoadCommand *Command =
const typename ObjType::LoadCommand *Command =
MachOObj->getLoadCommandInfo(i);
if (Command->Type == macho::LCT_FunctionStarts) {
// We found a function starts segment, parse the addresses for later
// consumption.
const MachOObjectFileBase::LinkeditDataLoadCommand *LLC =
reinterpret_cast<const MachOObjectFileBase::LinkeditDataLoadCommand*>(Command);
const typename ObjType::LinkeditDataLoadCommand *LLC =
reinterpret_cast<const typename ObjType::LinkeditDataLoadCommand*>(Command);
MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);
}
}
}
template<endianness E>
static void DisassembleInputMachO2(StringRef Filename,
MachOObjectFileMiddle<E> *MachOOF);
void llvm::DisassembleInputMachO(StringRef Filename) {
OwningPtr<MemoryBuffer> Buff;
@ -226,7 +234,18 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
OwningPtr<MachOObjectFileBase> MachOOF(static_cast<MachOObjectFileBase*>(
ObjectFile::createMachOObjectFile(Buff.take())));
const Target *TheTarget = GetTarget(MachOOF.get());
if (MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(MachOOF.get())) {
DisassembleInputMachO2(Filename, O);
return;
}
MachOObjectFileBE *O = cast<MachOObjectFileBE>(MachOOF.get());
DisassembleInputMachO2(Filename, O);
}
template<endianness E>
static void DisassembleInputMachO2(StringRef Filename,
MachOObjectFileMiddle<E> *MachOOF) {
const Target *TheTarget = GetTarget(MachOOF);
if (!TheTarget) {
// GetTarget prints out stuff.
return;
@ -254,13 +273,14 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
outs() << '\n' << Filename << ":\n\n";
const MachOObjectFileBase::Header *Header = MachOOF->getHeader();
const typename MachOObjectFileMiddle<E>::Header *Header =
MachOOF->getHeader();
std::vector<SectionRef> Sections;
std::vector<SymbolRef> Symbols;
SmallVector<uint64_t, 8> FoundFns;
getSectionsAndSymbols(Header, MachOOF.get(), Sections, Symbols, FoundFns);
getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns);
// Make a copy of the unsorted symbol list. FIXME: duplication
std::vector<SymbolRef> UnsortedSymbols(Symbols);
@ -274,7 +294,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
#endif
OwningPtr<DIContext> diContext;
ObjectFile *DbgObj = MachOOF.get();
ObjectFile *DbgObj = MachOOF;
// Try to find debug info and set up the DIContext for it.
if (UseDbg) {
// A separate DSym file path was specified, parse it as a macho file,
@ -563,7 +583,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
Relocs[j].second.getName(SymName);
outs() << "\t# " << SymName << ' ';
DumpAddress(Addr, Sections, MachOOF.get(), outs());
DumpAddress(Addr, Sections, MachOOF, outs());
}
// If this instructions contains an address, see if we can evaluate
@ -572,7 +592,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
Inst.Address,
Inst.Size);
if (targ != -1ULL)
DumpAddress(targ, Sections, MachOOF.get(), outs());
DumpAddress(targ, Sections, MachOOF, outs());
// Print debug info.
if (diContext) {

View File

@ -191,6 +191,14 @@ bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
return a_addr < b_addr;
}
StringRef
getSectionFinalSegmentName(const MachOObjectFileBase *MachO, DataRefImpl DR) {
if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(MachO))
return O->getSectionFinalSegmentName(DR);
const MachOObjectFileBE *O = dyn_cast<MachOObjectFileBE>(MachO);
return O->getSectionFinalSegmentName(DR);
}
static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
const Target *TheTarget = getTarget(Obj);
// getTarget() will have already issued a diagnostic if necessary, so
@ -255,9 +263,10 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
StringRef SegmentName = "";
if (const MachOObjectFileBase *MachO = dyn_cast<const MachOObjectFileBase>(Obj)) {
if (const MachOObjectFileBase *MachO =
dyn_cast<const MachOObjectFileBase>(Obj)) {
DataRefImpl DR = i->getRawDataRefImpl();
SegmentName = MachO->getSectionFinalSegmentName(DR);
SegmentName = getSectionFinalSegmentName(MachO, DR);
}
StringRef name;
if (error(i->getName(name))) break;
@ -591,9 +600,10 @@ static void PrintSymbolTable(const ObjectFile *o) {
else if (Section == o->end_sections())
outs() << "*UND*";
else {
if (const MachOObjectFileBase *MachO = dyn_cast<const MachOObjectFileBase>(o)) {
if (const MachOObjectFileBase *MachO =
dyn_cast<const MachOObjectFileBase>(o)) {
DataRefImpl DR = Section->getRawDataRefImpl();
StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
StringRef SegmentName = getSectionFinalSegmentName(MachO, DR);
outs() << SegmentName << ",";
}
StringRef SectionName;

View File

@ -27,7 +27,7 @@ namespace {
class MachODumper : public ObjDumper {
public:
MachODumper(const llvm::object::MachOObjectFileBase *Obj, StreamWriter& Writer)
MachODumper(const MachOObjectFileBase *Obj, StreamWriter& Writer)
: ObjDumper(Writer)
, Obj(Obj) { }
@ -43,7 +43,14 @@ private:
void printRelocation(section_iterator SecI, relocation_iterator RelI);
const llvm::object::MachOObjectFileBase *Obj;
template<support::endianness E>
void printRelocation(const MachOObjectFileMiddle<E> *Obj,
section_iterator SecI, relocation_iterator RelI);
template<support::endianness E>
void printSections(const MachOObjectFileMiddle<E> *Obj);
const MachOObjectFileBase *Obj;
};
} // namespace
@ -157,58 +164,59 @@ namespace {
};
}
template<class MachOT>
static void getSection(const MachOObjectFile<MachOT> *Obj,
DataRefImpl DRI,
MachOSection &Section) {
const typename MachOObjectFile<MachOT>::Section *Sect = Obj->getSection(DRI);
Section.Address = Sect->Address;
Section.Size = Sect->Size;
Section.Offset = Sect->Offset;
Section.Alignment = Sect->Align;
Section.RelocationTableOffset = Sect->RelocationTableOffset;
Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
Section.Flags = Sect->Flags;
Section.Reserved1 = Sect->Reserved1;
Section.Reserved2 = Sect->Reserved2;
}
static void getSection(const MachOObjectFileBase *Obj,
DataRefImpl DRI,
MachOSection &Section) {
if (const MachOObjectFile64Le *O = dyn_cast<MachOObjectFile64Le>(Obj)) {
const MachOObjectFile64Le::Section *Sect = O->getSection(DRI);
if (const MachOObjectFileLE32 *O = dyn_cast<MachOObjectFileLE32>(Obj))
return getSection(O, DRI, Section);
if (const MachOObjectFileLE64 *O = dyn_cast<MachOObjectFileLE64>(Obj))
return getSection(O, DRI, Section);
if (const MachOObjectFileBE32 *O = dyn_cast<MachOObjectFileBE32>(Obj))
return getSection(O, DRI, Section);
const MachOObjectFileBE64 *O = cast<MachOObjectFileBE64>(Obj);
getSection(O, DRI, Section);
}
Section.Address = Sect->Address;
Section.Size = Sect->Size;
Section.Offset = Sect->Offset;
Section.Alignment = Sect->Align;
Section.RelocationTableOffset = Sect->RelocationTableOffset;
Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
Section.Flags = Sect->Flags;
Section.Reserved1 = Sect->Reserved1;
Section.Reserved2 = Sect->Reserved2;
} else {
const MachOObjectFile32Le *O2 = cast<MachOObjectFile32Le>(Obj);
const MachOObjectFile32Le::Section *Sect = O2->getSection(DRI);
Section.Address = Sect->Address;
Section.Size = Sect->Size;
Section.Offset = Sect->Offset;
Section.Alignment = Sect->Align;
Section.RelocationTableOffset = Sect->RelocationTableOffset;
Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
Section.Flags = Sect->Flags;
Section.Reserved1 = Sect->Reserved1;
Section.Reserved2 = Sect->Reserved2;
}
template<class MachOT>
static void getSymbol(const MachOObjectFile<MachOT> *Obj,
DataRefImpl DRI,
MachOSymbol &Symbol) {
const typename MachOObjectFile<MachOT>::SymbolTableEntry *Entry =
Obj->getSymbolTableEntry(DRI);
Symbol.StringIndex = Entry->StringIndex;
Symbol.Type = Entry->Type;
Symbol.SectionIndex = Entry->SectionIndex;
Symbol.Flags = Entry->Flags;
Symbol.Value = Entry->Value;
}
static void getSymbol(const MachOObjectFileBase *Obj,
DataRefImpl DRI,
MachOSymbol &Symbol) {
if (const MachOObjectFile64Le *O = dyn_cast<MachOObjectFile64Le>(Obj)) {
const MachOObjectFile64Le::SymbolTableEntry *Entry =
O->getSymbolTableEntry(DRI);
Symbol.StringIndex = Entry->StringIndex;
Symbol.Type = Entry->Type;
Symbol.SectionIndex = Entry->SectionIndex;
Symbol.Flags = Entry->Flags;
Symbol.Value = Entry->Value;
} else {
const MachOObjectFile32Le *O2 = cast<MachOObjectFile32Le>(Obj);
const MachOObjectFile32Le::SymbolTableEntry *Entry =
O2->getSymbolTableEntry(DRI);
Symbol.StringIndex = Entry->StringIndex;
Symbol.Type = Entry->Type;
Symbol.SectionIndex = Entry->SectionIndex;
Symbol.Flags = Entry->Flags;
Symbol.Value = Entry->Value;
}
if (const MachOObjectFileLE32 *O = dyn_cast<MachOObjectFileLE32>(Obj))
return getSymbol(O, DRI, Symbol);
if (const MachOObjectFileLE64 *O = dyn_cast<MachOObjectFileLE64>(Obj))
return getSymbol(O, DRI, Symbol);
if (const MachOObjectFileBE32 *O = dyn_cast<MachOObjectFileBE32>(Obj))
return getSymbol(O, DRI, Symbol);
const MachOObjectFileBE64 *O = cast<MachOObjectFileBE64>(Obj);
getSymbol(O, DRI, Symbol);
}
void MachODumper::printFileHeaders() {
@ -216,6 +224,14 @@ void MachODumper::printFileHeaders() {
}
void MachODumper::printSections() {
if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(Obj))
return printSections(O);
const MachOObjectFileBE *O = cast<MachOObjectFileBE>(Obj);
return printSections(O);
}
template<support::endianness E>
void MachODumper::printSections(const MachOObjectFileMiddle<E> *Obj) {
ListScope Group(W, "Sections");
int SectionIndex = -1;
@ -328,6 +344,16 @@ void MachODumper::printRelocations() {
void MachODumper::printRelocation(section_iterator SecI,
relocation_iterator RelI) {
if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(Obj))
return printRelocation(O, SecI, RelI);
const MachOObjectFileBE *O = cast<MachOObjectFileBE>(Obj);
return printRelocation(O, SecI, RelI);
}
template<support::endianness E>
void MachODumper::printRelocation(const MachOObjectFileMiddle<E> *Obj,
section_iterator SecI,
relocation_iterator RelI) {
uint64_t Offset;
SmallString<32> RelocName;
StringRef SymbolName;
@ -338,14 +364,15 @@ void MachODumper::printRelocation(section_iterator SecI,
if (error(Symbol.getName(SymbolName))) return;
DataRefImpl DR = RelI->getRawDataRefImpl();
const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR);
bool IsScattered = Obj->isScattered(RE);
const typename MachOObjectFileMiddle<E>::RelocationEntry *RE =
Obj->getRelocation(DR);
bool IsScattered = Obj->isRelocationScattered(RE);
if (opts::ExpandRelocs) {
DictScope Group(W, "Relocation");
W.printHex("Offset", Offset);
W.printNumber("PCRel", Obj->isPCRel(RE));
W.printNumber("Length", Obj->getLength(RE));
W.printNumber("PCRel", Obj->isRelocationPCRel(RE));
W.printNumber("Length", Obj->getRelocationLength(RE));
if (IsScattered)
W.printString("Extern", StringRef("N/A"));
else
@ -356,8 +383,8 @@ void MachODumper::printRelocation(section_iterator SecI,
} else {
raw_ostream& OS = W.startLine();
OS << W.hex(Offset)
<< " " << Obj->isPCRel(RE)
<< " " << Obj->getLength(RE);
<< " " << Obj->isRelocationPCRel(RE)
<< " " << Obj->getRelocationLength(RE);
if (IsScattered)
OS << " n/a";
else
@ -399,6 +426,7 @@ void MachODumper::printSymbol(symbol_iterator SymI) {
StringRef SectionName;
section_iterator SecI(Obj->end_sections());
if (error(SymI->getSection(SecI)) ||
SecI == Obj->end_sections() ||
error(SecI->getName(SectionName)))
SectionName = "";