MC/Mach-O: Initial x86_64 support.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98454 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2010-03-13 22:10:17 +00:00
parent f0a0be47ed
commit ee0d89245e
3 changed files with 644 additions and 52 deletions

View File

@ -24,6 +24,7 @@
#include "llvm/Support/MachO.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmBackend.h"
// FIXME: Gross.
@ -86,14 +87,19 @@ class MachObjectWriter {
Header_Magic64 = 0xFEEDFACF
};
static const unsigned Header32Size = 28;
static const unsigned Header64Size = 32;
static const unsigned SegmentLoadCommand32Size = 56;
static const unsigned Section32Size = 68;
static const unsigned SymtabLoadCommandSize = 24;
static const unsigned DysymtabLoadCommandSize = 80;
static const unsigned Nlist32Size = 12;
static const unsigned RelocationInfoSize = 8;
enum {
Header32Size = 28,
Header64Size = 32,
SegmentLoadCommand32Size = 56,
SegmentLoadCommand64Size = 72,
Section32Size = 68,
Section64Size = 80,
SymtabLoadCommandSize = 24,
DysymtabLoadCommandSize = 80,
Nlist32Size = 12,
Nlist64Size = 16,
RelocationInfoSize = 8
};
enum HeaderFileType {
HFT_Object = 0x1
@ -106,7 +112,8 @@ class MachObjectWriter {
enum LoadCommandType {
LCT_Segment = 0x1,
LCT_Symtab = 0x2,
LCT_Dysymtab = 0xb
LCT_Dysymtab = 0xb,
LCT_Segment64 = 0x19
};
// See <mach-o/nlist.h>.
@ -161,11 +168,12 @@ class MachObjectWriter {
};
raw_ostream &OS;
bool IsLSB;
unsigned Is64Bit : 1;
unsigned IsLSB : 1;
public:
MachObjectWriter(raw_ostream &_OS, bool _IsLSB = true)
: OS(_OS), IsLSB(_IsLSB) {
MachObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool _IsLSB = true)
: OS(_OS), Is64Bit(_Is64Bit), IsLSB(_IsLSB) {
}
/// @name Helper Methods
@ -222,22 +230,23 @@ public:
/// @}
void WriteHeader32(unsigned NumLoadCommands, unsigned LoadCommandsSize,
bool SubsectionsViaSymbols) {
void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
bool SubsectionsViaSymbols) {
uint32_t Flags = 0;
if (SubsectionsViaSymbols)
Flags |= HF_SubsectionsViaSymbols;
// struct mach_header (28 bytes)
// struct mach_header (28 bytes) or
// struct mach_header_64 (32 bytes)
uint64_t Start = OS.tell();
(void) Start;
Write32(Header_Magic32);
Write32(Is64Bit ? Header_Magic64 : Header_Magic32);
// FIXME: Support cputype.
Write32(MachO::CPUTypeI386);
Write32(Is64Bit ? MachO::CPUTypeX86_64 : MachO::CPUTypeI386);
// FIXME: Support cpusubtype.
Write32(MachO::CPUSubType_I386_ALL);
Write32(HFT_Object);
@ -245,48 +254,62 @@ public:
// segment.
Write32(LoadCommandsSize);
Write32(Flags);
if (Is64Bit)
Write32(0); // reserved
assert(OS.tell() - Start == Header32Size);
assert(OS.tell() - Start == Is64Bit ? Header64Size : Header32Size);
}
/// WriteSegmentLoadCommand32 - Write a 32-bit segment load command.
/// WriteSegmentLoadCommand - Write a segment load command.
///
/// \arg NumSections - The number of sections in this segment.
/// \arg SectionDataSize - The total size of the sections.
void WriteSegmentLoadCommand32(unsigned NumSections,
uint64_t VMSize,
uint64_t SectionDataStartOffset,
uint64_t SectionDataSize) {
// struct segment_command (56 bytes)
void WriteSegmentLoadCommand(unsigned NumSections,
uint64_t VMSize,
uint64_t SectionDataStartOffset,
uint64_t SectionDataSize) {
// struct segment_command (56 bytes) or
// struct segment_command_64 (72 bytes)
uint64_t Start = OS.tell();
(void) Start;
Write32(LCT_Segment);
Write32(SegmentLoadCommand32Size + NumSections * Section32Size);
unsigned SegmentLoadCommandSize = Is64Bit ? SegmentLoadCommand64Size :
SegmentLoadCommand32Size;
Write32(Is64Bit ? LCT_Segment64 : LCT_Segment);
Write32(SegmentLoadCommandSize +
NumSections * (Is64Bit ? Section64Size : Section32Size));
WriteString("", 16);
Write32(0); // vmaddr
Write32(VMSize); // vmsize
Write32(SectionDataStartOffset); // file offset
Write32(SectionDataSize); // file size
if (Is64Bit) {
Write64(0); // vmaddr
Write64(VMSize); // vmsize
Write64(SectionDataStartOffset); // file offset
Write64(SectionDataSize); // file size
} else {
Write32(0); // vmaddr
Write32(VMSize); // vmsize
Write32(SectionDataStartOffset); // file offset
Write32(SectionDataSize); // file size
}
Write32(0x7); // maxprot
Write32(0x7); // initprot
Write32(NumSections);
Write32(0); // flags
assert(OS.tell() - Start == SegmentLoadCommand32Size);
assert(OS.tell() - Start == SegmentLoadCommandSize);
}
void WriteSection32(const MCSectionData &SD, uint64_t FileOffset,
uint64_t RelocationsStart, unsigned NumRelocations) {
void WriteSection(const MCSectionData &SD, uint64_t FileOffset,
uint64_t RelocationsStart, unsigned NumRelocations) {
// The offset is unused for virtual sections.
if (isVirtualSection(SD.getSection())) {
assert(SD.getFileSize() == 0 && "Invalid file size!");
FileOffset = 0;
}
// struct section (68 bytes)
// struct section (68 bytes) or
// struct section_64 (80 bytes)
uint64_t Start = OS.tell();
(void) Start;
@ -296,8 +319,13 @@ public:
static_cast<const MCSectionMachO&>(SD.getSection());
WriteString(Section.getSectionName(), 16);
WriteString(Section.getSegmentName(), 16);
Write32(SD.getAddress()); // address
Write32(SD.getSize()); // size
if (Is64Bit) {
Write64(SD.getAddress()); // address
Write64(SD.getSize()); // size
} else {
Write32(SD.getAddress()); // address
Write32(SD.getSize()); // size
}
Write32(FileOffset);
unsigned Flags = Section.getTypeAndAttributes();
@ -311,8 +339,10 @@ public:
Write32(Flags);
Write32(0); // reserved1
Write32(Section.getStubSize()); // reserved2
if (Is64Bit)
Write32(0); // reserved3
assert(OS.tell() - Start == Section32Size);
assert(OS.tell() - Start == Is64Bit ? Section64Size : Section32Size);
}
void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
@ -748,7 +778,8 @@ public:
// The section data starts after the header, the segment load command (and
// section headers) and the symbol table.
unsigned NumLoadCommands = 1;
uint64_t LoadCommandsSize =
uint64_t LoadCommandsSize = Is64Bit ?
SegmentLoadCommand64Size + NumSections * Section64Size :
SegmentLoadCommand32Size + NumSections * Section32Size;
// Add the symbol table load command sizes, if used.
@ -759,7 +790,8 @@ public:
// Compute the total size of the section data, as well as its file size and
// vm size.
uint64_t SectionDataStart = Header32Size + LoadCommandsSize;
uint64_t SectionDataStart = (Is64Bit ? Header64Size : Header32Size)
+ LoadCommandsSize;
uint64_t SectionDataSize = 0;
uint64_t SectionDataFileSize = 0;
uint64_t VMSize = 0;
@ -785,10 +817,10 @@ public:
SectionDataFileSize += SectionDataPadding;
// Write the prolog, starting with the header and load command...
WriteHeader32(NumLoadCommands, LoadCommandsSize,
Asm.getSubsectionsViaSymbols());
WriteSegmentLoadCommand32(NumSections, VMSize,
SectionDataStart, SectionDataSize);
WriteHeader(NumLoadCommands, LoadCommandsSize,
Asm.getSubsectionsViaSymbols());
WriteSegmentLoadCommand(NumSections, VMSize,
SectionDataStart, SectionDataSize);
// ... and then the section headers.
//
@ -815,7 +847,7 @@ public:
unsigned NumRelocs = RelocInfos.size() - NumRelocsStart;
uint64_t SectionStart = SectionDataStart + SD.getAddress();
WriteSection32(SD, SectionStart, RelocTableEnd, NumRelocs);
WriteSection(SD, SectionStart, RelocTableEnd, NumRelocs);
RelocTableEnd += NumRelocs * RelocationInfoSize;
}
@ -1284,7 +1316,10 @@ void MCAssembler::Finish() {
dump(); });
// Write the object file.
MachObjectWriter MOW(OS);
//
// FIXME: Factor out MCObjectWriter.
bool Is64Bit = StringRef(getBackend().getTarget().getName()) == "x86-64";
MachObjectWriter MOW(OS, Is64Bit);
MOW.WriteObject(*this);
OS.flush();

View File

@ -36,13 +36,9 @@
.objc_class_vars
.objc_instance_vars
.objc_module_info
// FIXME: These are aliases for __TEXT, __cstring which we don't properly unique
// yet.
// .objc_class_names
// .objc_meth_var_types
// .objc_meth_var_names
.objc_class_names
.objc_meth_var_types
.objc_meth_var_names
.objc_selector_strs
.section __TEXT,__picsymbolstub4,symbol_stubs,none,16

View File

@ -0,0 +1,561 @@
// RUN: llvm-mc -triple x86_64-apple-darwin10 %s -filetype=obj -o - | macho-dump | FileCheck %s
.text
.section __TEXT,__text,regular,pure_instructions
.const
.static_const
.cstring
.literal4
.literal8
.literal16
.constructor
.destructor
.data
.static_data
.dyld
.mod_init_func
.mod_term_func
.const_data
.objc_class
.objc_meta_class
.objc_cat_cls_meth
.objc_cat_inst_meth
.objc_protocol
.objc_string_object
.objc_cls_meth
.objc_inst_meth
.objc_cls_refs
.objc_message_refs
.objc_symbols
.objc_category
.objc_class_vars
.objc_instance_vars
.objc_module_info
.objc_class_names
.objc_meth_var_types
.objc_meth_var_names
.objc_selector_strs
.subsections_via_symbols
// CHECK: ('cputype', 16777223)
// CHECK: ('cpusubtype', 3)
// CHECK: ('filetype', 1)
// CHECK: ('num_load_commands', 1)
// CHECK: ('load_commands_size', 2552)
// CHECK: ('flag', 8192)
// CHECK: ('reserved', 0)
// CHECK: ('load_commands', [
// CHECK: # Load Command 0
// CHECK: (('command', 25)
// CHECK: ('size', 2552)
// 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', 0)
// CHECK: ('file_offset', 2584)
// CHECK: ('file_size', 0)
// CHECK: ('maxprot', 7)
// CHECK: ('initprot', 7)
// CHECK: ('num_sections', 31)
// 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', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x80000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 1
// 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', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 2
// CHECK: (('section_name', '__static_const\x00\x00')
// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 3
// CHECK: (('section_name', '__cstring\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', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x2)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 4
// CHECK: (('section_name', '__literal4\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', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 2)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x3)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 5
// CHECK: (('section_name', '__literal8\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', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 3)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x4)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 6
// CHECK: (('section_name', '__literal16\x00\x00\x00\x00\x00')
// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 4)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0xe)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 7
// CHECK: (('section_name', '__constructor\x00\x00\x00')
// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 8
// CHECK: (('section_name', '__destructor\x00\x00\x00\x00')
// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 9
// 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', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 10
// CHECK: (('section_name', '__static_data\x00\x00\x00')
// CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 11
// CHECK: (('section_name', '__dyld\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', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 12
// CHECK: (('section_name', '__mod_init_func\x00')
// CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 2)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x9)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 13
// CHECK: (('section_name', '__mod_term_func\x00')
// CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 2)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0xa)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 14
// CHECK: (('section_name', '__const\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', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x0)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 15
// CHECK: (('section_name', '__class\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 16
// CHECK: (('section_name', '__meta_class\x00\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 17
// CHECK: (('section_name', '__cat_cls_meth\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 18
// CHECK: (('section_name', '__cat_inst_meth\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 19
// CHECK: (('section_name', '__protocol\x00\x00\x00\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 20
// CHECK: (('section_name', '__string_object\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 21
// CHECK: (('section_name', '__cls_meth\x00\x00\x00\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 22
// CHECK: (('section_name', '__inst_meth\x00\x00\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 23
// CHECK: (('section_name', '__cls_refs\x00\x00\x00\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 2)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000005)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 24
// CHECK: (('section_name', '__message_refs\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 2)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000005)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 25
// CHECK: (('section_name', '__symbols\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 26
// CHECK: (('section_name', '__category\x00\x00\x00\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 27
// CHECK: (('section_name', '__class_vars\x00\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 28
// CHECK: (('section_name', '__instance_vars\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 29
// CHECK: (('section_name', '__module_info\x00\x00\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x10000000)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: # Section 30
// CHECK: (('section_name', '__selector_strs\x00')
// CHECK: ('segment_name', '__OBJC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
// CHECK: ('address', 0)
// CHECK: ('size', 0)
// CHECK: ('offset', 2584)
// CHECK: ('alignment', 0)
// CHECK: ('reloc_offset', 0)
// CHECK: ('num_reloc', 0)
// CHECK: ('flags', 0x2)
// CHECK: ('reserved1', 0)
// CHECK: ('reserved2', 0)
// CHECK: ('reserved3', 0)
// CHECK: ),
// CHECK: ('_relocations', [
// CHECK: ])
// CHECK: ])
// CHECK: ),
// CHECK: ])