forked from OSchip/llvm-project
llvm-mc/Mach-O: Add section padding where needed (to align the next section).
Also, simplify some of Mach-O writer code which can now use section addresses. llvm-svn: 80067
This commit is contained in:
parent
458055a890
commit
066d0f93bf
|
@ -82,7 +82,7 @@ public:
|
||||||
|
|
||||||
uint64_t getAddress() const;
|
uint64_t getAddress() const;
|
||||||
|
|
||||||
unsigned getFileSize() const {
|
uint64_t getFileSize() const {
|
||||||
assert(FileSize != ~UINT64_C(0) && "File size not set!");
|
assert(FileSize != ~UINT64_C(0) && "File size not set!");
|
||||||
return FileSize;
|
return FileSize;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +267,9 @@ private:
|
||||||
/// initialized.
|
/// initialized.
|
||||||
uint64_t Address;
|
uint64_t Address;
|
||||||
|
|
||||||
|
/// Size - The content size of this section. This is ~0 until initialized.
|
||||||
|
uint64_t Size;
|
||||||
|
|
||||||
/// FileSize - The size of this section in the object file. This is ~0 until
|
/// FileSize - The size of this section in the object file. This is ~0 until
|
||||||
/// initialized.
|
/// initialized.
|
||||||
uint64_t FileSize;
|
uint64_t FileSize;
|
||||||
|
@ -305,13 +308,19 @@ public:
|
||||||
//
|
//
|
||||||
// FIXME: This could all be kept private to the assembler implementation.
|
// FIXME: This could all be kept private to the assembler implementation.
|
||||||
|
|
||||||
unsigned getAddress() const {
|
uint64_t getAddress() const {
|
||||||
assert(Address != ~UINT64_C(0) && "Address not set!");
|
assert(Address != ~UINT64_C(0) && "Address not set!");
|
||||||
return Address;
|
return Address;
|
||||||
}
|
}
|
||||||
void setAddress(uint64_t Value) { Address = Value; }
|
void setAddress(uint64_t Value) { Address = Value; }
|
||||||
|
|
||||||
unsigned getFileSize() const {
|
uint64_t getSize() const {
|
||||||
|
assert(Size != ~UINT64_C(0) && "File size not set!");
|
||||||
|
return Size;
|
||||||
|
}
|
||||||
|
void setSize(uint64_t Value) { Size = Value; }
|
||||||
|
|
||||||
|
uint64_t getFileSize() const {
|
||||||
assert(FileSize != ~UINT64_C(0) && "File size not set!");
|
assert(FileSize != ~UINT64_C(0) && "File size not set!");
|
||||||
return FileSize;
|
return FileSize;
|
||||||
}
|
}
|
||||||
|
@ -414,7 +423,11 @@ private:
|
||||||
/// LayoutSection - Assign offsets and sizes to the fragments in the section
|
/// LayoutSection - Assign offsets and sizes to the fragments in the section
|
||||||
/// \arg SD, and update the section size. The section file offset should
|
/// \arg SD, and update the section size. The section file offset should
|
||||||
/// already have been computed.
|
/// already have been computed.
|
||||||
void LayoutSection(MCSectionData &SD);
|
///
|
||||||
|
/// \param NextAlign - The alignment for the section end address, which may
|
||||||
|
/// add padding bytes to the section (these are included in the section "file"
|
||||||
|
/// size, but not its regular size).
|
||||||
|
void LayoutSection(MCSectionData &SD, unsigned NextAlign);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Construct a new assembler instance.
|
/// Construct a new assembler instance.
|
||||||
|
|
|
@ -217,7 +217,7 @@ public:
|
||||||
WriteString(Section.getSectionName(), 16);
|
WriteString(Section.getSectionName(), 16);
|
||||||
WriteString(Section.getSegmentName(), 16);
|
WriteString(Section.getSegmentName(), 16);
|
||||||
Write32(SD.getAddress()); // address
|
Write32(SD.getAddress()); // address
|
||||||
Write32(SD.getFileSize()); // size
|
Write32(SD.getSize()); // size
|
||||||
Write32(FileOffset);
|
Write32(FileOffset);
|
||||||
|
|
||||||
assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
|
assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
|
||||||
|
@ -507,11 +507,6 @@ public:
|
||||||
if (NumSymbols)
|
if (NumSymbols)
|
||||||
ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
|
ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
|
||||||
UndefinedSymbolData);
|
UndefinedSymbolData);
|
||||||
|
|
||||||
// Compute the file offsets for all the sections in advance, so that we can
|
|
||||||
// write things out in order.
|
|
||||||
SmallVector<uint64_t, 16> SectionFileOffsets;
|
|
||||||
SectionFileOffsets.resize(NumSections);
|
|
||||||
|
|
||||||
// The section data starts after the header, the segment load command (and
|
// The section data starts after the header, the segment load command (and
|
||||||
// section headers) and the symbol table.
|
// section headers) and the symbol table.
|
||||||
|
@ -525,27 +520,22 @@ public:
|
||||||
LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize;
|
LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t FileOffset = Header32Size + LoadCommandsSize;
|
uint64_t SectionDataStart = Header32Size + LoadCommandsSize;
|
||||||
uint64_t SectionDataStartOffset = FileOffset;
|
uint64_t SectionDataEnd = SectionDataStart;
|
||||||
uint64_t SectionDataSize = 0;
|
uint64_t SectionDataSize = 0;
|
||||||
unsigned Index = 0;
|
if (!Asm.getSectionList().empty()) {
|
||||||
for (MCAssembler::iterator it = Asm.begin(),
|
MCSectionData &SD = Asm.getSectionList().back();
|
||||||
ie = Asm.end(); it != ie; ++it, ++Index) {
|
SectionDataSize = SD.getAddress() + SD.getSize();
|
||||||
SectionFileOffsets[Index] = FileOffset;
|
SectionDataEnd = SectionDataStart + SD.getAddress() + SD.getFileSize();
|
||||||
FileOffset += it->getFileSize();
|
|
||||||
SectionDataSize += it->getFileSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the prolog, starting with the header and load command...
|
// Write the prolog, starting with the header and load command...
|
||||||
WriteHeader32(NumLoadCommands, LoadCommandsSize);
|
WriteHeader32(NumLoadCommands, LoadCommandsSize);
|
||||||
WriteSegmentLoadCommand32(NumSections, SectionDataStartOffset,
|
WriteSegmentLoadCommand32(NumSections, SectionDataStart, SectionDataSize);
|
||||||
SectionDataSize);
|
|
||||||
|
|
||||||
// ... and then the section headers.
|
// ... and then the section headers.
|
||||||
Index = 0;
|
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
|
||||||
for (MCAssembler::iterator it = Asm.begin(),
|
WriteSection32(*it, SectionDataStart + it->getAddress());
|
||||||
ie = Asm.end(); it != ie; ++it, ++Index)
|
|
||||||
WriteSection32(*it, SectionFileOffsets[Index]);
|
|
||||||
|
|
||||||
// Write the symbol table load command, if used.
|
// Write the symbol table load command, if used.
|
||||||
if (NumSymbols) {
|
if (NumSymbols) {
|
||||||
|
@ -563,11 +553,10 @@ public:
|
||||||
|
|
||||||
// If used, the indirect symbols are written after the section data.
|
// If used, the indirect symbols are written after the section data.
|
||||||
if (NumIndirectSymbols)
|
if (NumIndirectSymbols)
|
||||||
IndirectSymbolOffset = SectionDataStartOffset + SectionDataSize;
|
IndirectSymbolOffset = SectionDataEnd;
|
||||||
|
|
||||||
// The symbol table is written after the indirect symbol data.
|
// The symbol table is written after the indirect symbol data.
|
||||||
uint64_t SymbolTableOffset =
|
uint64_t SymbolTableOffset = SectionDataEnd + IndirectSymbolSize;
|
||||||
SectionDataStartOffset + SectionDataSize + IndirectSymbolSize;
|
|
||||||
|
|
||||||
// The string table is written after symbol table.
|
// The string table is written after symbol table.
|
||||||
uint64_t StringTableOffset =
|
uint64_t StringTableOffset =
|
||||||
|
@ -675,6 +664,7 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
|
||||||
: Section(_Section),
|
: Section(_Section),
|
||||||
Alignment(1),
|
Alignment(1),
|
||||||
Address(~UINT64_C(0)),
|
Address(~UINT64_C(0)),
|
||||||
|
Size(~UINT64_C(0)),
|
||||||
FileSize(~UINT64_C(0))
|
FileSize(~UINT64_C(0))
|
||||||
{
|
{
|
||||||
if (A)
|
if (A)
|
||||||
|
@ -701,26 +691,24 @@ MCAssembler::MCAssembler(raw_ostream &_OS) : OS(_OS) {}
|
||||||
MCAssembler::~MCAssembler() {
|
MCAssembler::~MCAssembler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCAssembler::LayoutSection(MCSectionData &SD) {
|
void MCAssembler::LayoutSection(MCSectionData &SD, unsigned NextAlign) {
|
||||||
uint64_t Offset = 0;
|
uint64_t Address = SD.getAddress();
|
||||||
|
|
||||||
for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) {
|
for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) {
|
||||||
MCFragment &F = *it;
|
MCFragment &F = *it;
|
||||||
|
|
||||||
F.setOffset(Offset);
|
F.setOffset(Address - SD.getAddress());
|
||||||
|
|
||||||
// Evaluate fragment size.
|
// Evaluate fragment size.
|
||||||
switch (F.getKind()) {
|
switch (F.getKind()) {
|
||||||
case MCFragment::FT_Align: {
|
case MCFragment::FT_Align: {
|
||||||
MCAlignFragment &AF = cast<MCAlignFragment>(F);
|
MCAlignFragment &AF = cast<MCAlignFragment>(F);
|
||||||
|
|
||||||
uint64_t AlignedOffset = RoundUpToAlignment(Offset, AF.getAlignment());
|
uint64_t Size = RoundUpToAlignment(Address, AF.getAlignment()) - Address;
|
||||||
uint64_t PaddingBytes = AlignedOffset - Offset;
|
if (Size > AF.getMaxBytesToEmit())
|
||||||
|
|
||||||
if (PaddingBytes > AF.getMaxBytesToEmit())
|
|
||||||
AF.setFileSize(0);
|
AF.setFileSize(0);
|
||||||
else
|
else
|
||||||
AF.setFileSize(PaddingBytes);
|
AF.setFileSize(Size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,22 +723,24 @@ void MCAssembler::LayoutSection(MCSectionData &SD) {
|
||||||
if (!OF.getOffset().isAbsolute())
|
if (!OF.getOffset().isAbsolute())
|
||||||
llvm_unreachable("FIXME: Not yet implemented!");
|
llvm_unreachable("FIXME: Not yet implemented!");
|
||||||
uint64_t OrgOffset = OF.getOffset().getConstant();
|
uint64_t OrgOffset = OF.getOffset().getConstant();
|
||||||
|
uint64_t Offset = Address - SD.getAddress();
|
||||||
|
|
||||||
// FIXME: We need a way to communicate this error.
|
// FIXME: We need a way to communicate this error.
|
||||||
if (OrgOffset < Offset)
|
if (OrgOffset < Offset)
|
||||||
llvm_report_error("invalid .org offset '" + Twine(OrgOffset) +
|
llvm_report_error("invalid .org offset '" + Twine(OrgOffset) +
|
||||||
"' (section offset '" + Twine(Offset) + "'");
|
"' (at offset '" + Twine(Offset) + "'");
|
||||||
|
|
||||||
F.setFileSize(OrgOffset - Offset);
|
F.setFileSize(OrgOffset - Offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset += F.getFileSize();
|
Address += F.getFileSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Pad section?
|
// Set the section sizes.
|
||||||
SD.setFileSize(Offset);
|
SD.setSize(Address - SD.getAddress());
|
||||||
|
SD.setFileSize(RoundUpToAlignment(Address, NextAlign) - SD.getAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// WriteFileData - Write the \arg F data to the output file.
|
/// WriteFileData - Write the \arg F data to the output file.
|
||||||
|
@ -836,16 +826,32 @@ static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
|
||||||
ie = SD.end(); it != ie; ++it)
|
ie = SD.end(); it != ie; ++it)
|
||||||
WriteFileData(OS, *it, MOW);
|
WriteFileData(OS, *it, MOW);
|
||||||
|
|
||||||
|
// Add section padding.
|
||||||
|
assert(SD.getFileSize() >= SD.getSize() && "Invalid section sizes!");
|
||||||
|
MOW.WriteZeros(SD.getFileSize() - SD.getSize());
|
||||||
|
|
||||||
assert(OS.tell() - Start == SD.getFileSize());
|
assert(OS.tell() - Start == SD.getFileSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCAssembler::Finish() {
|
void MCAssembler::Finish() {
|
||||||
// Layout the sections and fragments.
|
// Layout the sections and fragments.
|
||||||
uint64_t Address = 0;
|
uint64_t Address = 0;
|
||||||
for (iterator it = begin(), ie = end(); it != ie; ++it) {
|
for (iterator it = begin(), ie = end(); it != ie;) {
|
||||||
it->setAddress(Address);
|
MCSectionData &SD = *it;
|
||||||
LayoutSection(*it);
|
|
||||||
Address += it->getFileSize();
|
// Select the amount of padding alignment we need, based on either the next
|
||||||
|
// sections alignment or the default alignment.
|
||||||
|
//
|
||||||
|
// FIXME: This should probably match the native word size.
|
||||||
|
unsigned NextAlign = 4;
|
||||||
|
++it;
|
||||||
|
if (it != ie)
|
||||||
|
NextAlign = it->getAlignment();
|
||||||
|
|
||||||
|
// Layout the section fragments and its size.
|
||||||
|
SD.setAddress(Address);
|
||||||
|
LayoutSection(SD, NextAlign);
|
||||||
|
Address += SD.getFileSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the object file.
|
// Write the object file.
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump | FileCheck %s
|
||||||
|
|
||||||
|
name:
|
||||||
|
.byte 0
|
||||||
|
|
||||||
|
// Check that symbol table is aligned to 4 bytes.
|
||||||
|
|
||||||
|
|
||||||
|
// CHECK: ('cputype', 7)
|
||||||
|
// CHECK: ('cpusubtype', 3)
|
||||||
|
// CHECK: ('filetype', 1)
|
||||||
|
// CHECK: ('num_load_commands', 1)
|
||||||
|
// CHECK: ('load_commands_size', 228)
|
||||||
|
// CHECK: ('flag', 0)
|
||||||
|
// CHECK: ('load_commands', [
|
||||||
|
// CHECK: # Load Command 0
|
||||||
|
// CHECK: (('command', 1)
|
||||||
|
// CHECK: ('size', 124)
|
||||||
|
// CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('vm_addr', 0)
|
||||||
|
// CHECK: ('vm_size', 1)
|
||||||
|
// CHECK: ('file_offset', 256)
|
||||||
|
// CHECK: ('file_size', 1)
|
||||||
|
// CHECK: ('maxprot', 7)
|
||||||
|
// CHECK: ('initprot', 7)
|
||||||
|
// CHECK: ('num_sections', 1)
|
||||||
|
// CHECK: ('flags', 0)
|
||||||
|
// CHECK: ('sections', [
|
||||||
|
// CHECK: # Section 0
|
||||||
|
// CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('address', 0)
|
||||||
|
// CHECK: ('size', 1)
|
||||||
|
// CHECK: ('offset', 256)
|
||||||
|
// CHECK: ('alignment', 0)
|
||||||
|
// CHECK: ('reloc_offset', 0)
|
||||||
|
// CHECK: ('num_reloc', 0)
|
||||||
|
// CHECK: ('flags', 0x80000000)
|
||||||
|
// CHECK: ('reserved1', 0)
|
||||||
|
// CHECK: ('reserved2', 0)
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: ])
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: # Load Command 1
|
||||||
|
// CHECK: (('command', 2)
|
||||||
|
// CHECK: ('size', 24)
|
||||||
|
// CHECK: ('symoff', 260)
|
||||||
|
// CHECK: ('nsyms', 1)
|
||||||
|
// CHECK: ('stroff', 272)
|
||||||
|
// CHECK: ('strsize', 8)
|
||||||
|
// CHECK: ('_string_data', '\x00name\x00\x00\x00')
|
||||||
|
// CHECK: ('_symbols', [
|
||||||
|
// CHECK: # Symbol 0
|
||||||
|
// CHECK: (('n_strx', 1)
|
||||||
|
// CHECK: ('n_type', 0xe)
|
||||||
|
// CHECK: ('n_sect', 1)
|
||||||
|
// CHECK: ('n_desc', 0)
|
||||||
|
// CHECK: ('n_value', 0)
|
||||||
|
// CHECK: ('_string', 'name')
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: ])
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: # Load Command 2
|
||||||
|
// CHECK: (('command', 11)
|
||||||
|
// CHECK: ('size', 80)
|
||||||
|
// CHECK: ('ilocalsym', 0)
|
||||||
|
// CHECK: ('nlocalsym', 1)
|
||||||
|
// CHECK: ('iextdefsym', 1)
|
||||||
|
// CHECK: ('nextdefsym', 0)
|
||||||
|
// CHECK: ('iundefsym', 1)
|
||||||
|
// CHECK: ('nundefsym', 0)
|
||||||
|
// CHECK: ('tocoff', 0)
|
||||||
|
// CHECK: ('ntoc', 0)
|
||||||
|
// CHECK: ('modtaboff', 0)
|
||||||
|
// CHECK: ('nmodtab', 0)
|
||||||
|
// CHECK: ('extrefsymoff', 0)
|
||||||
|
// CHECK: ('nextrefsyms', 0)
|
||||||
|
// CHECK: ('indirectsymoff', 0)
|
||||||
|
// CHECK: ('nindirectsyms', 0)
|
||||||
|
// CHECK: ('extreloff', 0)
|
||||||
|
// CHECK: ('nextrel', 0)
|
||||||
|
// CHECK: ('locreloff', 0)
|
||||||
|
// CHECK: ('nlocrel', 0)
|
||||||
|
// CHECK: ('_indirect_symbols', [
|
||||||
|
// CHECK: ])
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: ])
|
|
@ -0,0 +1,137 @@
|
||||||
|
// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump | FileCheck %s
|
||||||
|
|
||||||
|
.byte 0
|
||||||
|
|
||||||
|
// There should be 3 padding bytes here.
|
||||||
|
|
||||||
|
.data
|
||||||
|
.align 2
|
||||||
|
foo:
|
||||||
|
.org 8
|
||||||
|
bar:
|
||||||
|
.byte 0
|
||||||
|
|
||||||
|
.const
|
||||||
|
baz:
|
||||||
|
|
||||||
|
// CHECK: ('cputype', 7)
|
||||||
|
// CHECK: ('cpusubtype', 3)
|
||||||
|
// CHECK: ('filetype', 1)
|
||||||
|
// CHECK: ('num_load_commands', 1)
|
||||||
|
// CHECK: ('load_commands_size', 364)
|
||||||
|
// CHECK: ('flag', 0)
|
||||||
|
// CHECK: ('load_commands', [
|
||||||
|
// CHECK: # Load Command 0
|
||||||
|
// CHECK: (('command', 1)
|
||||||
|
// CHECK: ('size', 260)
|
||||||
|
// CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('vm_addr', 0)
|
||||||
|
// CHECK: ('vm_size', 13)
|
||||||
|
// CHECK: ('file_offset', 392)
|
||||||
|
// CHECK: ('file_size', 13)
|
||||||
|
// CHECK: ('maxprot', 7)
|
||||||
|
// CHECK: ('initprot', 7)
|
||||||
|
// CHECK: ('num_sections', 3)
|
||||||
|
// CHECK: ('flags', 0)
|
||||||
|
// CHECK: ('sections', [
|
||||||
|
// CHECK: # Section 0
|
||||||
|
// CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('address', 0)
|
||||||
|
// CHECK: ('size', 1)
|
||||||
|
// CHECK: ('offset', 392)
|
||||||
|
// CHECK: ('alignment', 0)
|
||||||
|
// CHECK: ('reloc_offset', 0)
|
||||||
|
// CHECK: ('num_reloc', 0)
|
||||||
|
// CHECK: ('flags', 0x80000000)
|
||||||
|
// CHECK: ('reserved1', 0)
|
||||||
|
// CHECK: ('reserved2', 0)
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: # Section 1
|
||||||
|
// CHECK: (('section_name', '__data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('address', 4)
|
||||||
|
// CHECK: ('size', 9)
|
||||||
|
// CHECK: ('offset', 396)
|
||||||
|
// CHECK: ('alignment', 2)
|
||||||
|
// CHECK: ('reloc_offset', 0)
|
||||||
|
// CHECK: ('num_reloc', 0)
|
||||||
|
// CHECK: ('flags', 0x0)
|
||||||
|
// CHECK: ('reserved1', 0)
|
||||||
|
// CHECK: ('reserved2', 0)
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: # Section 2
|
||||||
|
// CHECK: (('section_name', '__const\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('address', 13)
|
||||||
|
// CHECK: ('size', 0)
|
||||||
|
// CHECK: ('offset', 405)
|
||||||
|
// CHECK: ('alignment', 0)
|
||||||
|
// CHECK: ('reloc_offset', 0)
|
||||||
|
// CHECK: ('num_reloc', 0)
|
||||||
|
// CHECK: ('flags', 0x0)
|
||||||
|
// CHECK: ('reserved1', 0)
|
||||||
|
// CHECK: ('reserved2', 0)
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: ])
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: # Load Command 1
|
||||||
|
// CHECK: (('command', 2)
|
||||||
|
// CHECK: ('size', 24)
|
||||||
|
// CHECK: ('symoff', 408)
|
||||||
|
// CHECK: ('nsyms', 3)
|
||||||
|
// CHECK: ('stroff', 444)
|
||||||
|
// CHECK: ('strsize', 16)
|
||||||
|
// CHECK: ('_string_data', '\x00foo\x00bar\x00baz\x00\x00\x00\x00')
|
||||||
|
// CHECK: ('_symbols', [
|
||||||
|
// CHECK: # Symbol 0
|
||||||
|
// CHECK: (('n_strx', 1)
|
||||||
|
// CHECK: ('n_type', 0xe)
|
||||||
|
// CHECK: ('n_sect', 2)
|
||||||
|
// CHECK: ('n_desc', 0)
|
||||||
|
// CHECK: ('n_value', 4)
|
||||||
|
// CHECK: ('_string', 'foo')
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: # Symbol 1
|
||||||
|
// CHECK: (('n_strx', 5)
|
||||||
|
// CHECK: ('n_type', 0xe)
|
||||||
|
// CHECK: ('n_sect', 2)
|
||||||
|
// CHECK: ('n_desc', 0)
|
||||||
|
// CHECK: ('n_value', 12)
|
||||||
|
// CHECK: ('_string', 'bar')
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: # Symbol 2
|
||||||
|
// CHECK: (('n_strx', 9)
|
||||||
|
// CHECK: ('n_type', 0xe)
|
||||||
|
// CHECK: ('n_sect', 3)
|
||||||
|
// CHECK: ('n_desc', 0)
|
||||||
|
// CHECK: ('n_value', 13)
|
||||||
|
// CHECK: ('_string', 'baz')
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: ])
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: # Load Command 2
|
||||||
|
// CHECK: (('command', 11)
|
||||||
|
// CHECK: ('size', 80)
|
||||||
|
// CHECK: ('ilocalsym', 0)
|
||||||
|
// CHECK: ('nlocalsym', 3)
|
||||||
|
// CHECK: ('iextdefsym', 3)
|
||||||
|
// CHECK: ('nextdefsym', 0)
|
||||||
|
// CHECK: ('iundefsym', 3)
|
||||||
|
// CHECK: ('nundefsym', 0)
|
||||||
|
// CHECK: ('tocoff', 0)
|
||||||
|
// CHECK: ('ntoc', 0)
|
||||||
|
// CHECK: ('modtaboff', 0)
|
||||||
|
// CHECK: ('nmodtab', 0)
|
||||||
|
// CHECK: ('extrefsymoff', 0)
|
||||||
|
// CHECK: ('nextrefsyms', 0)
|
||||||
|
// CHECK: ('indirectsymoff', 0)
|
||||||
|
// CHECK: ('nindirectsyms', 0)
|
||||||
|
// CHECK: ('extreloff', 0)
|
||||||
|
// CHECK: ('nextrel', 0)
|
||||||
|
// CHECK: ('locreloff', 0)
|
||||||
|
// CHECK: ('nlocrel', 0)
|
||||||
|
// CHECK: ('_indirect_symbols', [
|
||||||
|
// CHECK: ])
|
||||||
|
// CHECK: ),
|
||||||
|
// CHECK: ])
|
Loading…
Reference in New Issue