[llvm] r335402 - [RuntimeDyld] Implement the ELF PIC large code model relocations

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 22 16:53:22 PDT 2018


Author: rnk
Date: Fri Jun 22 16:53:22 2018
New Revision: 335402

URL: http://llvm.org/viewvc/llvm-project?rev=335402&view=rev
Log:
[RuntimeDyld] Implement the ELF PIC large code model relocations

Prerequisite for https://reviews.llvm.org/D47211 which improves our ELF
large PIC codegen.

Added:
    llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF-large-pic-relocations.s
Modified:
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=335402&r1=335401&r2=335402&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Fri Jun 22 16:53:22 2018
@@ -312,6 +312,22 @@ void RuntimeDyldELF::resolveX86_64Reloca
     int64_t RealOffset = Value + Addend - FinalAddress;
     support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
         RealOffset;
+    LLVM_DEBUG(dbgs() << "Writing " << format("%p", RealOffset) << " at "
+                      << format("%p\n", FinalAddress));
+    break;
+  }
+  case ELF::R_X86_64_GOTOFF64: {
+    // Compute Value - GOTBase.
+    uint64_t GOTBase = 0;
+    for (const auto &Section : Sections) {
+      if (Section.getName() == ".got") {
+        GOTBase = Section.getLoadAddressWithOffset(0);
+        break;
+      }
+    }
+    assert(GOTBase != 0 && "missing GOT");
+    int64_t GOTOffset = Value - GOTBase + Addend;
+    support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) = GOTOffset;
     break;
   }
   }
@@ -1700,6 +1716,29 @@ RuntimeDyldELF::processRelocationRef(
         addRelocationForSymbol(RE, Value.SymbolName);
       else
         addRelocationForSection(RE, Value.SectionID);
+    } else if (RelType == ELF::R_X86_64_GOT64) {
+      // Fill in a 64-bit GOT offset.
+      uint64_t GOTOffset = allocateGOTEntries(1);
+      resolveRelocation(Sections[SectionID], Offset, GOTOffset,
+                        ELF::R_X86_64_64, 0);
+
+      // Fill in the value of the symbol we're targeting into the GOT
+      RelocationEntry RE =
+          computeGOTOffsetRE(GOTOffset, Value.Offset, ELF::R_X86_64_64);
+      if (Value.SymbolName)
+        addRelocationForSymbol(RE, Value.SymbolName);
+      else
+        addRelocationForSection(RE, Value.SectionID);
+    } else if (RelType == ELF::R_X86_64_GOTPC64) {
+      // Materialize the address of the base of the GOT relative to the PC.
+      // This doesn't create a GOT entry, but it does mean we need a GOT
+      // section.
+      (void)allocateGOTEntries(0);
+      resolveGOTOffsetRelocation(SectionID, Offset, Addend, ELF::R_X86_64_PC64);
+    } else if (RelType == ELF::R_X86_64_GOTOFF64) {
+      // GOTOFF relocations ultimately require a section difference relocation.
+      (void)allocateGOTEntries(0);
+      processSimpleRelocation(SectionID, Offset, RelType, Value);
     } else if (RelType == ELF::R_X86_64_PC32) {
       Value.Addend += support::ulittle32_t::ref(computePlaceholderAddress(SectionID, Offset));
       processSimpleRelocation(SectionID, Offset, RelType, Value);
@@ -1871,6 +1910,7 @@ bool RuntimeDyldELF::relocationNeedsGot(
   if (Arch == Triple::x86_64)
     return RelTy == ELF::R_X86_64_GOTPCREL ||
            RelTy == ELF::R_X86_64_GOTPCRELX ||
+           RelTy == ELF::R_X86_64_GOT64 ||
            RelTy == ELF::R_X86_64_REX_GOTPCRELX;
   return false;
 }
@@ -1887,6 +1927,9 @@ bool RuntimeDyldELF::relocationNeedsStub
   case ELF::R_X86_64_GOTPCREL:
   case ELF::R_X86_64_GOTPCRELX:
   case ELF::R_X86_64_REX_GOTPCRELX:
+  case ELF::R_X86_64_GOTPC64:
+  case ELF::R_X86_64_GOT64:
+  case ELF::R_X86_64_GOTOFF64:
   case ELF::R_X86_64_PC32:
   case ELF::R_X86_64_PC64:
   case ELF::R_X86_64_64:

Added: llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF-large-pic-relocations.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF-large-pic-relocations.s?rev=335402&view=auto
==============================================================================
--- llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF-large-pic-relocations.s (added)
+++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/X86/ELF-large-pic-relocations.s Fri Jun 22 16:53:22 2018
@@ -0,0 +1,104 @@
+# RUN: rm -rf %t && mkdir -p %t && cd %t
+# RUN: llvm-mc -triple=x86_64-unknown-freebsd -filetype=obj -o t.o %s
+# RUN: llvm-rtdyld -triple=x86_64-unknown-linux -verify -check=%s t.o -dummy-extern=extern_data=0x4200000000
+
+# Generated from this C source:
+#
+# static int static_data[10];
+# int global_data[10] = {1, 2};
+# extern int extern_data[10];
+#
+# int *lea_static_data() { return &static_data[0]; }
+# int *lea_global_data() { return &global_data[0]; }
+# int *lea_extern_data() { return &extern_data[0]; }
+
+        .text
+        .file   "model.c"
+        .globl  lea_static_data         # -- Begin function lea_static_data
+        .p2align        4, 0x90
+        .type   lea_static_data, at function
+lea_static_data:                        # @lea_static_data
+        .cfi_startproc
+# %bb.0:
+.Ltmp0:
+        leaq    .Ltmp0(%rip), %rcx
+# rtdyld-check: decode_operand(lea_static_got, 1) = section_addr(t.o, .got) - lea_static_data
+lea_static_got:
+        movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp0, %rax
+        addq    %rax, %rcx
+# rtdyld-check: decode_operand(lea_static_gotoff, 1) = static_data - section_addr(t.o, .got)
+lea_static_gotoff:
+        movabsq $static_data at GOTOFF, %rax
+        addq    %rcx, %rax
+        retq
+.Lfunc_end0:
+        .size   lea_static_data, .Lfunc_end0-lea_static_data
+        .cfi_endproc
+
+
+        .globl  lea_global_data         # -- Begin function lea_global_data
+        .p2align        4, 0x90
+        .type   lea_global_data, at function
+lea_global_data:                        # @lea_global_data
+        .cfi_startproc
+# %bb.0:
+.Ltmp1:
+        leaq    .Ltmp1(%rip), %rcx
+# rtdyld-check: decode_operand(lea_global_got, 1) = section_addr(t.o, .got) - lea_global_data
+lea_global_got:
+        movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp1, %rax
+        addq    %rax, %rcx
+# rtdyld-check: decode_operand(lea_global_gotoff, 1) = global_data - section_addr(t.o, .got)
+lea_global_gotoff:
+        movabsq $global_data at GOTOFF, %rax
+        addq    %rcx, %rax
+        retq
+.Lfunc_end1:
+        .size   lea_global_data, .Lfunc_end1-lea_global_data
+        .cfi_endproc
+
+
+        .globl  lea_extern_data         # -- Begin function lea_extern_data
+        .p2align        4, 0x90
+        .type   lea_extern_data, at function
+lea_extern_data:                        # @lea_extern_data
+        .cfi_startproc
+# %bb.0:
+.Ltmp2:
+        leaq    .Ltmp2(%rip), %rax
+# rtdyld-check: decode_operand(lea_extern_got, 1) = section_addr(t.o, .got) - lea_extern_data
+lea_extern_got:
+        movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp2, %rcx
+        addq    %rcx, %rax
+# extern_data is the only thing in the GOT, so it'll be slot 0.
+# rtdyld-check: decode_operand(lea_extern_gotslot, 1) = 0
+lea_extern_gotslot:
+        movabsq $extern_data at GOT, %rcx
+        movq    (%rax,%rcx), %rax
+        retq
+.Lfunc_end2:
+        .size   lea_extern_data, .Lfunc_end2-lea_extern_data
+        .cfi_endproc
+
+
+        .type   global_data, at object     # @global_data
+        .data
+        .globl  global_data
+        .p2align        4
+global_data:
+        .long   1                       # 0x1
+        .long   2                       # 0x2
+        .long   0                       # 0x0
+        .long   0                       # 0x0
+        .long   0                       # 0x0
+        .long   0                       # 0x0
+        .long   0                       # 0x0
+        .long   0                       # 0x0
+        .long   0                       # 0x0
+        .long   0                       # 0x0
+        .size   global_data, 40
+
+        .type   static_data, at object     # @static_data
+        .local  static_data
+        .comm   static_data,40,16
+




More information about the llvm-commits mailing list