[lld] r239216 - COFF: Merge Chunk::applyRelocations with Chunk::writeTo.

Rui Ueyama ruiu at google.com
Fri Jun 5 21:07:39 PDT 2015


Author: ruiu
Date: Fri Jun  5 23:07:39 2015
New Revision: 239216

URL: http://llvm.org/viewvc/llvm-project?rev=239216&view=rev
Log:
COFF: Merge Chunk::applyRelocations with Chunk::writeTo.

In this design, Chunk is the only thing that knows how to write
its contents to output file as well as how to apply relocations
there. The writer shouldn't know about the details.

Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Chunks.h
    lld/trunk/COFF/Writer.cpp

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=239216&r1=239215&r2=239216&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Fri Jun  5 23:07:39 2015
@@ -37,9 +37,16 @@ SectionChunk::SectionChunk(ObjectFile *F
 void SectionChunk::writeTo(uint8_t *Buf) {
   if (!hasData())
     return;
+  // Copy section contents from source object file to output file.
   ArrayRef<uint8_t> Data;
   File->getCOFFObj()->getSectionContents(Header, Data);
   memcpy(Buf + FileOff, Data.data(), Data.size());
+
+  // Apply relocations.
+  for (const auto &I : getSectionRef().relocations()) {
+    const coff_relocation *Rel = File->getCOFFObj()->getCOFFRelocation(I);
+    applyReloc(Buf, Rel);
+  }
 }
 
 // Returns true if this chunk should be considered as a GC root.
@@ -80,13 +87,6 @@ void SectionChunk::addAssociative(Sectio
   AssocChildren.push_back(Child);
 }
 
-void SectionChunk::applyRelocations(uint8_t *Buf) {
-  for (const auto &I : getSectionRef().relocations()) {
-    const coff_relocation *Rel = File->getCOFFObj()->getCOFFRelocation(I);
-    applyReloc(Buf, Rel);
-  }
-}
-
 static void add16(uint8_t *P, int32_t V) { write16le(P, read16le(P) + V); }
 static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
 static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
@@ -163,11 +163,8 @@ void StringChunk::writeTo(uint8_t *Buf)
 
 void ImportThunkChunk::writeTo(uint8_t *Buf) {
   memcpy(Buf + FileOff, ImportThunkData, sizeof(ImportThunkData));
-}
-
-void ImportThunkChunk::applyRelocations(uint8_t *Buf) {
+  // The first two bytes is a JMP instruction. Fill its operand.
   uint32_t Operand = ImpSymbol->getRVA() - RVA - getSize();
-  // The first two bytes are a JMP instruction. Fill its operand.
   write32le(Buf + FileOff + 2, Operand);
 }
 
@@ -182,7 +179,7 @@ void HintNameChunk::writeTo(uint8_t *Buf
   memcpy(Buf + FileOff + 2, Name.data(), Name.size());
 }
 
-void LookupChunk::applyRelocations(uint8_t *Buf) {
+void LookupChunk::writeTo(uint8_t *Buf) {
   write32le(Buf + FileOff, HintName->getRVA());
 }
 
@@ -192,7 +189,7 @@ void OrdinalOnlyChunk::writeTo(uint8_t *
   write64le(Buf + FileOff, (uint64_t(1) << 63) | Ordinal);
 }
 
-void DirectoryChunk::applyRelocations(uint8_t *Buf) {
+void DirectoryChunk::writeTo(uint8_t *Buf) {
   auto *E = (coff_import_directory_table_entry *)(Buf + FileOff);
   E->ImportLookupTableRVA = LookupTab->getRVA();
   E->NameRVA = DLLName->getRVA();

Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=239216&r1=239215&r2=239216&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Fri Jun  5 23:07:39 2015
@@ -42,7 +42,10 @@ public:
   // Returns the size of this chunk (even if this is a common or BSS.)
   virtual size_t getSize() const = 0;
 
-  // Write this chunk to a mmap'ed file. Buf is pointing to beginning of file.
+  // Write this chunk to a mmap'ed file, assuming Buf is pointing to
+  // beginning of the file. Because this function may use RVA values
+  // of other chunks for relocations, you need to set them properly
+  // before calling this function.
   virtual void writeTo(uint8_t *Buf) {}
 
   // The writer sets and uses the addresses.
@@ -52,12 +55,6 @@ public:
   void setRVA(uint64_t V) { RVA = V; }
   void setFileOff(uint64_t V) { FileOff = V; }
 
-  // Applies relocations, assuming Buffer points to beginning of an
-  // mmap'ed output file. Because this function uses file offsets and
-  // RVA values of other chunks, you need to set them properly before
-  // calling this function.
-  virtual void applyRelocations(uint8_t *Buf) {}
-
   // Returns true if this has non-zero data. BSS chunks return
   // false. If false is returned, the space occupied by this chunk
   // will be filled with zeros.
@@ -116,7 +113,6 @@ public:
                uint32_t SectionIndex);
   size_t getSize() const override { return Header->SizeOfRawData; }
   void writeTo(uint8_t *Buf) override;
-  void applyRelocations(uint8_t *Buf) override;
   bool hasData() const override;
   uint32_t getPermissions() const override;
   StringRef getSectionName() const override { return SectionName; }
@@ -185,7 +181,6 @@ public:
   explicit ImportThunkChunk(Defined *S) : ImpSymbol(S) {}
   size_t getSize() const override { return sizeof(ImportThunkData); }
   void writeTo(uint8_t *Buf) override;
-  void applyRelocations(uint8_t *Buf) override;
 
 private:
   Defined *ImpSymbol;
@@ -207,9 +202,8 @@ private:
 class LookupChunk : public Chunk {
 public:
   explicit LookupChunk(Chunk *C) : HintName(C) {}
-  bool hasData() const override { return false; }
   size_t getSize() const override { return sizeof(uint64_t); }
-  void applyRelocations(uint8_t *Buf) override;
+  void writeTo(uint8_t *Buf) override;
   Chunk *HintName;
 };
 
@@ -219,7 +213,6 @@ public:
 class OrdinalOnlyChunk : public Chunk {
 public:
   explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {}
-  bool hasData() const override { return true; }
   size_t getSize() const override { return sizeof(uint64_t); }
   void writeTo(uint8_t *Buf) override;
   uint16_t Ordinal;
@@ -229,9 +222,8 @@ public:
 class DirectoryChunk : public Chunk {
 public:
   explicit DirectoryChunk(Chunk *N) : DLLName(N) {}
-  bool hasData() const override { return false; }
   size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
-  void applyRelocations(uint8_t *Buf) override;
+  void writeTo(uint8_t *Buf) override;
 
   Chunk *DLLName;
   Chunk *LookupTab;

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=239216&r1=239215&r2=239216&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Fri Jun  5 23:07:39 2015
@@ -413,13 +413,6 @@ OutputSection *Writer::createSection(Str
   return Sec;
 }
 
-void Writer::applyRelocations() {
-  uint8_t *Buf = Buffer->getBufferStart();
-  for (OutputSection *Sec : OutputSections)
-    for (Chunk *C : Sec->getChunks())
-      C->applyRelocations(Buf);
-}
-
 std::error_code Writer::write(StringRef OutputPath) {
   markLive();
   createSections();
@@ -430,7 +423,6 @@ std::error_code Writer::write(StringRef
     return EC;
   writeHeader();
   writeSections();
-  applyRelocations();
   return Buffer->commit();
 }
 





More information about the llvm-commits mailing list