[llvm-commits] [llvm] r80067 - in /llvm/trunk: include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp test/MC/MachO/section-align-1.s test/MC/MachO/section-align-2.s
Daniel Dunbar
daniel at zuster.org
Tue Aug 25 21:13:32 PDT 2009
Author: ddunbar
Date: Tue Aug 25 23:13:32 2009
New Revision: 80067
URL: http://llvm.org/viewvc/llvm-project?rev=80067&view=rev
Log:
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.
Added:
llvm/trunk/test/MC/MachO/section-align-1.s
llvm/trunk/test/MC/MachO/section-align-2.s
Modified:
llvm/trunk/include/llvm/MC/MCAssembler.h
llvm/trunk/lib/MC/MCAssembler.cpp
Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=80067&r1=80066&r2=80067&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Tue Aug 25 23:13:32 2009
@@ -82,7 +82,7 @@
uint64_t getAddress() const;
- unsigned getFileSize() const {
+ uint64_t getFileSize() const {
assert(FileSize != ~UINT64_C(0) && "File size not set!");
return FileSize;
}
@@ -267,6 +267,9 @@
/// initialized.
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
/// initialized.
uint64_t FileSize;
@@ -305,13 +308,19 @@
//
// 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!");
return Address;
}
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!");
return FileSize;
}
@@ -414,7 +423,11 @@
/// LayoutSection - Assign offsets and sizes to the fragments in the section
/// \arg SD, and update the section size. The section file offset should
/// 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:
/// Construct a new assembler instance.
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=80067&r1=80066&r2=80067&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Tue Aug 25 23:13:32 2009
@@ -217,7 +217,7 @@
WriteString(Section.getSectionName(), 16);
WriteString(Section.getSegmentName(), 16);
Write32(SD.getAddress()); // address
- Write32(SD.getFileSize()); // size
+ Write32(SD.getSize()); // size
Write32(FileOffset);
assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
@@ -507,11 +507,6 @@
if (NumSymbols)
ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
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
// section headers) and the symbol table.
@@ -525,27 +520,22 @@
LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize;
}
- uint64_t FileOffset = Header32Size + LoadCommandsSize;
- uint64_t SectionDataStartOffset = FileOffset;
+ uint64_t SectionDataStart = Header32Size + LoadCommandsSize;
+ uint64_t SectionDataEnd = SectionDataStart;
uint64_t SectionDataSize = 0;
- unsigned Index = 0;
- for (MCAssembler::iterator it = Asm.begin(),
- ie = Asm.end(); it != ie; ++it, ++Index) {
- SectionFileOffsets[Index] = FileOffset;
- FileOffset += it->getFileSize();
- SectionDataSize += it->getFileSize();
+ if (!Asm.getSectionList().empty()) {
+ MCSectionData &SD = Asm.getSectionList().back();
+ SectionDataSize = SD.getAddress() + SD.getSize();
+ SectionDataEnd = SectionDataStart + SD.getAddress() + SD.getFileSize();
}
// Write the prolog, starting with the header and load command...
WriteHeader32(NumLoadCommands, LoadCommandsSize);
- WriteSegmentLoadCommand32(NumSections, SectionDataStartOffset,
- SectionDataSize);
+ WriteSegmentLoadCommand32(NumSections, SectionDataStart, SectionDataSize);
// ... and then the section headers.
- Index = 0;
- for (MCAssembler::iterator it = Asm.begin(),
- ie = Asm.end(); it != ie; ++it, ++Index)
- WriteSection32(*it, SectionFileOffsets[Index]);
+ for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
+ WriteSection32(*it, SectionDataStart + it->getAddress());
// Write the symbol table load command, if used.
if (NumSymbols) {
@@ -563,11 +553,10 @@
// If used, the indirect symbols are written after the section data.
if (NumIndirectSymbols)
- IndirectSymbolOffset = SectionDataStartOffset + SectionDataSize;
+ IndirectSymbolOffset = SectionDataEnd;
// The symbol table is written after the indirect symbol data.
- uint64_t SymbolTableOffset =
- SectionDataStartOffset + SectionDataSize + IndirectSymbolSize;
+ uint64_t SymbolTableOffset = SectionDataEnd + IndirectSymbolSize;
// The string table is written after symbol table.
uint64_t StringTableOffset =
@@ -675,6 +664,7 @@
: Section(_Section),
Alignment(1),
Address(~UINT64_C(0)),
+ Size(~UINT64_C(0)),
FileSize(~UINT64_C(0))
{
if (A)
@@ -701,26 +691,24 @@
MCAssembler::~MCAssembler() {
}
-void MCAssembler::LayoutSection(MCSectionData &SD) {
- uint64_t Offset = 0;
+void MCAssembler::LayoutSection(MCSectionData &SD, unsigned NextAlign) {
+ uint64_t Address = SD.getAddress();
for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) {
MCFragment &F = *it;
- F.setOffset(Offset);
+ F.setOffset(Address - SD.getAddress());
// Evaluate fragment size.
switch (F.getKind()) {
case MCFragment::FT_Align: {
MCAlignFragment &AF = cast<MCAlignFragment>(F);
- uint64_t AlignedOffset = RoundUpToAlignment(Offset, AF.getAlignment());
- uint64_t PaddingBytes = AlignedOffset - Offset;
-
- if (PaddingBytes > AF.getMaxBytesToEmit())
+ uint64_t Size = RoundUpToAlignment(Address, AF.getAlignment()) - Address;
+ if (Size > AF.getMaxBytesToEmit())
AF.setFileSize(0);
else
- AF.setFileSize(PaddingBytes);
+ AF.setFileSize(Size);
break;
}
@@ -735,22 +723,24 @@
if (!OF.getOffset().isAbsolute())
llvm_unreachable("FIXME: Not yet implemented!");
uint64_t OrgOffset = OF.getOffset().getConstant();
+ uint64_t Offset = Address - SD.getAddress();
// FIXME: We need a way to communicate this error.
if (OrgOffset < Offset)
llvm_report_error("invalid .org offset '" + Twine(OrgOffset) +
- "' (section offset '" + Twine(Offset) + "'");
+ "' (at offset '" + Twine(Offset) + "'");
F.setFileSize(OrgOffset - Offset);
break;
}
}
- Offset += F.getFileSize();
+ Address += F.getFileSize();
}
- // FIXME: Pad section?
- SD.setFileSize(Offset);
+ // Set the section sizes.
+ SD.setSize(Address - SD.getAddress());
+ SD.setFileSize(RoundUpToAlignment(Address, NextAlign) - SD.getAddress());
}
/// WriteFileData - Write the \arg F data to the output file.
@@ -836,16 +826,32 @@
ie = SD.end(); it != ie; ++it)
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());
}
void MCAssembler::Finish() {
// Layout the sections and fragments.
uint64_t Address = 0;
- for (iterator it = begin(), ie = end(); it != ie; ++it) {
- it->setAddress(Address);
- LayoutSection(*it);
- Address += it->getFileSize();
+ for (iterator it = begin(), ie = end(); it != ie;) {
+ MCSectionData &SD = *it;
+
+ // 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.
Added: llvm/trunk/test/MC/MachO/section-align-1.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/section-align-1.s?rev=80067&view=auto
==============================================================================
--- llvm/trunk/test/MC/MachO/section-align-1.s (added)
+++ llvm/trunk/test/MC/MachO/section-align-1.s Tue Aug 25 23:13:32 2009
@@ -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: ])
Added: llvm/trunk/test/MC/MachO/section-align-2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/section-align-2.s?rev=80067&view=auto
==============================================================================
--- llvm/trunk/test/MC/MachO/section-align-2.s (added)
+++ llvm/trunk/test/MC/MachO/section-align-2.s Tue Aug 25 23:13:32 2009
@@ -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: ])
More information about the llvm-commits
mailing list