summaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-08-28 05:49:04 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-08-28 05:49:04 +0000
commitedc670f3f2ba629b6803a1a7ed4aa47061afd276 (patch)
treebe78296dcb875b7b15ae93cc5b89d37b9cc473f4 /lib/MC
parent0f5fa6955199cc7e0964524d73c8a9820d8f78c1 (diff)
downloadllvm-edc670f3f2ba629b6803a1a7ed4aa47061afd276.tar.gz
llvm-edc670f3f2ba629b6803a1a7ed4aa47061afd276.tar.bz2
llvm-edc670f3f2ba629b6803a1a7ed4aa47061afd276.tar.xz
llvm-mc: Tweak section alignment and size computation to match 'as' closer.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80345 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCAssembler.cpp62
1 files changed, 42 insertions, 20 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index a01d8de46b..1375b77958 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -203,6 +203,7 @@ public:
/// \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)
@@ -215,7 +216,7 @@ public:
WriteString("", 16);
Write32(0); // vmaddr
- Write32(SectionDataSize); // vmsize
+ Write32(VMSize); // vmsize
Write32(SectionDataStartOffset); // file offset
Write32(SectionDataSize); // file size
Write32(0x7); // maxprot
@@ -679,19 +680,35 @@ public:
LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize;
}
+ // Compute the total size of the section data, as well as its file size and
+ // vm size.
uint64_t SectionDataStart = Header32Size + LoadCommandsSize;
- uint64_t SectionDataEnd = SectionDataStart;
uint64_t SectionDataSize = 0;
- if (!Asm.getSectionList().empty()) {
- MCSectionData &SD = Asm.getSectionList().back();
- SectionDataSize = SD.getAddress() + SD.getSize();
- SectionDataEnd = SectionDataStart + SD.getAddress() + SD.getFileSize();
+ uint64_t SectionDataFileSize = 0;
+ uint64_t VMSize = 0;
+ for (MCAssembler::iterator it = Asm.begin(),
+ ie = Asm.end(); it != ie; ++it) {
+ MCSectionData &SD = *it;
+
+ VMSize = std::max(VMSize, SD.getAddress() + SD.getSize());
+
+ SectionDataSize = std::max(SectionDataSize,
+ SD.getAddress() + SD.getSize());
+ SectionDataFileSize = std::max(SectionDataFileSize,
+ SD.getAddress() + SD.getFileSize());
}
+ // The section data is passed to 4 bytes.
+ //
+ // FIXME: Is this machine dependent?
+ unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
+ SectionDataFileSize += SectionDataPadding;
+
// Write the prolog, starting with the header and load command...
WriteHeader32(NumLoadCommands, LoadCommandsSize,
Asm.getSubsectionsViaSymbols());
- WriteSegmentLoadCommand32(NumSections, SectionDataStart, SectionDataSize);
+ WriteSegmentLoadCommand32(NumSections, VMSize,
+ SectionDataStart, SectionDataSize);
// ... and then the section headers.
//
@@ -700,7 +717,7 @@ public:
// value; this will be overwrite the appropriate data in the fragment when
// it is written.
std::vector<MachRelocationEntry> RelocInfos;
- uint64_t RelocTableEnd = SectionDataEnd;
+ uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie;
++it) {
MCSectionData &SD = *it;
@@ -756,6 +773,9 @@ public:
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
WriteFileData(OS, *it, *this);
+ // Write the extra padding.
+ WriteZeros(SectionDataPadding);
+
// Write the relocation entries.
for (unsigned i = 0, e = RelocInfos.size(); i != e; ++i) {
Write32(RelocInfos[i].Word0);
@@ -889,7 +909,7 @@ MCAssembler::MCAssembler(raw_ostream &_OS)
MCAssembler::~MCAssembler() {
}
-void MCAssembler::LayoutSection(MCSectionData &SD, unsigned NextAlign) {
+void MCAssembler::LayoutSection(MCSectionData &SD) {
uint64_t Address = SD.getAddress();
for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) {
@@ -955,7 +975,7 @@ void MCAssembler::LayoutSection(MCSectionData &SD, unsigned NextAlign) {
// Set the section sizes.
SD.setSize(Address - SD.getAddress());
- SD.setFileSize(RoundUpToAlignment(Address, NextAlign) - SD.getAddress());
+ SD.setFileSize(Address - SD.getAddress());
}
/// WriteFileData - Write the \arg F data to the output file.
@@ -1060,22 +1080,24 @@ static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
void MCAssembler::Finish() {
// Layout the sections and fragments.
uint64_t Address = 0;
- for (iterator it = begin(), ie = end(); it != ie;) {
+ MCSectionData *Prev = 0;
+ for (iterator it = begin(), ie = end(); it != ie; ++it) {
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();
+ // Align this section if necessary by adding padding bytes to the previous
+ // section.
+ if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment())) {
+ assert(Prev && "Missing prev section!");
+ Prev->setFileSize(Prev->getFileSize() + Pad);
+ Address += Pad;
+ }
// Layout the section fragments and its size.
SD.setAddress(Address);
- LayoutSection(SD, NextAlign);
+ LayoutSection(SD);
Address += SD.getFileSize();
+
+ Prev = &SD;
}
// Write the object file.