[PATCH] D28857: [ELF] - Allow relative relocations to a absolute value defined in linker script.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 18 05:43:57 PST 2017


grimar created this revision.

I faced next error during linking linux kernel:
arch/x86/entry/vdso/vclock_gettime.c:148: relocation R_X86_64_PC32 cannot refer to absolute symbol 'vvar_vsyscall_gtod_data' defined in (internal)

Symbol is defined in script:

   /*
  	 * User/kernel shared data is before the vDSO.  This may be a little
  	 * uglier than putting it after the vDSO, but it avoids issues with
  	 * non-allocatable things that dangle past the end of the PT_LOAD
  	 * segment.
  	 */
   vvar_start = . - 2 * (1 << 12);
   vvar_page = vvar_start;
  /*
  <skipped>
   * These variables live in a page of kernel data that has an extra RO
   * mapping for userspace.  Each variable needs a unique offset within
   * that page; specify that offset with the DECLARE_VVAR macro.  (If
   * you mess up, the linker will catch it.)
   */
  /* The kernel linker script defines its own magic to put vvars in the
   * right place.
   */
  /* DECLARE_VVAR(offset, type, name) */
  vvar_vsyscall_gtod_data = vvar_page + 128;

I was able to extract minimal reproducable using the original parts of code
for demonstation of their use case.

main.c:

  // https://github.com/torvalds/linux/blob/d33d5a6c88fcd53fec329a1521010f1bc55fa191/arch/x86/include/asm/vgtod.h
  // https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/include/asm/vvar.h
  // https://github.com/torvalds/linux/blob/d33d5a6c88fcd53fec329a1521010f1bc55fa191/arch/x86/entry/vdso/vclock_gettime.c
  
  struct vsyscall_gtod_data {
  	unsigned seq;
  };
  
  #define DECLARE_VVAR(offset, type, name)				\
  	extern type vvar_ ## name __attribute__((visibility("hidden")));
  DECLARE_VVAR(128, struct vsyscall_gtod_data, vsyscall_gtod_data)
  
  #define VVAR(name) (vvar_ ## name)
  
  #define gtod (&VVAR(vsyscall_gtod_data))
  
  void foo() {
    unsigned seq = gtod->seq;
  }

script.lds:

  SECTIONS { vvar_vsyscall_gtod_data = 0x10000; }

Run:

  gcc -shared main.c -S -o main_gcc.s
  llvm-mc -filetype=obj -triple=x86_64-pc-linux main_gcc.s -o main.o
  ld -shared main.o --script script.lds -o out.lld

bfd accepts this inputs fine, LLD fails with "cannot refer to absolute symbol..." error. 
Patch allows to have such relocations.


https://reviews.llvm.org/D28857

Files:
  ELF/Relocations.cpp
  test/ELF/linkerscript/relative-absolute.s


Index: test/ELF/linkerscript/relative-absolute.s
===================================================================
--- test/ELF/linkerscript/relative-absolute.s
+++ test/ELF/linkerscript/relative-absolute.s
@@ -0,0 +1,30 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+# RUN: echo "SECTIONS { vvar_vsyscall_gtod_data = 0x10000; }" > %t.script
+# RUN: ld.lld -shared %t1.o --script %t.script -o %t
+# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DUMP
+# RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SYMBOL
+
+# DUMP:       Disassembly of section .text:
+# DUMP-NEXT:  foo:
+# DUMP-NEXT:   0: {{.*}} 65530(%rip), %eax
+
+# SYMBOL:     Symbol {
+# SYMBOL:        Name: vvar_vsyscall_gtod_data
+# SYMBOL-NEXT:   Value: 0x10000
+# SYMBOL-NEXT:   Size: 0
+# SYMBOL-NEXT:   Binding: Local
+# SYMBOL-NEXT:   Type: None
+# SYMBOL-NEXT:   Other [
+# SYMBOL-NEXT:     STV_HIDDEN
+# SYMBOL-NEXT:   ]
+# SYMBOL-NEXT:   Section: Absolute (0xFFF1)
+# SYMBOL-NEXT: }
+
+.text
+.globl foo
+.type foo, @function
+foo:
+ movl vvar_vsyscall_gtod_data(%rip), %eax
+
+.hidden	vvar_vsyscall_gtod_data
Index: ELF/Relocations.cpp
===================================================================
--- ELF/Relocations.cpp
+++ ELF/Relocations.cpp
@@ -356,6 +356,10 @@
       return true;
     if (&Body == ElfSym<ELFT>::MipsGpDisp)
       return true;
+    // Sometimes code has relocations to absolute symbol defined in linker script.
+    // Example is linux kernel. Hence we allow it.
+    if (!Body.File)
+      return true;
     error(S.getLocation(RelOff) + ": relocation " + toString(Type) +
           " cannot refer to absolute symbol '" + toString(Body) +
           "' defined in " + toString(Body.File));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28857.84824.patch
Type: text/x-patch
Size: 1750 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170118/0612a8c6/attachment.bin>


More information about the llvm-commits mailing list