From d5a8e98ef627a35284c9b5989664514f8f163968 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 28 Aug 2009 05:49:21 +0000 Subject: [PATCH] llvm-mc: Support .zerofill emission. - I'm still trying to figure out the cleanest way to implement this and match the assembler, currently there are some substantial differences. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80347 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCAssembler.h | 38 ++++++++- lib/MC/MCAssembler.cpp | 67 ++++++++++++++- lib/MC/MCMachOStreamer.cpp | 22 ++++- test/MC/MachO/lcomm-attributes.s | 136 +++++++++++++++++++++++++++++ test/MC/MachO/zerofill-1.s | 121 ++++++++++++++++++++++++++ test/MC/MachO/zerofill-2.s | 103 ++++++++++++++++++++++ test/MC/MachO/zerofill-3.s | 141 +++++++++++++++++++++++++++++++ 7 files changed, 623 insertions(+), 5 deletions(-) create mode 100644 test/MC/MachO/lcomm-attributes.s create mode 100644 test/MC/MachO/zerofill-1.s create mode 100644 test/MC/MachO/zerofill-2.s create mode 100644 test/MC/MachO/zerofill-3.s diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index edb504bda25..4b66159d4dc 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -33,7 +33,8 @@ public: FT_Data, FT_Align, FT_Fill, - FT_Org + FT_Org, + FT_ZeroFill }; private: @@ -218,6 +219,7 @@ public: MCOrgFragment(MCValue _Offset, int8_t _Value, MCSectionData *SD = 0) : MCFragment(FT_Org, SD), Offset(_Offset), Value(_Value) {} + /// @name Accessors /// @{ @@ -238,6 +240,40 @@ public: static bool classof(const MCOrgFragment *) { return true; } }; +/// MCZeroFillFragment - Represent data which has a fixed size and alignment, +/// but requires no physical space in the object file. +class MCZeroFillFragment : public MCFragment { + /// Size - The size of this fragment. + uint64_t Size; + + /// Alignment - The alignment for this fragment. + unsigned Alignment; + +public: + MCZeroFillFragment(uint64_t _Size, unsigned _Alignment, MCSectionData *SD = 0) + : MCFragment(FT_ZeroFill, SD), + Size(_Size), Alignment(_Alignment) {} + + /// @name Accessors + /// @{ + + uint64_t getMaxFileSize() const { + // FIXME: This also doesn't make much sense, this method is misnamed. + return ~UINT64_C(0); + } + + uint64_t getSize() const { return Size; } + + unsigned getAlignment() const { return Alignment; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_ZeroFill; + } + static bool classof(const MCZeroFillFragment *) { return true; } +}; + // FIXME: Should this be a separate class, or just merged into MCSection? Since // we anticipate the fast path being through an MCAssembler, the only reason to // keep it out is for API abstraction. diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 1375b779580..8057fcb3593 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -28,6 +28,15 @@ STATISTIC(EmittedFragments, "Number of emitted assembler fragments"); static void WriteFileData(raw_ostream &OS, const MCSectionData &SD, MachObjectWriter &MOW); +/// isVirtualSection - Check if this is a section which does not actually exist +/// in the object file. +static bool isVirtualSection(const MCSection &Section) { + // FIXME: Lame. + const MCSectionMachO &SMO = static_cast(Section); + unsigned Type = SMO.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE; + return (Type == MCSectionMachO::S_ZEROFILL); +} + class MachObjectWriter { // See . enum { @@ -229,6 +238,12 @@ public: void WriteSection32(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) uint64_t Start = OS.tell(); @@ -692,6 +707,9 @@ public: VMSize = std::max(VMSize, SD.getAddress() + SD.getSize()); + if (isVirtualSection(SD.getSection())) + continue; + SectionDataSize = std::max(SectionDataSize, SD.getAddress() + SD.getSize()); SectionDataFileSize = std::max(SectionDataFileSize, @@ -922,7 +940,7 @@ void MCAssembler::LayoutSection(MCSectionData &SD) { case MCFragment::FT_Align: { MCAlignFragment &AF = cast(F); - uint64_t Size = RoundUpToAlignment(Address, AF.getAlignment()) - Address; + uint64_t Size = OffsetToAlignment(Address, AF.getAlignment()); if (Size > AF.getMaxBytesToEmit()) AF.setFileSize(0); else @@ -968,6 +986,19 @@ void MCAssembler::LayoutSection(MCSectionData &SD) { F.setFileSize(OrgOffset - Offset); break; } + + case MCFragment::FT_ZeroFill: { + MCZeroFillFragment &ZFF = cast(F); + + // Align the fragment offset; it is safe to adjust the offset freely since + // this is only in virtual sections. + uint64_t Aligned = RoundUpToAlignment(Address, ZFF.getAlignment()); + F.setOffset(Aligned - SD.getAddress()); + + // FIXME: This is misnamed. + F.setFileSize(ZFF.getSize()); + break; + } } Address += F.getFileSize(); @@ -975,7 +1006,10 @@ void MCAssembler::LayoutSection(MCSectionData &SD) { // Set the section sizes. SD.setSize(Address - SD.getAddress()); - SD.setFileSize(Address - SD.getAddress()); + if (isVirtualSection(SD.getSection())) + SD.setFileSize(0); + else + SD.setFileSize(Address - SD.getAddress()); } /// WriteFileData - Write the \arg F data to the output file. @@ -1055,6 +1089,11 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F, break; } + + case MCFragment::FT_ZeroFill: { + assert(0 && "Invalid zero fill fragment in concrete section!"); + break; + } } assert(OS.tell() - Start == F.getFileSize()); @@ -1063,6 +1102,12 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F, /// WriteFileData - Write the \arg SD data to the output file. static void WriteFileData(raw_ostream &OS, const MCSectionData &SD, MachObjectWriter &MOW) { + // Ignore virtual sections. + if (isVirtualSection(SD.getSection())) { + assert(SD.getFileSize() == 0); + return; + } + uint64_t Start = OS.tell(); (void) Start; @@ -1078,12 +1123,16 @@ static void WriteFileData(raw_ostream &OS, const MCSectionData &SD, } void MCAssembler::Finish() { - // Layout the sections and fragments. + // Layout the concrete sections and fragments. uint64_t Address = 0; MCSectionData *Prev = 0; for (iterator it = begin(), ie = end(); it != ie; ++it) { MCSectionData &SD = *it; + // Skip virtual sections. + if (isVirtualSection(SD.getSection())) + continue; + // Align this section if necessary by adding padding bytes to the previous // section. if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment())) { @@ -1100,6 +1149,18 @@ void MCAssembler::Finish() { Prev = &SD; } + // Layout the virtual sections. + for (iterator it = begin(), ie = end(); it != ie; ++it) { + MCSectionData &SD = *it; + + if (!isVirtualSection(SD.getSection())) + continue; + + SD.setAddress(Address); + LayoutSection(SD); + Address += SD.getSize(); + } + // Write the object file. MachObjectWriter MOW(OS); MOW.WriteObject(*this); diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 9f813fdc49e..b53a82e9586 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -278,7 +278,27 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, unsigned Size, unsigned Pow2Alignment) { - llvm_unreachable("FIXME: Not yet implemented!"); + unsigned ByteAlignment = 1 << Pow2Alignment; + MCSectionData &SectData = getSectionData(*Section); + + // The symbol may not be present, which only creates the section. + if (!Symbol) + return; + + // FIXME: Assert that this section has the zerofill type. + + assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); + + MCSymbolData &SD = getSymbolData(*Symbol); + + MCFragment *F = new MCZeroFillFragment(Size, 1 << Pow2Alignment, &SectData); + SD.setFragment(F); + + Symbol->setSection(*Section); + + // Update the maximum alignment on the zero fill section if necessary. + if (ByteAlignment > SectData.getAlignment()) + SectData.setAlignment(ByteAlignment); } void MCMachOStreamer::EmitBytes(const StringRef &Data) { diff --git a/test/MC/MachO/lcomm-attributes.s b/test/MC/MachO/lcomm-attributes.s new file mode 100644 index 00000000000..2685395e1ed --- /dev/null +++ b/test/MC/MachO/lcomm-attributes.s @@ -0,0 +1,136 @@ +// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump | FileCheck %s + + // Note, this test intentionally mismatches Darwin 'as', which loses the + // following global marker. + // + // FIXME: We should probably warn about our interpretation of this. + .globl sym_lcomm_ext_A + .lcomm sym_lcomm_ext_A, 4 + .lcomm sym_lcomm_ext_B, 4 + .globl sym_lcomm_ext_B + + .globl sym_zfill_ext_A + .zerofill __DATA, __bss, sym_zfill_ext_A, 4 + .zerofill __DATA, __bss, sym_zfill_ext_B, 4 + .globl sym_zfill_ext_B + +// CHECK: ('cputype', 7) +// CHECK: ('cpusubtype', 3) +// CHECK: ('filetype', 1) +// CHECK: ('num_load_commands', 1) +// CHECK: ('load_commands_size', 296) +// CHECK: ('flag', 0) +// CHECK: ('load_commands', [ +// CHECK: # Load Command 0 +// CHECK: (('command', 1) +// CHECK: ('size', 192) +// 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', 16) +// CHECK: ('file_offset', 324) +// CHECK: ('file_size', 0) +// CHECK: ('maxprot', 7) +// CHECK: ('initprot', 7) +// CHECK: ('num_sections', 2) +// 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', 324) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x80000000) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: # Section 1 +// CHECK: (('section_name', '__bss\x00\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', 16) +// CHECK: ('offset', 0) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x1) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: ]) +// CHECK: ), +// CHECK: # Load Command 1 +// CHECK: (('command', 2) +// CHECK: ('size', 24) +// CHECK: ('symoff', 324) +// CHECK: ('nsyms', 4) +// CHECK: ('stroff', 372) +// CHECK: ('strsize', 68) +// CHECK: ('_string_data', '\x00sym_lcomm_ext_A\x00sym_lcomm_ext_B\x00sym_zfill_ext_A\x00sym_zfill_ext_B\x00\x00\x00\x00') +// CHECK: ('_symbols', [ +// CHECK: # Symbol 0 +// CHECK: (('n_strx', 1) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 0) +// CHECK: ('_string', 'sym_lcomm_ext_A') +// CHECK: ), +// CHECK: # Symbol 1 +// CHECK: (('n_strx', 17) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 4) +// CHECK: ('_string', 'sym_lcomm_ext_B') +// CHECK: ), +// CHECK: # Symbol 2 +// CHECK: (('n_strx', 33) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 8) +// CHECK: ('_string', 'sym_zfill_ext_A') +// CHECK: ), +// CHECK: # Symbol 3 +// CHECK: (('n_strx', 49) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 12) +// CHECK: ('_string', 'sym_zfill_ext_B') +// CHECK: ), +// CHECK: ]) +// CHECK: ), +// CHECK: # Load Command 2 +// CHECK: (('command', 11) +// CHECK: ('size', 80) +// CHECK: ('ilocalsym', 0) +// CHECK: ('nlocalsym', 0) +// CHECK: ('iextdefsym', 0) +// CHECK: ('nextdefsym', 4) +// CHECK: ('iundefsym', 4) +// 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: ]) diff --git a/test/MC/MachO/zerofill-1.s b/test/MC/MachO/zerofill-1.s new file mode 100644 index 00000000000..a175d4c4d01 --- /dev/null +++ b/test/MC/MachO/zerofill-1.s @@ -0,0 +1,121 @@ +// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s + + .text + .byte 0 // Align to 2**3 bytes, not 2**1 + + .zerofill __DATA, __common, zfill, 2, 1 + + .data + .align 3 + +// 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', 10) +// CHECK: ('file_offset', 392) +// CHECK: ('file_size', 8) +// 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: ('_relocations', [ +// CHECK: ]) +// CHECK: # Section 1 +// CHECK: (('section_name', '__common\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('address', 8) +// CHECK: ('size', 2) +// CHECK: ('offset', 0) +// CHECK: ('alignment', 1) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x1) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: # Section 2 +// 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', 8) +// CHECK: ('size', 0) +// CHECK: ('offset', 400) +// CHECK: ('alignment', 3) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x0) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: ]) +// CHECK: ), +// CHECK: # Load Command 1 +// CHECK: (('command', 2) +// CHECK: ('size', 24) +// CHECK: ('symoff', 400) +// CHECK: ('nsyms', 1) +// CHECK: ('stroff', 412) +// CHECK: ('strsize', 8) +// CHECK: ('_string_data', '\x00zfill\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', 8) +// CHECK: ('_string', 'zfill') +// 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: ]) diff --git a/test/MC/MachO/zerofill-2.s b/test/MC/MachO/zerofill-2.s new file mode 100644 index 00000000000..e76de8453cb --- /dev/null +++ b/test/MC/MachO/zerofill-2.s @@ -0,0 +1,103 @@ +// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s + + .byte 0 + + // This file has size 2, the tail padding doesn't count. + .zerofill __DATA, __bss, sym_a, 1 + +// CHECK: ('cputype', 7) +// CHECK: ('cpusubtype', 3) +// CHECK: ('filetype', 1) +// CHECK: ('num_load_commands', 1) +// CHECK: ('load_commands_size', 296) +// CHECK: ('flag', 0) +// CHECK: ('load_commands', [ +// CHECK: # Load Command 0 +// CHECK: (('command', 1) +// CHECK: ('size', 192) +// 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', 2) +// CHECK: ('file_offset', 324) +// CHECK: ('file_size', 1) +// CHECK: ('maxprot', 7) +// CHECK: ('initprot', 7) +// CHECK: ('num_sections', 2) +// 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', 324) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x80000000) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: # Section 1 +// CHECK: (('section_name', '__bss\x00\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', 1) +// CHECK: ('size', 1) +// CHECK: ('offset', 0) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x1) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: ]) +// CHECK: ), +// CHECK: # Load Command 1 +// CHECK: (('command', 2) +// CHECK: ('size', 24) +// CHECK: ('symoff', 328) +// CHECK: ('nsyms', 1) +// CHECK: ('stroff', 340) +// CHECK: ('strsize', 8) +// CHECK: ('_string_data', '\x00sym_a\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', 1) +// CHECK: ('_string', 'sym_a') +// 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: ]) diff --git a/test/MC/MachO/zerofill-3.s b/test/MC/MachO/zerofill-3.s new file mode 100644 index 00000000000..e7f4c7b4441 --- /dev/null +++ b/test/MC/MachO/zerofill-3.s @@ -0,0 +1,141 @@ +// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s + + // FIXME: We don't get the order right currently, the assembler first + // orders the symbols, then assigns addresses. :( +.if 0 + .lcomm sym_lcomm_B, 4 + .lcomm sym_lcomm_C, 4, 4 + .lcomm sym_lcomm_A, 4, 3 + .lcomm sym_lcomm_D, 4 + .globl sym_lcomm_D + .globl sym_lcomm_C +.else + .lcomm sym_lcomm_C, 4, 4 + .lcomm sym_lcomm_D, 4 + .globl sym_lcomm_D + .globl sym_lcomm_C + + .lcomm sym_lcomm_A, 4, 3 + .lcomm sym_lcomm_B, 4 +.endif + +// CHECK: ('cputype', 7) +// CHECK: ('cpusubtype', 3) +// CHECK: ('filetype', 1) +// CHECK: ('num_load_commands', 1) +// CHECK: ('load_commands_size', 296) +// CHECK: ('flag', 0) +// CHECK: ('load_commands', [ +// CHECK: # Load Command 0 +// CHECK: (('command', 1) +// CHECK: ('size', 192) +// 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', 16) +// CHECK: ('file_offset', 324) +// CHECK: ('file_size', 0) +// CHECK: ('maxprot', 7) +// CHECK: ('initprot', 7) +// CHECK: ('num_sections', 2) +// 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', 324) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x80000000) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: # Section 1 +// CHECK: (('section_name', '__bss\x00\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', 16) +// CHECK: ('offset', 0) +// CHECK: ('alignment', 4) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x1) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: ]) +// CHECK: ), +// CHECK: # Load Command 1 +// CHECK: (('command', 2) +// CHECK: ('size', 24) +// CHECK: ('symoff', 324) +// CHECK: ('nsyms', 4) +// CHECK: ('stroff', 372) +// CHECK: ('strsize', 52) +// CHECK: ('_string_data', '\x00sym_lcomm_C\x00sym_lcomm_D\x00sym_lcomm_A\x00sym_lcomm_B\x00\x00\x00\x00') +// CHECK: ('_symbols', [ +// CHECK: # Symbol 0 +// CHECK: (('n_strx', 25) +// CHECK: ('n_type', 0xe) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 8) +// CHECK: ('_string', 'sym_lcomm_A') +// CHECK: ), +// CHECK: # Symbol 1 +// CHECK: (('n_strx', 37) +// CHECK: ('n_type', 0xe) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 12) +// CHECK: ('_string', 'sym_lcomm_B') +// CHECK: ), +// CHECK: # Symbol 2 +// CHECK: (('n_strx', 1) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 0) +// CHECK: ('_string', 'sym_lcomm_C') +// CHECK: ), +// CHECK: # Symbol 3 +// CHECK: (('n_strx', 13) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 4) +// CHECK: ('_string', 'sym_lcomm_D') +// CHECK: ), +// CHECK: ]) +// CHECK: ), +// CHECK: # Load Command 2 +// CHECK: (('command', 11) +// CHECK: ('size', 80) +// CHECK: ('ilocalsym', 0) +// CHECK: ('nlocalsym', 2) +// CHECK: ('iextdefsym', 2) +// CHECK: ('nextdefsym', 2) +// CHECK: ('iundefsym', 4) +// 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: ])