llvm-mc/Mach-O: Move more logic for writing the Mach-O file into the writer
authorDaniel Dunbar <daniel@zuster.org>
Sat, 22 Aug 2009 08:28:27 +0000 (08:28 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sat, 22 Aug 2009 08:28:27 +0000 (08:28 +0000)
class, and kill off MCSectionData::FileOffset.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79735 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCAssembler.h
lib/MC/MCAssembler.cpp

index bb2cda90945ef9d42432e390fa94cdfce6eb191f..86ad502c7e08f9b48e945d8a00e85cf181c8f3f1 100644 (file)
@@ -254,10 +254,6 @@ private:
   //
   // FIXME: This could all be kept private to the assembler implementation.
 
-  /// FileOffset - The offset of this section in the object file. This is ~0
-  /// until initialized.
-  uint64_t FileOffset;
-
   /// FileSize - The size of this section in the object file. This is ~0 until
   /// initialized.
   uint64_t FileSize;
@@ -301,12 +297,6 @@ public:
   }
   void setFileSize(uint64_t Value) { FileSize = Value; }
 
-  uint64_t getFileOffset() const {
-    assert(FileOffset != ~UINT64_C(0) && "File offset not set!");
-    return FileOffset;
-  }
-  void setFileOffset(uint64_t Value) { FileOffset = Value; }
-
   /// @}
 };
 
index 16864f960725758faec42b644b8decff5dc88407..f822711d4a2249f5e6c65535c506950fc48036e5 100644 (file)
@@ -102,11 +102,6 @@ public:
 
   /// @}
   
-  static unsigned getPrologSize32(unsigned NumSections) {
-    return Header32Size + SegmentLoadCommand32Size + 
-      NumSections * Section32Size;
-  }
-
   void WriteHeader32(unsigned NumSections) {
     // struct mach_header (28 bytes)
 
@@ -166,7 +161,7 @@ public:
     assert(OS.tell() - Start == SegmentLoadCommand32Size);
   }
 
-  void WriteSection32(const MCSectionData &SD) {
+  void WriteSection32(const MCSectionData &SD, uint64_t FileOffset) {
     // struct section (68 bytes)
 
     uint64_t Start = OS.tell();
@@ -179,7 +174,7 @@ public:
     WriteString(Section.getSegmentName(), 16);
     Write32(0); // address
     Write32(SD.getFileSize()); // size
-    Write32(SD.getFileOffset());
+    Write32(FileOffset);
 
     assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
     Write32(Log2_32(SD.getAlignment()));
@@ -191,6 +186,39 @@ public:
 
     assert(OS.tell() - Start == Section32Size);
   }
+
+  void WriteProlog(MCAssembler &Asm) {
+    unsigned NumSections = Asm.size();
+
+    // 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
+    // the section headers.
+    uint64_t FileOffset = Header32Size + SegmentLoadCommand32Size + 
+      NumSections * Section32Size;
+    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();
+    }
+
+    // Write the prolog, starting with the header and load command...
+    WriteHeader32(NumSections);
+    WriteSegmentLoadCommand32(NumSections, 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]);
+  }
+
 };
 
 }
@@ -218,7 +246,6 @@ MCSectionData::MCSectionData() : Section(*(MCSection*)0) {}
 MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
   : Section(_Section),
     Alignment(1),
-    FileOffset(~UINT64_C(0)),
     FileSize(~UINT64_C(0))
 {
   if (A)
@@ -369,31 +396,17 @@ static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
 }
 
 void MCAssembler::Finish() {
-  unsigned NumSections = Sections.size();
-
   // Layout the sections and fragments.
-  uint64_t Offset = MachObjectWriter::getPrologSize32(NumSections);
-  uint64_t SectionDataSize = 0;
-  for (iterator it = begin(), ie = end(); it != ie; ++it) {
-    it->setFileOffset(Offset);
-
+  for (iterator it = begin(), ie = end(); it != ie; ++it)
     LayoutSection(*it);
 
-    Offset += it->getFileSize();
-    SectionDataSize += it->getFileSize();
-  }
-
   MachObjectWriter MOW(OS);
 
-  // Write the prolog, starting with the header and load command...
-  MOW.WriteHeader32(NumSections);
-  MOW.WriteSegmentLoadCommand32(NumSections, SectionDataSize);
-  
-  // ... and then the section headers.
-  for (iterator it = begin(), ie = end(); it != ie; ++it)
-    MOW.WriteSection32(*it);
+  // Write the prolog, followed by the data for all the sections & fragments.
+  MOW.WriteProlog(*this);
 
-  // Finally, write the section data.
+  // FIXME: This should move into the Mach-O writer, it should have control over
+  // what goes where.
   for (iterator it = begin(), ie = end(); it != ie; ++it)
     WriteFileData(OS, *it, MOW);