[COFF] Simplify Chunk::writeTo and remove OutputSectionOff, NFC
Summary:
Prior to this change, every implementation of writeTo would add
OutputSectionOff to the output section buffer start before writing data.
Instead, do this math in the caller, so that it can be written once
instead of many times.
The output section offset is always equivalent to the difference between
the chunk RVA and the output section RVA, so we can replace the one
remaining usage of OutputSectionOff with that subtraction.
This doesn't change the size of SectionChunk because of alignment
requirements, but I will rearrange the fields in a follow-up change to
accomplish that.
Reviewers: ruiu, aganea
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D61696
llvm-svn: 360376
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 1669124..353d9d9 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -344,7 +344,7 @@
// Copy section contents from source object file to output file.
ArrayRef<uint8_t> A = getContents();
if (!A.empty())
- memcpy(Buf + OutputSectionOff, A.data(), A.size());
+ memcpy(Buf, A.data(), A.size());
// Apply relocations.
size_t InputSize = getSize();
@@ -360,7 +360,7 @@
continue;
}
- uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
+ uint8_t *Off = Buf + Rel.VirtualAddress;
auto *Sym =
dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
@@ -649,8 +649,8 @@
}
void StringChunk::writeTo(uint8_t *Buf) const {
- memcpy(Buf + OutputSectionOff, Str.data(), Str.size());
- Buf[OutputSectionOff + Str.size()] = '\0';
+ memcpy(Buf, Str.data(), Str.size());
+ Buf[Str.size()] = '\0';
}
ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
@@ -660,9 +660,9 @@
}
void ImportThunkChunkX64::writeTo(uint8_t *Buf) const {
- memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
+ memcpy(Buf, ImportThunkX86, sizeof(ImportThunkX86));
// The first two bytes is a JMP instruction. Fill its operand.
- write32le(Buf + OutputSectionOff + 2, ImpSymbol->getRVA() - RVA - getSize());
+ write32le(Buf + 2, ImpSymbol->getRVA() - RVA - getSize());
}
void ImportThunkChunkX86::getBaserels(std::vector<Baserel> *Res) {
@@ -670,9 +670,9 @@
}
void ImportThunkChunkX86::writeTo(uint8_t *Buf) const {
- memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
+ memcpy(Buf, ImportThunkX86, sizeof(ImportThunkX86));
// The first two bytes is a JMP instruction. Fill its operand.
- write32le(Buf + OutputSectionOff + 2,
+ write32le(Buf + 2,
ImpSymbol->getRVA() + Config->ImageBase);
}
@@ -681,16 +681,16 @@
}
void ImportThunkChunkARM::writeTo(uint8_t *Buf) const {
- memcpy(Buf + OutputSectionOff, ImportThunkARM, sizeof(ImportThunkARM));
+ memcpy(Buf, ImportThunkARM, sizeof(ImportThunkARM));
// Fix mov.w and mov.t operands.
- applyMOV32T(Buf + OutputSectionOff, ImpSymbol->getRVA() + Config->ImageBase);
+ applyMOV32T(Buf, ImpSymbol->getRVA() + Config->ImageBase);
}
void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const {
int64_t Off = ImpSymbol->getRVA() & 0xfff;
- memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64));
- applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA, 12);
- applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
+ memcpy(Buf, ImportThunkARM64, sizeof(ImportThunkARM64));
+ applyArm64Addr(Buf, ImpSymbol->getRVA(), RVA, 12);
+ applyArm64Ldr(Buf + 4, Off);
}
// A Thumb2, PIC, non-interworking range extension thunk.
@@ -708,8 +708,8 @@
void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const {
assert(Config->Machine == ARMNT);
uint64_t Offset = Target->getRVA() - RVA - 12;
- memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk));
- applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset));
+ memcpy(Buf, ArmThunk, sizeof(ArmThunk));
+ applyMOV32T(Buf, uint32_t(Offset));
}
// A position independent ARM64 adrp+add thunk, with a maximum range of
@@ -727,9 +727,9 @@
void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const {
assert(Config->Machine == ARM64);
- memcpy(Buf + OutputSectionOff, Arm64Thunk, sizeof(Arm64Thunk));
- applyArm64Addr(Buf + OutputSectionOff + 0, Target->getRVA(), RVA, 12);
- applyArm64Imm(Buf + OutputSectionOff + 4, Target->getRVA() & 0xfff, 0);
+ memcpy(Buf, Arm64Thunk, sizeof(Arm64Thunk));
+ applyArm64Addr(Buf + 0, Target->getRVA(), RVA, 12);
+ applyArm64Imm(Buf + 4, Target->getRVA() & 0xfff, 0);
}
void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
@@ -740,14 +740,14 @@
void LocalImportChunk::writeTo(uint8_t *Buf) const {
if (Config->is64()) {
- write64le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
+ write64le(Buf, Sym->getRVA() + Config->ImageBase);
} else {
- write32le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
+ write32le(Buf, Sym->getRVA() + Config->ImageBase);
}
}
void RVATableChunk::writeTo(uint8_t *Buf) const {
- ulittle32_t *Begin = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
+ ulittle32_t *Begin = reinterpret_cast<ulittle32_t *>(Buf);
size_t Cnt = 0;
for (const ChunkAndOffset &CO : Syms)
Begin[Cnt++] = CO.InputChunk->getRVA() + CO.Offset;
@@ -768,7 +768,7 @@
if (Relocs.empty())
return;
- ulittle32_t *Table = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
+ ulittle32_t *Table = reinterpret_cast<ulittle32_t *>(Buf);
// This is the list header, to signal the runtime pseudo relocation v2
// format.
Table[0] = 0;
@@ -838,7 +838,7 @@
}
void BaserelChunk::writeTo(uint8_t *Buf) const {
- memcpy(Buf + OutputSectionOff, Data.data(), Data.size());
+ memcpy(Buf, Data.data(), Data.size());
}
uint8_t Baserel::getDefaultType() {
@@ -883,7 +883,6 @@
size_t Off = Builder.getOffset(toStringRef(C->getContents()));
C->setOutputSection(Out);
C->setRVA(RVA + Off);
- C->OutputSectionOff = OutputSectionOff + Off;
}
}
@@ -896,7 +895,7 @@
}
void MergeChunk::writeTo(uint8_t *Buf) const {
- Builder.write(Buf + OutputSectionOff);
+ Builder.write(Buf);
}
// MinGW specific.
@@ -904,9 +903,9 @@
void AbsolutePointerChunk::writeTo(uint8_t *Buf) const {
if (Config->is64()) {
- write64le(Buf + OutputSectionOff, Value);
+ write64le(Buf, Value);
} else {
- write32le(Buf + OutputSectionOff, Value);
+ write32le(Buf, Value);
}
}
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index 223141b..2b3bd29 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -121,10 +121,6 @@
// The RVA of this chunk in the output. The writer sets a value.
uint32_t RVA = 0;
-public:
- // The offset from beginning of the output section. The writer sets a value.
- uint32_t OutputSectionOff = 0;
-
protected:
// The output section for this chunk.
OutputSection *Out = nullptr;
diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index 6c31b78..815ba27 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -46,9 +46,9 @@
}
void writeTo(uint8_t *Buf) const override {
- memset(Buf + OutputSectionOff, 0, getSize());
- write16le(Buf + OutputSectionOff, Hint);
- memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());
+ memset(Buf, 0, getSize());
+ write16le(Buf, Hint);
+ memcpy(Buf + 2, Name.data(), Name.size());
}
private:
@@ -64,9 +64,9 @@
void writeTo(uint8_t *Buf) const override {
if (Config->is64())
- write64le(Buf + OutputSectionOff, HintName->getRVA());
+ write64le(Buf, HintName->getRVA());
else
- write32le(Buf + OutputSectionOff, HintName->getRVA());
+ write32le(Buf, HintName->getRVA());
}
Chunk *HintName;
@@ -86,9 +86,9 @@
// An import-by-ordinal slot has MSB 1 to indicate that
// this is import-by-ordinal (and not import-by-name).
if (Config->is64()) {
- write64le(Buf + OutputSectionOff, (1ULL << 63) | Ordinal);
+ write64le(Buf, (1ULL << 63) | Ordinal);
} else {
- write32le(Buf + OutputSectionOff, (1ULL << 31) | Ordinal);
+ write32le(Buf, (1ULL << 31) | Ordinal);
}
}
@@ -102,9 +102,9 @@
size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
void writeTo(uint8_t *Buf) const override {
- memset(Buf + OutputSectionOff, 0, getSize());
+ memset(Buf, 0, getSize());
- auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
+ auto *E = (coff_import_directory_table_entry *)(Buf);
E->ImportLookupTableRVA = LookupTab->getRVA();
E->NameRVA = DLLName->getRVA();
E->ImportAddressTableRVA = AddressTab->getRVA();
@@ -124,7 +124,7 @@
size_t getSize() const override { return Size; }
void writeTo(uint8_t *Buf) const override {
- memset(Buf + OutputSectionOff, 0, Size);
+ memset(Buf, 0, Size);
}
private:
@@ -169,9 +169,9 @@
}
void writeTo(uint8_t *Buf) const override {
- memset(Buf + OutputSectionOff, 0, getSize());
+ memset(Buf, 0, getSize());
- auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);
+ auto *E = (delay_import_directory_table_entry *)(Buf);
E->Attributes = 1;
E->Name = DLLName->getRVA();
E->ModuleHandle = ModuleHandle->getRVA();
@@ -280,10 +280,10 @@
size_t getSize() const override { return sizeof(ThunkX64); }
void writeTo(uint8_t *Buf) const override {
- memcpy(Buf + OutputSectionOff, ThunkX64, sizeof(ThunkX64));
- write32le(Buf + OutputSectionOff + 36, Imp->getRVA() - RVA - 40);
- write32le(Buf + OutputSectionOff + 43, Desc->getRVA() - RVA - 47);
- write32le(Buf + OutputSectionOff + 48, Helper->getRVA() - RVA - 52);
+ memcpy(Buf, ThunkX64, sizeof(ThunkX64));
+ write32le(Buf + 36, Imp->getRVA() - RVA - 40);
+ write32le(Buf + 43, Desc->getRVA() - RVA - 47);
+ write32le(Buf + 48, Helper->getRVA() - RVA - 52);
}
Defined *Imp = nullptr;
@@ -299,10 +299,10 @@
size_t getSize() const override { return sizeof(ThunkX86); }
void writeTo(uint8_t *Buf) const override {
- memcpy(Buf + OutputSectionOff, ThunkX86, sizeof(ThunkX86));
- write32le(Buf + OutputSectionOff + 3, Imp->getRVA() + Config->ImageBase);
- write32le(Buf + OutputSectionOff + 8, Desc->getRVA() + Config->ImageBase);
- write32le(Buf + OutputSectionOff + 13, Helper->getRVA() - RVA - 17);
+ memcpy(Buf, ThunkX86, sizeof(ThunkX86));
+ write32le(Buf + 3, Imp->getRVA() + Config->ImageBase);
+ write32le(Buf + 8, Desc->getRVA() + Config->ImageBase);
+ write32le(Buf + 13, Helper->getRVA() - RVA - 17);
}
void getBaserels(std::vector<Baserel> *Res) override {
@@ -323,10 +323,10 @@
size_t getSize() const override { return sizeof(ThunkARM); }
void writeTo(uint8_t *Buf) const override {
- memcpy(Buf + OutputSectionOff, ThunkARM, sizeof(ThunkARM));
- applyMOV32T(Buf + OutputSectionOff + 0, Imp->getRVA() + Config->ImageBase);
- applyMOV32T(Buf + OutputSectionOff + 22, Desc->getRVA() + Config->ImageBase);
- applyBranch24T(Buf + OutputSectionOff + 30, Helper->getRVA() - RVA - 34);
+ memcpy(Buf, ThunkARM, sizeof(ThunkARM));
+ applyMOV32T(Buf + 0, Imp->getRVA() + Config->ImageBase);
+ applyMOV32T(Buf + 22, Desc->getRVA() + Config->ImageBase);
+ applyBranch24T(Buf + 30, Helper->getRVA() - RVA - 34);
}
void getBaserels(std::vector<Baserel> *Res) override {
@@ -347,13 +347,12 @@
size_t getSize() const override { return sizeof(ThunkARM64); }
void writeTo(uint8_t *Buf) const override {
- memcpy(Buf + OutputSectionOff, ThunkARM64, sizeof(ThunkARM64));
- applyArm64Addr(Buf + OutputSectionOff + 0, Imp->getRVA(), RVA + 0, 12);
- applyArm64Imm(Buf + OutputSectionOff + 4, Imp->getRVA() & 0xfff, 0);
- applyArm64Addr(Buf + OutputSectionOff + 52, Desc->getRVA(), RVA + 52, 12);
- applyArm64Imm(Buf + OutputSectionOff + 56, Desc->getRVA() & 0xfff, 0);
- applyArm64Branch26(Buf + OutputSectionOff + 60,
- Helper->getRVA() - RVA - 60);
+ memcpy(Buf, ThunkARM64, sizeof(ThunkARM64));
+ applyArm64Addr(Buf + 0, Imp->getRVA(), RVA + 0, 12);
+ applyArm64Imm(Buf + 4, Imp->getRVA() & 0xfff, 0);
+ applyArm64Addr(Buf + 52, Desc->getRVA(), RVA + 52, 12);
+ applyArm64Imm(Buf + 56, Desc->getRVA() & 0xfff, 0);
+ applyArm64Branch26(Buf + 60, Helper->getRVA() - RVA - 60);
}
Defined *Imp = nullptr;
@@ -371,13 +370,13 @@
void writeTo(uint8_t *Buf) const override {
if (Config->is64()) {
- write64le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase);
+ write64le(Buf, Thunk->getRVA() + Config->ImageBase);
} else {
uint32_t Bit = 0;
// Pointer to thumb code must have the LSB set, so adjust it.
if (Config->Machine == ARMNT)
Bit = 1;
- write32le(Buf + OutputSectionOff, (Thunk->getRVA() + Config->ImageBase) | Bit);
+ write32le(Buf, (Thunk->getRVA() + Config->ImageBase) | Bit);
}
}
@@ -403,9 +402,9 @@
}
void writeTo(uint8_t *Buf) const override {
- memset(Buf + OutputSectionOff, 0, getSize());
+ memset(Buf, 0, getSize());
- auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);
+ auto *E = (export_directory_table_entry *)(Buf);
E->NameRVA = DLLName->getRVA();
E->OrdinalBase = 0;
E->AddressTableEntries = MaxOrdinal + 1;
@@ -429,10 +428,10 @@
size_t getSize() const override { return Size * 4; }
void writeTo(uint8_t *Buf) const override {
- memset(Buf + OutputSectionOff, 0, getSize());
+ memset(Buf, 0, getSize());
for (const Export &E : Config->Exports) {
- uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
+ uint8_t *P = Buf + E.Ordinal * 4;
uint32_t Bit = 0;
// Pointer to thumb code must have the LSB set, so adjust it.
if (Config->Machine == ARMNT && !E.Data)
@@ -455,10 +454,9 @@
size_t getSize() const override { return Chunks.size() * 4; }
void writeTo(uint8_t *Buf) const override {
- uint8_t *P = Buf + OutputSectionOff;
for (Chunk *C : Chunks) {
- write32le(P, C->getRVA());
- P += 4;
+ write32le(Buf, C->getRVA());
+ Buf += 4;
}
}
@@ -472,12 +470,11 @@
size_t getSize() const override { return Size * 2; }
void writeTo(uint8_t *Buf) const override {
- uint8_t *P = Buf + OutputSectionOff;
for (Export &E : Config->Exports) {
if (E.Noname)
continue;
- write16le(P, E.Ordinal);
- P += 2;
+ write16le(Buf, E.Ordinal);
+ Buf += 2;
}
}
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index a192724..f237485 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1030,7 +1030,7 @@
static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
SectionChunk &DebugChunk) {
uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk.getSize());
- assert(DebugChunk.OutputSectionOff == 0 &&
+ assert(DebugChunk.getOutputSection() == nullptr &&
"debug sections should not be in output sections");
DebugChunk.writeTo(Buffer);
return makeArrayRef(Buffer, DebugChunk.getSize());
@@ -1557,6 +1557,8 @@
}
DefinedImportThunk *Thunk = cast<DefinedImportThunk>(File->ThunkSym);
+ Chunk *ThunkChunk = Thunk->getChunk();
+ OutputSection *ThunkOS = ThunkChunk->getOutputSection();
ObjNameSym ONS(SymbolRecordKind::ObjNameSym);
Compile3Sym CS(SymbolRecordKind::Compile3Sym);
@@ -1573,9 +1575,9 @@
TS.End = 0;
TS.Next = 0;
TS.Thunk = ThunkOrdinal::Standard;
- TS.Length = Thunk->getChunk()->getSize();
- TS.Segment = Thunk->getChunk()->getOutputSection()->SectionIndex;
- TS.Offset = Thunk->getChunk()->OutputSectionOff;
+ TS.Length = ThunkChunk->getSize();
+ TS.Segment = ThunkOS->SectionIndex;
+ TS.Offset = ThunkChunk->getRVA() - ThunkOS->getRVA();
Mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol(
ONS, Alloc, CodeViewContainer::Pdb));
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 5918e75..46e8ee6 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -91,7 +91,7 @@
}
void writeTo(uint8_t *B) const override {
- auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);
+ auto *D = reinterpret_cast<debug_directory *>(B);
for (const Chunk *Record : Records) {
OutputSection *OS = Record->getOutputSection();
@@ -145,10 +145,10 @@
void writeTo(uint8_t *B) const override {
// Save off the DebugInfo entry to backfill the file signature (build id)
// in Writer::writeBuildId
- BuildId = reinterpret_cast<codeview::DebugInfo *>(B + OutputSectionOff);
+ BuildId = reinterpret_cast<codeview::DebugInfo *>(B);
// variable sized field (PDB Path)
- char *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*BuildId));
+ char *P = reinterpret_cast<char *>(B + sizeof(*BuildId));
if (!Config->PDBAltPath.empty())
memcpy(P, Config->PDBAltPath.data(), Config->PDBAltPath.size());
P[Config->PDBAltPath.size()] = '\0';
@@ -1161,7 +1161,6 @@
VirtualSize += Padding;
VirtualSize = alignTo(VirtualSize, C->Alignment);
C->setRVA(RVA + VirtualSize);
- C->OutputSectionOff = VirtualSize;
C->finalizeContents();
VirtualSize += C->getSize();
if (C->hasData())
@@ -1675,7 +1674,9 @@
// ADD instructions).
if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE)
memset(SecBuf, 0xCC, Sec->getRawSize());
- parallelForEach(Sec->Chunks, [&](Chunk *C) { C->writeTo(SecBuf); });
+ parallelForEach(Sec->Chunks, [&](Chunk *C) {
+ C->writeTo(SecBuf + C->getRVA() - Sec->getRVA());
+ });
}
}