diff options
-rw-r--r-- | lld/COFF/Chunks.cpp | 35 | ||||
-rw-r--r-- | lld/COFF/Chunks.h | 1 |
2 files changed, 21 insertions, 15 deletions
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index daf2ff681b5..128d09c83fe 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -48,6 +48,25 @@ 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::applyRelX64(uint8_t *Off, uint16_t Type, uint64_t S, + uint64_t P) { + switch (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::writeTo(uint8_t *Buf) { if (!hasData()) return; @@ -61,21 +80,7 @@ void SectionChunk::writeTo(uint8_t *Buf) { SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex)->repl(); 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"); - } + applyRelX64(Off, Rel.Type, S, P); } } diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h index 074a87ae35f..50fba3c3a4f 100644 --- a/lld/COFF/Chunks.h +++ b/lld/COFF/Chunks.h @@ -136,6 +136,7 @@ public: StringRef getSectionName() const override { return SectionName; } void getBaserels(std::vector<uint32_t> *Res, Defined *ImageBase) override; bool isCOMDAT() const; + void applyRelX64(uint8_t *Off, uint16_t Type, uint64_t S, uint64_t P); // Called if the garbage collector decides to not include this chunk // in a final output. It's supposed to print out a log message to stdout. |