[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