[lld] r200185 - [PECOFF] Implement relocations for x86-64.
Shankar Easwaran
shankare at codeaurora.org
Sun Jan 26 20:06:12 PST 2014
Rui,
You might want to subclass the writer for 32bit and 64bit.
On ELF, we consider X86/X86_64 as two separate targets.
Thoughts ?
Thanks
Shankar Easwaran
On 1/26/2014 9:53 PM, Rui Ueyama wrote:
> Author: ruiu
> Date: Sun Jan 26 21:53:30 2014
> New Revision: 200185
>
> URL: http://llvm.org/viewvc/llvm-project?rev=200185&view=rev
> Log:
> [PECOFF] Implement relocations for x86-64.
>
> Added:
> lld/trunk/test/pecoff/Inputs/reloc64-1.asm
> lld/trunk/test/pecoff/Inputs/reloc64-1.obj
> lld/trunk/test/pecoff/Inputs/reloc64-2.asm
> lld/trunk/test/pecoff/Inputs/reloc64-2.obj
> lld/trunk/test/pecoff/reloc64.test
> Modified:
> lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
>
> Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=200185&r1=200184&r2=200185&view=diff
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Sun Jan 26 21:53:30 2014
> @@ -22,6 +22,7 @@
> #define DEBUG_TYPE "WriterPECOFF"
>
> #include <algorithm>
> +#include <cstdlib>
> #include <map>
> #include <time.h>
> #include <vector>
> @@ -209,10 +210,16 @@ public:
>
> void appendAtom(const DefinedAtom *atom);
> void buildAtomRvaMap(std::map<const Atom *, uint64_t> &atomRva) const;
> - void applyRelocations(uint8_t *buffer,
> - std::map<const Atom *, uint64_t> &atomRva,
> - std::vector<uint64_t> §ionRva,
> - uint64_t imageBaseAddress);
> +
> + void applyRelocations32(uint8_t *buffer,
> + std::map<const Atom *, uint64_t> &atomRva,
> + std::vector<uint64_t> §ionRva,
> + uint64_t imageBaseAddress);
> + void applyRelocations64(uint8_t *buffer,
> + std::map<const Atom *, uint64_t> &atomRva,
> + std::vector<uint64_t> §ionRva,
> + uint64_t imageBaseAddress);
> +
> void printAtomAddresses(uint64_t baseAddr) const;
> void addBaseRelocations(std::vector<uint64_t> &relocSites) const;
>
> @@ -460,10 +467,10 @@ AtomChunk::buildAtomRvaMap(std::map<cons
> atomRva[layout->_atom] = layout->_virtualAddr;
> }
>
> -void AtomChunk::applyRelocations(uint8_t *buffer,
> - std::map<const Atom *, uint64_t> &atomRva,
> - std::vector<uint64_t> §ionRva,
> - uint64_t imageBaseAddress) {
> +void AtomChunk::applyRelocations32(uint8_t *buffer,
> + std::map<const Atom *, uint64_t> &atomRva,
> + std::vector<uint64_t> §ionRva,
> + uint64_t imageBaseAddress) {
> buffer += _fileOffset;
> for (const auto *layout : _atomLayouts) {
> const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
> @@ -527,6 +534,49 @@ void AtomChunk::applyRelocations(uint8_t
> }
> }
>
> +void AtomChunk::applyRelocations64(uint8_t *buffer,
> + std::map<const Atom *, uint64_t> &atomRva,
> + std::vector<uint64_t> §ionRva,
> + uint64_t imageBase) {
> + buffer += _fileOffset;
> + for (const auto *layout : _atomLayouts) {
> + const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
> + for (const Reference *ref : *atom) {
> + if (ref->kindNamespace() != Reference::KindNamespace::COFF)
> + continue;
> +
> + auto relocSite32 = reinterpret_cast<ulittle32_t *>(
> + buffer + layout->_fileOffset + ref->offsetInAtom());
> + uint64_t targetAddr = atomRva[ref->target()];
> +
> + switch (ref->kindValue()) {
> + case llvm::COFF::IMAGE_REL_AMD64_ADDR32NB:
> + *relocSite32 = targetAddr - imageBase;
> + break;
> + case llvm::COFF::IMAGE_REL_AMD64_REL32:
> + *relocSite32 = targetAddr - atomRva[atom] + ref->offsetInAtom() + 4;
> + break;
> +
> +#define REL32(x) \
> + case llvm::COFF::IMAGE_REL_AMD64_REL32_ ## x: { \
> + uint32_t off = targetAddr - atomRva[atom] + ref->offsetInAtom() + 4; \
> + *relocSite32 = off + x; \
> + }
> + REL32(1);
> + REL32(2);
> + REL32(3);
> + REL32(4);
> + REL32(5);
> +#undef CASE
> +
> + default:
> + llvm::errs() << "Kind: " << (int)ref->kindValue() << "\n";
> + llvm_unreachable("Unsupported relocation kind");
> + }
> + }
> + }
> +}
> +
> /// Print atom VAs. Used only for debugging.
> void AtomChunk::printAtomAddresses(uint64_t baseAddr) const {
> for (const auto *layout : _atomLayouts) {
> @@ -965,10 +1015,16 @@ void PECOFFWriter::applyAllRelocations(u
> chunk->buildAtomRvaMap(atomRva);
>
> // Pass 2
> - for (auto &cp : _chunks)
> - if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp))
> - chunk->applyRelocations(bufferStart, atomRva, sectionRva,
> - _ctx.getBaseAddress());
> + uint64_t base = _ctx.getBaseAddress();
> + for (auto &cp : _chunks) {
> + if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp)) {
> + if (_ctx.is64Bit()) {
> + chunk->applyRelocations64(bufferStart, atomRva, sectionRva, base);
> + } else {
> + chunk->applyRelocations32(bufferStart, atomRva, sectionRva, base);
> + }
> + }
> + }
> }
>
> /// Print atom VAs. Used only for debugging.
>
> Added: lld/trunk/test/pecoff/Inputs/reloc64-1.asm
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc64-1.asm?rev=200185&view=auto
> ==============================================================================
> --- lld/trunk/test/pecoff/Inputs/reloc64-1.asm (added)
> +++ lld/trunk/test/pecoff/Inputs/reloc64-1.asm Sun Jan 26 21:53:30 2014
> @@ -0,0 +1,8 @@
> +extern fn2 : PROC
> +
> +.code
> +fn1 PROC
> + call fn2
> + ret
> +fn1 ENDP
> +End
>
> Added: lld/trunk/test/pecoff/Inputs/reloc64-1.obj
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc64-1.obj?rev=200185&view=auto
> ==============================================================================
> Binary files lld/trunk/test/pecoff/Inputs/reloc64-1.obj (added) and lld/trunk/test/pecoff/Inputs/reloc64-1.obj Sun Jan 26 21:53:30 2014 differ
>
> Added: lld/trunk/test/pecoff/Inputs/reloc64-2.asm
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc64-2.asm?rev=200185&view=auto
> ==============================================================================
> --- lld/trunk/test/pecoff/Inputs/reloc64-2.asm (added)
> +++ lld/trunk/test/pecoff/Inputs/reloc64-2.asm Sun Jan 26 21:53:30 2014
> @@ -0,0 +1,5 @@
> +.code
> +fn2 PROC
> + ret
> +fn2 ENDP
> +End
>
> Added: lld/trunk/test/pecoff/Inputs/reloc64-2.obj
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc64-2.obj?rev=200185&view=auto
> ==============================================================================
> Binary files lld/trunk/test/pecoff/Inputs/reloc64-2.obj (added) and lld/trunk/test/pecoff/Inputs/reloc64-2.obj Sun Jan 26 21:53:30 2014 differ
>
> Added: lld/trunk/test/pecoff/reloc64.test
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/reloc64.test?rev=200185&view=auto
> ==============================================================================
> --- lld/trunk/test/pecoff/reloc64.test (added)
> +++ lld/trunk/test/pecoff/reloc64.test Sun Jan 26 21:53:30 2014
> @@ -0,0 +1,7 @@
> +# RUN: lld -flavor link /out:%t.exe /subsystem:console /machine:x64 \
> +# RUN: /entry:fn1 -- %p/Inputs/reloc64-1.obj %p/Inputs/reloc64-2.obj
> +# RUN: llvm-objdump -d %t.exe | FileCheck %s
> +
> +CHECK: Disassembly of section .text:
> +CHECK-NEXT: .text:
> +CHECK-NEXT: 2000: e8 15 00 00 00 callq 21
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation
More information about the llvm-commits
mailing list