[PATCH] D30256: [ELF] - Implemented -z noreloc-overflow.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 22 07:50:37 PST 2017


grimar created this revision.

-z noreloc-overflow is a specific feature used in linux kernel, for example,
when KASLR (Kernel address space layout randomization) is enabled.

For supporting KALSR, kernel should be build as PIE.
Currently configuration checks if noreloc-overflow is available before doing that.
(https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/Makefile#L51).

Then loader handles the produced relative dynamic relocations by itself.
 (https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/misc.c#L173).

So what this patch do is allows producing relocations against RO segement, that is where
we fail now.


https://reviews.llvm.org/D30256

Files:
  ELF/Config.h
  ELF/Driver.cpp
  ELF/Relocations.cpp
  test/ELF/znoreloc-overflow.s


Index: test/ELF/znoreloc-overflow.s
===================================================================
--- test/ELF/znoreloc-overflow.s
+++ test/ELF/znoreloc-overflow.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld --no-dynamic-linker -z noreloc-overflow %t.o -o %t -pie
+# RUN: llvm-readobj -r  %t | FileCheck %s
+
+# CHECK:      Relocations [
+# CHECK-NEXT:    Section {{.*}} .rela.dyn {
+# CHECK-NEXT:      0x1000 R_X86_64_RELATIVE - 0x1000
+# CHECK-NEXT:      0x1004 R_X86_64_RELATIVE - 0x1000
+# CHECK-NEXT:    }
+# CHECK-NEXT:  ]
+
+# RUN: not ld.lld -z noreloc-overflow %t.o -o %t -pie 2>&1 \
+# RUN:  | FileCheck %s --check-prefix=ERR
+# ERR: -z noreloc-overflow may not be used without --no-dynamic-linker
+
+.text
+.global _start
+_start:
+ .long _start
+ .quad _start
Index: ELF/Relocations.cpp
===================================================================
--- ELF/Relocations.cpp
+++ ELF/Relocations.cpp
@@ -528,11 +528,12 @@
   // only memory. We can hack around it if we are producing an executable and
   // the refered symbol can be preemepted to refer to the executable.
   if (Config->Shared || (Config->pic() && !isRelExpr(Expr))) {
-    error(S.getLocation(RelOff) + ": can't create dynamic relocation " +
-          toString(Type) + " against " +
-          (Body.getName().empty() ? "local symbol in readonly segment"
-                                  : "symbol '" + toString(Body) + "'") +
-          " defined in " + toString(Body.File));
+    if (!Config->ZNorelocOverflow)
+      error(S.getLocation(RelOff) + ": can't create dynamic relocation " +
+            toString(Type) + " against " +
+            (Body.getName().empty() ? "local symbol in readonly segment"
+                                    : "symbol '" + toString(Body) + "'") +
+            " defined in " + toString(Body.File));
     return Expr;
   }
   if (Body.getVisibility() != STV_DEFAULT) {
Index: ELF/Driver.cpp
===================================================================
--- ELF/Driver.cpp
+++ ELF/Driver.cpp
@@ -234,6 +234,14 @@
     if (Config->Pie)
       error("-r and -pie may not be used together");
   }
+
+  // -z noreloc-overflow is a specific feature used in kernels. When it is
+  // enabled, we may emit a dynamic relocation against RO segment. In that
+  // case we would need to add DT_TEXTREL flag to prepareruntime linker.
+  // Though noreloc-overflow is usually for producing  self-relocatable
+  // output which avoid use of dynamic linker.
+  if (Config->ZNorelocOverflow && !Args.hasArg(OPT_no_dynamic_linker))
+    error("-z noreloc-overflow may not be used without --no-dynamic-linker");
 }
 
 static StringRef getString(opt::InputArgList &Args, unsigned Key,
@@ -576,6 +584,7 @@
   Config->ZExecstack = hasZOption(Args, "execstack");
   Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
   Config->ZNodelete = hasZOption(Args, "nodelete");
+  Config->ZNorelocOverflow = hasZOption(Args, "noreloc-overflow");
   Config->ZNow = hasZOption(Args, "now");
   Config->ZOrigin = hasZOption(Args, "origin");
   Config->ZRelro = !hasZOption(Args, "norelro");
Index: ELF/Config.h
===================================================================
--- ELF/Config.h
+++ ELF/Config.h
@@ -138,6 +138,7 @@
   bool ZExecstack;
   bool ZNocopyreloc;
   bool ZNodelete;
+  bool ZNorelocOverflow;
   bool ZNow;
   bool ZOrigin;
   bool ZRelro;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30256.89361.patch
Type: text/x-patch
Size: 3441 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170222/de99c6a0/attachment.bin>


More information about the llvm-commits mailing list