[lld] r288581 - [ELF] - Implemented R_386_16 and R_386PC16 relocations

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 2 23:30:30 PST 2016


Author: grimar
Date: Sat Dec  3 01:30:30 2016
New Revision: 288581

URL: http://llvm.org/viewvc/llvm-project?rev=288581&view=rev
Log:
[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

Added:
    lld/trunk/test/ELF/i386-pc16.test
Modified:
    lld/trunk/ELF/Target.cpp

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=288581&r1=288580&r2=288581&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Sat Dec  3 01:30:30 2016
@@ -329,6 +329,7 @@ RelExpr X86TargetInfo::getRelExpr(uint32
     return R_TLSLD;
   case R_386_PLT32:
     return R_PLT_PC;
+  case R_386_PC16:
   case R_386_PC32:
     return R_PC;
   case R_386_GOTPC:
@@ -437,11 +438,13 @@ uint64_t X86TargetInfo::getImplicitAdden
   switch (Type) {
   default:
     return 0;
+  case R_386_16:
   case R_386_32:
   case R_386_GOT32:
   case R_386_GOT32X:
   case R_386_GOTOFF:
   case R_386_GOTPC:
+  case R_386_PC16:
   case R_386_PC32:
   case R_386_PLT32:
   case R_386_TLS_LE:
@@ -452,6 +455,13 @@ uint64_t X86TargetInfo::getImplicitAdden
 void X86TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
                                 uint64_t Val) const {
   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);
 }
 

Added: lld/trunk/test/ELF/i386-pc16.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/i386-pc16.test?rev=288581&view=auto
==============================================================================
--- lld/trunk/test/ELF/i386-pc16.test (added)
+++ lld/trunk/test/ELF/i386-pc16.test Sat Dec  3 01:30:30 2016
@@ -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




More information about the llvm-commits mailing list