[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