[lld] r200185 - [PECOFF] Implement relocations for x86-64.

Rui Ueyama ruiu at google.com
Sun Jan 26 20:15:37 PST 2014


On Sun, Jan 26, 2014 at 8:06 PM, Shankar Easwaran
<shankare at codeaurora.org>wrote:

> Rui,
>
> You might want to subclass the writer for 32bit and 64bit.
>
> On ELF, we consider X86/X86_64 as two separate targets.
>

I intentionally did not separate them because they are so similar that such
abstraction wouldn't worth it. PE32+ is not actually 64 bit file format,
but it's a 32 bit file format that allows one to use just 64 bit address
space. One cannot create an executable larger than 2GB with PE32+, for
example. Unlike ELF, most data structures in the PE32+ file remains the
same as PE32.

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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140126/52232656/attachment.html>


More information about the llvm-commits mailing list