[ELF] - Implemented R_386_16 and R_386PC16 relocations

A program or object file using R_386_8, R_386_16, R_386_PC16 or R_386_PC8
relocations is not conformant to latest ABI. The R_386_16, and R_386_8
relocations truncate the computed value to 16 - bits and 8 - bits
respectively. R_386_PC16 and R_386_16 are used by some
applications, for example by FreeBSD loaders.

Previously we did not take addend in account for these relocation,
counting it as 0, what is wrong and was a reason of hangs.

This patch needed for example for FreeBSD pmbr (protective mbr).

Differential revision: https://reviews.llvm.org/D27303

llvm-svn: 288581
This commit is contained in:
George Rimar 2016-12-03 07:30:30 +00:00
parent 40c28c7f9a
commit 1b3d34a298
2 changed files with 50 additions and 0 deletions

View File

@ -329,6 +329,7 @@ RelExpr X86TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
return R_TLSLD; return R_TLSLD;
case R_386_PLT32: case R_386_PLT32:
return R_PLT_PC; return R_PLT_PC;
case R_386_PC16:
case R_386_PC32: case R_386_PC32:
return R_PC; return R_PC;
case R_386_GOTPC: case R_386_GOTPC:
@ -437,11 +438,13 @@ uint64_t X86TargetInfo::getImplicitAddend(const uint8_t *Buf,
switch (Type) { switch (Type) {
default: default:
return 0; return 0;
case R_386_16:
case R_386_32: case R_386_32:
case R_386_GOT32: case R_386_GOT32:
case R_386_GOT32X: case R_386_GOT32X:
case R_386_GOTOFF: case R_386_GOTOFF:
case R_386_GOTPC: case R_386_GOTPC:
case R_386_PC16:
case R_386_PC32: case R_386_PC32:
case R_386_PLT32: case R_386_PLT32:
case R_386_TLS_LE: case R_386_TLS_LE:
@ -452,6 +455,13 @@ uint64_t X86TargetInfo::getImplicitAddend(const uint8_t *Buf,
void X86TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type, void X86TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
uint64_t Val) const { uint64_t Val) const {
checkInt<32>(Loc, Val, Type); checkInt<32>(Loc, Val, Type);
// R_386_PC16 and R_386_16 are not part of the current i386 psABI. They are
// used by 16-bit x86 objects, like boot loaders.
if (Type == R_386_16 || Type == R_386_PC16) {
write16le(Loc, Val);
return;
}
write32le(Loc, Val); write32le(Loc, Val);
} }

View File

@ -0,0 +1,40 @@
# REQUIRES: x86
# RUN: yaml2obj %s -o %t.o
# RUN: ld.lld %t.o -o %t.exe
# RUN: llvm-objdump -s -section=.text %t.exe 2>&1 | FileCheck %s
# CHECK: Contents of section .text:
# CHECK-NEXT: 11000 56441111 52341111
!ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_386
Sections:
- Type: SHT_PROGBITS
Name: .text
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x04
Content: "1111111111111111"
- Type: SHT_REL
Name: .rel.text
Link: .symtab
Info: .text
AddressAlign: 0x04
Relocations:
- Offset: 0
Symbol: _start
Type: R_386_16
- Offset: 4
Symbol: _start
Type: R_386_PC16
Symbols:
Global:
- Name: _start
Type: STT_FUNC
Section: .text
Value: 0x12345
Size: 4