[lld] r284404 - [ELF] Support for R_ARM_TARGET2 relocation

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 17 11:12:25 PDT 2016


Author: psmith
Date: Mon Oct 17 13:12:24 2016
New Revision: 284404

URL: http://llvm.org/viewvc/llvm-project?rev=284404&view=rev
Log:
[ELF] Support for R_ARM_TARGET2 relocation

The R_ARM_TARGET2 relocation is used in ARM exception tables to encode
a data dependency that will only be dereferenced by code in the
run-time support library. In a similar way to R_ARM_TARGET1 the
handling of the relocation is target specific, it maps to one of
R_ARM_ABS32, R_ARM_REL32 or R_ARM_GOT_PREL. The choice depends on the 
run-time library. R_ARM_GOT_PREL is used for linux and BSD,
R_ARM_ABS32 and R_ARM_REL32 are used for bare-metal.

The command line option --target2=<target> can be used to select the
relocation used for R_ARM_TARGET2. The default is R_ARM_GOT_PREL.

Differential revision: https://reviews.llvm.org/D25684

Added:
    lld/trunk/test/ELF/arm-target2.s   (with props)
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/Target.cpp

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=284404&r1=284403&r2=284404&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Mon Oct 17 13:12:24 2016
@@ -45,6 +45,9 @@ enum class UnresolvedPolicy { NoUndef, R
 // For --sort-section and linkerscript sorting rules.
 enum class SortSectionPolicy { Default, None, Alignment, Name, Priority };
 
+// For --target2
+enum class Target2Policy { Abs, Rel, GotRel };
+
 struct SymbolVersion {
   llvm::StringRef Name;
   bool IsExternCpp;
@@ -131,6 +134,7 @@ struct Configuration {
   SortSectionPolicy SortSection;
   StripPolicy Strip = StripPolicy::None;
   UnresolvedPolicy UnresolvedSymbols;
+  Target2Policy Target2 = Target2Policy::GotRel;
   BuildIdKind BuildId = BuildIdKind::None;
   ELFKind EKind = ELFNoneKind;
   uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=284404&r1=284403&r2=284404&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Oct 17 13:12:24 2016
@@ -345,6 +345,20 @@ static UnresolvedPolicy getUnresolvedSym
   return UnresolvedPolicy::ReportError;
 }
 
+static Target2Policy getTarget2Option(opt::InputArgList &Args) {
+  if (auto *Arg = Args.getLastArg(OPT_target2)) {
+    StringRef S = Arg->getValue();
+    if (S == "rel")
+      return Target2Policy::Rel;
+    if (S == "abs")
+      return Target2Policy::Abs;
+    if (S == "got-rel")
+      return Target2Policy::GotRel;
+    error("unknown --target2 option: " + S);
+  }
+  return Target2Policy::GotRel;
+}
+
 static bool isOutputFormatBinary(opt::InputArgList &Args) {
   if (auto *Arg = Args.getLastArg(OPT_oformat)) {
     StringRef S = Arg->getValue();
@@ -550,6 +564,8 @@ void LinkerDriver::readConfigs(opt::Inpu
 
   Config->UnresolvedSymbols = getUnresolvedSymbolOption(Args);
 
+  Config->Target2 = getTarget2Option(Args);
+
   if (auto *Arg = Args.getLastArg(OPT_dynamic_list))
     if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
       parseDynamicList(*Buffer);

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=284404&r1=284403&r2=284404&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Mon Oct 17 13:12:24 2016
@@ -177,6 +177,8 @@ def target1_rel: F<"target1-rel">, HelpT
 
 def target1_abs: F<"target1-abs">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32">;
 
+def target2: J<"target2=">, MetaVarName<"<type>">, HelpText<"Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel.">;
+
 def threads: F<"threads">, HelpText<"Enable use of threads">;
 
 def trace: F<"trace">, HelpText<"Print the names of the input files">;

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=284404&r1=284403&r2=284404&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Mon Oct 17 13:12:24 2016
@@ -1554,6 +1554,12 @@ RelExpr ARMTargetInfo::getRelExpr(uint32
     return R_GOT_PC;
   case R_ARM_TARGET1:
     return Config->Target1Rel ? R_PC : R_ABS;
+  case R_ARM_TARGET2:
+    if (Config->Target2 == Target2Policy::Rel)
+      return R_PC;
+    if (Config->Target2 == Target2Policy::Abs)
+      return R_ABS;
+    return R_GOT_PC;
   case R_ARM_TLS_GD32:
     return R_TLSGD_PC;
   case R_ARM_TLS_LDM32:
@@ -1660,6 +1666,7 @@ void ARMTargetInfo::relocateOne(uint8_t
   case R_ARM_GOT_PREL:
   case R_ARM_REL32:
   case R_ARM_TARGET1:
+  case R_ARM_TARGET2:
   case R_ARM_TLS_GD32:
   case R_ARM_TLS_IE32:
   case R_ARM_TLS_LDM32:
@@ -1789,6 +1796,7 @@ uint64_t ARMTargetInfo::getImplicitAdden
   case R_ARM_GOT_PREL:
   case R_ARM_REL32:
   case R_ARM_TARGET1:
+  case R_ARM_TARGET2:
   case R_ARM_TLS_GD32:
   case R_ARM_TLS_LDM32:
   case R_ARM_TLS_LDO32:

Added: lld/trunk/test/ELF/arm-target2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-target2.s?rev=284404&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-target2.s (added)
+++ lld/trunk/test/ELF/arm-target2.s Mon Oct 17 13:12:24 2016
@@ -0,0 +1,60 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: ld.lld %t.o -o %t 2>&1
+// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t | FileCheck %s
+// RUN: ld.lld %t.o --target2=got-rel -o %t2 2>&1
+// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
+// RUN: ld.lld %t.o --target2=abs -o %t3 2>&1
+// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-ABS %s
+// RUN: ld.lld %t.o --target2=rel -o %t4 2>&1
+// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-REL %s
+// REQUIRES: arm
+
+// The R_ARM_TARGET2 is present in .ARM.extab sections. It can be handled as
+// either R_ARM_ABS32, R_ARM_REL32 or R_ARM_GOT_PREL. For ARM linux the default
+// is R_ARM_GOT_PREL. The other two options are primarily used for bare-metal,
+// they can be selected with the --target2=abs or --target2=rel option.
+ .syntax unified
+ .text
+ .globl _start
+ .align 2
+_start:
+ .type function, %function
+ .fnstart
+ bx lr
+ .personality   __gxx_personality_v0
+ .handlerdata
+ .word  _ZTIi(TARGET2)
+ .text
+ .fnend
+ .global __gxx_personality_v0
+ .type function, %function
+__gxx_personality_v0:
+ bx lr
+
+ .rodata
+_ZTIi:  .word 0
+
+// CHECK: Contents of section .ARM.extab:
+// 1011c + 1ee4 = 12000 = .got
+// CHECK-NEXT:  10114 f00e0000 b0b0b000 e41e0000
+
+// CHECK-ABS: Contents of section .ARM.extab:
+// 100e8 = .rodata
+// CHECK-ABS-NEXT: 100d4 300f0000 b0b0b000 e8000100
+
+// CHECK-REL: Contents of section .ARM.extab:
+// 100dc + c = 100e8 = .rodata
+// CHECK-REL-NEXT: 100d4 300f0000 b0b0b000 0c000000
+
+// CHECK: Contents of section .rodata:
+// CHECK-NEXT: 10128 00000000
+
+// CHECK-ABS: Contents of section .rodata:
+// CHECK-ABS-NEXT: 100e8 00000000
+
+// CHECK-REL: Contents of section .rodata:
+// CHECK-REL-NEXT: 100e8 00000000
+
+// CHECK: Contents of section .got:
+// 10128 = _ZTIi
+// CHECK-NEXT: 12000 28010100

Propchange: lld/trunk/test/ELF/arm-target2.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-target2.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id




More information about the llvm-commits mailing list