forked from OSchip/llvm-project
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. llvm-svn: 239216
This commit is contained in:
parent
468f670021
commit
743afa0736
|
@ -37,9 +37,16 @@ SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H, uint32_t SI)
|
|||
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(SectionChunk *Child) {
|
|||
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 *Buf) {
|
|||
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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -413,13 +413,6 @@ OutputSection *Writer::createSection(StringRef Name) {
|
|||
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 OutputPath) {
|
|||
return EC;
|
||||
writeHeader();
|
||||
writeSections();
|
||||
applyRelocations();
|
||||
return Buffer->commit();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue