forked from OSchip/llvm-project
COFF: Use COFFObjectFile::getRelocations(). NFC.
llvm-svn: 240614
This commit is contained in:
parent
e9247ab6d6
commit
42aa00b34b
|
@ -28,7 +28,8 @@ namespace lld {
|
|||
namespace coff {
|
||||
|
||||
SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H)
|
||||
: File(F), Ptr(this), Header(H) {
|
||||
: File(F), Ptr(this), Header(H),
|
||||
Relocs(File->getCOFFObj()->getRelocations(Header)) {
|
||||
// Initialize SectionName.
|
||||
File->getCOFFObj()->getSectionName(Header, SectionName);
|
||||
|
||||
|
@ -49,6 +50,10 @@ SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H)
|
|||
Root = true;
|
||||
}
|
||||
|
||||
static void add16(uint8_t *P, int16_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); }
|
||||
|
||||
void SectionChunk::writeTo(uint8_t *Buf) {
|
||||
if (!hasData())
|
||||
return;
|
||||
|
@ -58,8 +63,27 @@ void SectionChunk::writeTo(uint8_t *Buf) {
|
|||
memcpy(Buf + FileOff, Data.data(), Data.size());
|
||||
|
||||
// Apply relocations.
|
||||
for (const coff_relocation *Rel = relBegin(), *E = relEnd(); Rel != E; ++Rel)
|
||||
applyReloc(Buf, Rel);
|
||||
for (const coff_relocation &Rel : Relocs) {
|
||||
uint8_t *Off = Buf + FileOff + Rel.VirtualAddress;
|
||||
SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
|
||||
uint64_t S = cast<Defined>(Body)->getRVA();
|
||||
uint64_t P = RVA + Rel.VirtualAddress;
|
||||
switch (Rel.Type) {
|
||||
case IMAGE_REL_AMD64_ADDR32: add32(Off, S + Config->ImageBase); break;
|
||||
case IMAGE_REL_AMD64_ADDR64: add64(Off, S + Config->ImageBase); break;
|
||||
case IMAGE_REL_AMD64_ADDR32NB: add32(Off, S); break;
|
||||
case IMAGE_REL_AMD64_REL32: add32(Off, S - P - 4); break;
|
||||
case IMAGE_REL_AMD64_REL32_1: add32(Off, S - P - 5); break;
|
||||
case IMAGE_REL_AMD64_REL32_2: add32(Off, S - P - 6); break;
|
||||
case IMAGE_REL_AMD64_REL32_3: add32(Off, S - P - 7); break;
|
||||
case IMAGE_REL_AMD64_REL32_4: add32(Off, S - P - 8); break;
|
||||
case IMAGE_REL_AMD64_REL32_5: add32(Off, S - P - 9); break;
|
||||
case IMAGE_REL_AMD64_SECTION: add16(Off, Out->getSectionIndex()); break;
|
||||
case IMAGE_REL_AMD64_SECREL: add32(Off, S - Out->getRVA()); break;
|
||||
default:
|
||||
llvm::report_fatal_error("Unsupported relocation type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SectionChunk::mark() {
|
||||
|
@ -67,9 +91,8 @@ void SectionChunk::mark() {
|
|||
Live = true;
|
||||
|
||||
// Mark all symbols listed in the relocation table for this section.
|
||||
for (const coff_relocation *Rel = relBegin(), *E = relEnd(); Rel != E;
|
||||
++Rel) {
|
||||
SymbolBody *B = File->getSymbolBody(Rel->SymbolTableIndex);
|
||||
for (const coff_relocation &Rel : Relocs) {
|
||||
SymbolBody *B = File->getSymbolBody(Rel.SymbolTableIndex);
|
||||
if (auto *Def = dyn_cast<Defined>(B))
|
||||
Def->markLive();
|
||||
}
|
||||
|
@ -86,49 +109,21 @@ void SectionChunk::addAssociative(SectionChunk *Child) {
|
|||
Child->Root = false;
|
||||
}
|
||||
|
||||
static void add16(uint8_t *P, int16_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); }
|
||||
|
||||
// Implements x64 PE/COFF relocations.
|
||||
void SectionChunk::applyReloc(uint8_t *Buf, const coff_relocation *Rel) {
|
||||
uint8_t *Off = Buf + FileOff + Rel->VirtualAddress;
|
||||
SymbolBody *Body = File->getSymbolBody(Rel->SymbolTableIndex);
|
||||
uint64_t S = cast<Defined>(Body)->getRVA();
|
||||
uint64_t P = RVA + Rel->VirtualAddress;
|
||||
switch (Rel->Type) {
|
||||
case IMAGE_REL_AMD64_ADDR32: add32(Off, S + Config->ImageBase); break;
|
||||
case IMAGE_REL_AMD64_ADDR64: add64(Off, S + Config->ImageBase); break;
|
||||
case IMAGE_REL_AMD64_ADDR32NB: add32(Off, S); break;
|
||||
case IMAGE_REL_AMD64_REL32: add32(Off, S - P - 4); break;
|
||||
case IMAGE_REL_AMD64_REL32_1: add32(Off, S - P - 5); break;
|
||||
case IMAGE_REL_AMD64_REL32_2: add32(Off, S - P - 6); break;
|
||||
case IMAGE_REL_AMD64_REL32_3: add32(Off, S - P - 7); break;
|
||||
case IMAGE_REL_AMD64_REL32_4: add32(Off, S - P - 8); break;
|
||||
case IMAGE_REL_AMD64_REL32_5: add32(Off, S - P - 9); break;
|
||||
case IMAGE_REL_AMD64_SECTION: add16(Off, Out->getSectionIndex()); break;
|
||||
case IMAGE_REL_AMD64_SECREL: add32(Off, S - Out->getRVA()); break;
|
||||
default:
|
||||
llvm::report_fatal_error("Unsupported relocation type");
|
||||
}
|
||||
}
|
||||
|
||||
// Windows-specific.
|
||||
// Collect all locations that contain absolute 64-bit addresses,
|
||||
// which need to be fixed by the loader if load-time relocation is needed.
|
||||
// Only called when base relocation is enabled.
|
||||
void SectionChunk::getBaserels(std::vector<uint32_t> *Res, Defined *ImageBase) {
|
||||
for (const coff_relocation *Rel = relBegin(), *E = relEnd(); Rel != E;
|
||||
++Rel) {
|
||||
for (const coff_relocation &Rel : Relocs) {
|
||||
// ADDR64 relocations contain absolute addresses.
|
||||
// Symbol __ImageBase is special -- it's an absolute symbol, but its
|
||||
// address never changes even if image is relocated.
|
||||
if (Rel->Type != IMAGE_REL_AMD64_ADDR64)
|
||||
if (Rel.Type != IMAGE_REL_AMD64_ADDR64)
|
||||
continue;
|
||||
SymbolBody *Body = File->getSymbolBody(Rel->SymbolTableIndex);
|
||||
SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
|
||||
if (Body == ImageBase)
|
||||
continue;
|
||||
Res->push_back(RVA + Rel->VirtualAddress);
|
||||
Res->push_back(RVA + Rel.VirtualAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,9 +183,9 @@ bool SectionChunk::equals(const SectionChunk *X) const {
|
|||
return false;
|
||||
|
||||
// Compare relocations
|
||||
const coff_relocation *Rel1 = relBegin();
|
||||
const coff_relocation *End = relEnd();
|
||||
const coff_relocation *Rel2 = X->relBegin();
|
||||
const coff_relocation *Rel1 = Relocs.begin();
|
||||
const coff_relocation *End = Relocs.end();
|
||||
const coff_relocation *Rel2 = X->Relocs.begin();
|
||||
for (; Rel1 != End; ++Rel1, ++Rel2) {
|
||||
if (Rel1->Type != Rel2->Type)
|
||||
return false;
|
||||
|
@ -220,22 +215,6 @@ void SectionChunk::replaceWith(SectionChunk *Other) {
|
|||
Live = false;
|
||||
}
|
||||
|
||||
const coff_relocation *SectionChunk::relBegin() const {
|
||||
if (!Reloc) {
|
||||
DataRefImpl Ref;
|
||||
Ref.p = uintptr_t(Header);
|
||||
SectionRef Sref(Ref, File->getCOFFObj());
|
||||
relocation_iterator It = Sref.relocation_begin();
|
||||
Reloc = File->getCOFFObj()->getCOFFRelocation(*It);
|
||||
}
|
||||
return Reloc;
|
||||
}
|
||||
|
||||
const coff_relocation *SectionChunk::relEnd() const {
|
||||
const coff_relocation *I = relBegin();
|
||||
return I + Header->NumberOfRelocations;
|
||||
}
|
||||
|
||||
CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
|
||||
// Common symbols are aligned on natural boundaries up to 32 bytes.
|
||||
// This is what MSVC link.exe does.
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "lld/Core/LLVM.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Object/COFF.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
@ -149,16 +150,10 @@ public:
|
|||
|
||||
private:
|
||||
void mark() override;
|
||||
void applyReloc(uint8_t *Buf, const coff_relocation *Rel);
|
||||
|
||||
// A file this chunk was created from.
|
||||
ObjectFile *File;
|
||||
|
||||
// A raw pointer to the relocation table.
|
||||
mutable const coff_relocation *Reloc = nullptr;
|
||||
const coff_relocation *relBegin() const;
|
||||
const coff_relocation *relEnd() const;
|
||||
|
||||
// A pointer pointing to a replacement for this chunk.
|
||||
// Initially it points to "this" object. If this chunk is merged
|
||||
// with other chunk by ICF, it points to another chunk,
|
||||
|
@ -168,6 +163,7 @@ private:
|
|||
const coff_section *Header;
|
||||
StringRef SectionName;
|
||||
std::vector<Chunk *> AssocChildren;
|
||||
llvm::iterator_range<const coff_relocation *> Relocs;
|
||||
|
||||
// Chunks are basically unnamed chunks of bytes.
|
||||
// Symbols are associated for debugging and logging purposs only.
|
||||
|
|
Loading…
Reference in New Issue