From 45b392d6cf0e9a7d7401161500d1bce0f05144ae Mon Sep 17 00:00:00 2001 From: Shankar Easwaran Date: Sun, 22 Feb 2015 23:32:34 +0000 Subject: [PATCH] [ELF][X86_64] R_X86_64_16 relocation support llvm-svn: 230189 --- .../ELF/X86_64/X86_64RelocationHandler.cpp | 12 +++++ .../ELF/X86_64/X86_64RelocationPass.cpp | 1 + lld/test/elf/X86_64/reloc_r_x86_64_16.test | 60 ++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 lld/test/elf/X86_64/reloc_r_x86_64_16.test diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp index 91194c9..e436422 100644 --- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp @@ -47,6 +47,15 @@ static void reloc32S(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { // TODO: Make sure that the result sign extends to the 64bit value. } +/// \brief R_X86_64_16 - word16: S + A +static void reloc16(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { + uint16_t result = (uint16_t)(S + A); + *reinterpret_cast(location) = + result | + (uint16_t) * reinterpret_cast(location); + // TODO: Check for overflow. +} + std::error_code X86_64TargetRelocationHandler::applyRelocation( ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom, const Reference &ref) const { @@ -74,6 +83,9 @@ std::error_code X86_64TargetRelocationHandler::applyRelocation( case R_X86_64_32S: reloc32S(location, relocVAddress, targetVAddress, ref.addend()); break; + case R_X86_64_16: + reloc16(location, relocVAddress, targetVAddress, ref.addend()); + break; case R_X86_64_TPOFF64: case R_X86_64_DTPOFF32: case R_X86_64_TPOFF32: { diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp b/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp index 45bdcad..bf5dbde 100644 --- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp @@ -111,6 +111,7 @@ template class RelocationPass : public Pass { return; assert(ref.kindArch() == Reference::KindArch::x86_64); switch (ref.kindValue()) { + case R_X86_64_16: case R_X86_64_32: case R_X86_64_32S: case R_X86_64_64: diff --git a/lld/test/elf/X86_64/reloc_r_x86_64_16.test b/lld/test/elf/X86_64/reloc_r_x86_64_16.test new file mode 100644 index 0000000..7cca839 --- /dev/null +++ b/lld/test/elf/X86_64/reloc_r_x86_64_16.test @@ -0,0 +1,60 @@ +# Tests that lld can handle relocations of type R_X86_64_16 +#RUN: yaml2obj -format=elf -docnum 1 %s -o %t1.o +#RUN: lld -flavor gnu -target x86_64 %t1.o --noinhibit-exec -o %t2.out -static +#RUN: llvm-objdump -s %t2.out | FileCheck %s +#CHECK: Contents of section .data: +#CHECK: 401000 0210 +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000008 + Content: '0000' + - Name: .rela.data + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .data + Relocations: + - Offset: 0x0000000000000000 + Symbol: foo + Type: R_X86_64_16 + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '' +Symbols: + Local: + - Name: .text + Type: STT_SECTION + Section: .text + - Name: .data + Type: STT_SECTION + Section: .data + - Name: .bss + Type: STT_SECTION + Section: .bss + Global: + - Name: bar + Type: STT_OBJECT + Section: .data + Size: 0x0000000000000008 + - Name: foo + Type: STT_OBJECT + Section: .data + Value: 0x0000000000000002 + Size: 0x0000000000000002 +... -- 2.7.4