[lld] r238464 - COFF: Teach Chunk to write to a mmap'ed output file.

Rui Ueyama ruiu at google.com
Thu May 28 12:45:43 PDT 2015


Author: ruiu
Date: Thu May 28 14:45:43 2015
New Revision: 238464

URL: http://llvm.org/viewvc/llvm-project?rev=238464&view=rev
Log:
COFF: Teach Chunk to write to a mmap'ed output file.

Previously Writer directly handles writes to a file.
Chunks needed to give Writer a continuous chunk of memory.
That was inefficent if you construct data in chunks because
it would require two memory copies (one to construct a chunk
and the other is to write that to a file).

This patch teaches chunk to write directly to a file.
>From readability point of view, this is also good because
you no longer have to call hasData() before calling getData().

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=238464&r1=238463&r2=238464&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Thu May 28 14:45:43 2015
@@ -35,11 +35,11 @@ SectionChunk::SectionChunk(ObjectFile *F
   Align = uint32_t(1) << Shift;
 }
 
-const uint8_t *SectionChunk::getData() const {
+void SectionChunk::writeTo(uint8_t *Buf) {
   assert(hasData());
   ArrayRef<uint8_t> Data;
   File->getCOFFObj()->getSectionContents(Header, Data);
-  return Data.data();
+  memcpy(Buf + FileOff, Data.data(), Data.size());
 }
 
 // Returns true if this chunk should be considered as a GC root.
@@ -157,9 +157,12 @@ uint32_t CommonChunk::getPermissions() c
          IMAGE_SCN_MEM_WRITE;
 }
 
-StringChunk::StringChunk(StringRef S) : Data(S.size() + 1) {
-  memcpy(Data.data(), S.data(), S.size());
-  Data[S.size()] = 0;
+void StringChunk::writeTo(uint8_t *Buf) {
+  memcpy(Buf + FileOff, Str.data(), Str.size());
+}
+
+void ImportThunkChunk::writeTo(uint8_t *Buf) {
+  memcpy(Buf + FileOff, ImportThunkData, sizeof(ImportThunkData));
 }
 
 void ImportThunkChunk::applyRelocations(uint8_t *Buf) {
@@ -168,9 +171,12 @@ void ImportThunkChunk::applyRelocations(
   write32le(Buf + FileOff + 2, Operand);
 }
 
-HintNameChunk::HintNameChunk(StringRef Name)
-    : Data(RoundUpToAlignment(Name.size() + 4, 2)) {
-  memcpy(&Data[2], Name.data(), Name.size());
+HintNameChunk::HintNameChunk(StringRef N)
+    : Name(N), Size(RoundUpToAlignment(Name.size() + 4, 2)) {}
+
+void HintNameChunk::writeTo(uint8_t *Buf) {
+  // The first two bytes is Hint/Name field.
+  memcpy(Buf + FileOff + 2, Name.data(), Name.size());
 }
 
 void LookupChunk::applyRelocations(uint8_t *Buf) {

Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=238464&r1=238463&r2=238464&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Thu May 28 14:45:43 2015
@@ -39,15 +39,12 @@ class Chunk {
 public:
   virtual ~Chunk() = default;
 
-  // Returns the pointer to data. It is illegal to call this function if
-  // this is a common or BSS chunk.
-  virtual const uint8_t *getData() const {
-    llvm_unreachable("unimplemented getData");
-  }
-
   // 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.
+  virtual void writeTo(uint8_t *Buf) {}
+
   // The writer sets and uses the addresses.
   uint64_t getRVA() { return RVA; }
   uint64_t getFileOff() { return FileOff; }
@@ -61,9 +58,9 @@ public:
   // calling this function.
   virtual void applyRelocations(uint8_t *Buf) {}
 
-  // Returns true if getData() returns a valid pointer to data.
-  // BSS chunks return false. If false is returned, the space occupied
-  // by this chunk is filled with zeros.
+  // 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.
   virtual bool hasData() const { return true; }
 
   // Returns readable/writable/executable bits.
@@ -117,8 +114,8 @@ class SectionChunk : public Chunk {
 public:
   SectionChunk(ObjectFile *File, const coff_section *Header,
                uint32_t SectionIndex);
-  const uint8_t *getData() const override;
   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;
@@ -165,12 +162,12 @@ private:
 // A chunk for linker-created strings.
 class StringChunk : public Chunk {
 public:
-  explicit StringChunk(StringRef S);
-  const uint8_t *getData() const override { return &Data[0]; }
-  size_t getSize() const override { return Data.size(); }
+  explicit StringChunk(StringRef S) : Str(S) {}
+  size_t getSize() const override { return Str.size() + 1; }
+  void writeTo(uint8_t *Buf) override;
 
 private:
-  std::vector<uint8_t> Data;
+  StringRef Str;
 };
 
 // All chunks below are for the DLL import descriptor table and
@@ -186,8 +183,8 @@ static const uint8_t ImportThunkData[] =
 class ImportThunkChunk : public Chunk {
 public:
   explicit ImportThunkChunk(Defined *S) : ImpSymbol(S) {}
-  const uint8_t *getData() const override { return ImportThunkData; }
   size_t getSize() const override { return sizeof(ImportThunkData); }
+  void writeTo(uint8_t *Buf) override;
   void applyRelocations(uint8_t *Buf) override;
 
 private:
@@ -198,11 +195,12 @@ private:
 class HintNameChunk : public Chunk {
 public:
   explicit HintNameChunk(StringRef Name);
-  const uint8_t *getData() const override { return Data.data(); }
-  size_t getSize() const override { return Data.size(); }
+  size_t getSize() const override { return Size; }
+  void writeTo(uint8_t *Buf) override;
 
 private:
-  std::vector<uint8_t> Data;
+  StringRef Name;
+  size_t Size;
 };
 
 // A chunk for the import descriptor table.

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=238464&r1=238463&r2=238464&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Thu May 28 14:45:43 2015
@@ -312,8 +312,7 @@ void Writer::writeSections() {
     if (Sec->getPermissions() & IMAGE_SCN_CNT_CODE)
       memset(Buf + Sec->getFileOff(), 0xCC, Sec->getRawSize());
     for (Chunk *C : Sec->getChunks())
-      if (C->hasData())
-        memcpy(Buf + C->getFileOff(), C->getData(), C->getSize());
+      C->writeTo(Buf);
   }
 }
 





More information about the llvm-commits mailing list