[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> &sectionRva,
> -                        uint64_t imageBaseAddress);
> +
> +  void applyRelocations32(uint8_t *buffer,
> +                          std::map<const Atom *, uint64_t> &atomRva,
> +                          std::vector<uint64_t> &sectionRva,
> +                          uint64_t imageBaseAddress);
> +  void applyRelocations64(uint8_t *buffer,
> +                          std::map<const Atom *, uint64_t> &atomRva,
> +                          std::vector<uint64_t> &sectionRva,
> +                          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> &sectionRva,
> -                                 uint64_t imageBaseAddress) {
> +void AtomChunk::applyRelocations32(uint8_t *buffer,
> +                                   std::map<const Atom *, uint64_t> &atomRva,
> +                                   std::vector<uint64_t> &sectionRva,
> +                                   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> &sectionRva,
> +                                   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