[llvm-commits] [llvm] r80345 - in /llvm/trunk: include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp

Daniel Dunbar daniel at zuster.org
Thu Aug 27 22:49:05 PDT 2009


Author: ddunbar
Date: Fri Aug 28 00:49:04 2009
New Revision: 80345

URL: http://llvm.org/viewvc/llvm-project?rev=80345&view=rev
Log:
llvm-mc: Tweak section alignment and size computation to match 'as' closer.

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=80345&r1=80344&r2=80345&view=diff

==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Fri Aug 28 00:49:04 2009
@@ -502,11 +502,7 @@
   /// 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.
-  ///
-  /// \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);
+  void LayoutSection(MCSectionData &SD);
 
 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=80345&r1=80344&r2=80345&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Fri Aug 28 00:49:04 2009
@@ -203,6 +203,7 @@
   /// \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 @@
 
     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 @@
       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 @@
     // 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 @@
     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() {
 }
 
-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 @@
 
   // 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 @@
 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.





More information about the llvm-commits mailing list