diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-03-13 22:10:17 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-03-13 22:10:17 +0000 |
commit | ee0d89245eabf93d89b5fef7ac8707680796826d (patch) | |
tree | d6a9be7d16484cd94ec62d86a7fbaf22fd928bb3 /lib/MC/MCAssembler.cpp | |
parent | f0a0be47ed02c93e9679e8cf76a52a2ab18d3276 (diff) |
MC/Mach-O: Initial x86_64 support.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98454 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCAssembler.cpp')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 125 |
1 files changed, 80 insertions, 45 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 29ac8684bd..dae2d9336c 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -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(); |