Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -103,6 +103,7 @@ bool StripAll; bool StripDebug; bool SysvHash = true; + bool Target1Rel; bool Threads; bool Trace; bool Verbose; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -364,6 +364,7 @@ Config->Shared = Args.hasArg(OPT_shared); Config->StripAll = Args.hasArg(OPT_strip_all); Config->StripDebug = Args.hasArg(OPT_strip_debug); + Config->Target1Rel = Args.hasArg(OPT_target1_rel); Config->Threads = Args.hasArg(OPT_threads); Config->Trace = Args.hasArg(OPT_trace); Config->Verbose = Args.hasArg(OPT_verbose); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -146,6 +146,10 @@ def sysroot: J<"sysroot=">, HelpText<"Set the system root">; +def target1_rel: F<"target1-rel">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_REL32">; + +def target1_abs: F<"target1-abs">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32">; + def threads: F<"threads">, HelpText<"Enable use of threads">; def trace: F<"trace">, HelpText<"Print the names of the input files">; Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -1502,7 +1502,14 @@ NeedsThunks = true; } +static uint32_t modifyARMReloc(uint32_t Type) { + if (Type == R_ARM_TARGET1) + return (Config->Target1Rel) ? R_ARM_REL32 : R_ARM_ABS32; + return Type; +} + RelExpr ARMTargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const { + Type = modifyARMReloc(Type); switch (Type) { default: return R_ABS; @@ -1548,6 +1555,7 @@ } uint32_t ARMTargetInfo::getDynRel(uint32_t Type) const { + Type = modifyARMReloc(Type); if (Type == R_ARM_ABS32) return Type; // Keep it going with a dummy value so that we can find more reloc errors. @@ -1620,6 +1628,7 @@ void ARMTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { + Type = modifyARMReloc(Type); switch (Type) { case R_ARM_NONE: break; @@ -1748,6 +1757,7 @@ uint64_t ARMTargetInfo::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { + Type = modifyARMReloc(Type); switch (Type) { default: return 0; Index: test/ELF/arm-target1.s =================================================================== --- /dev/null +++ test/ELF/arm-target1.s @@ -0,0 +1,26 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +// RUN: llvm-readobj -r %t.o | FileCheck %s --check-prefix=RELOC +// RUN: ld.lld -shared %t.o -o %t2.so --target1-rel +// RUN: llvm-objdump -t -d %t2.so | FileCheck %s \ +// RUN: --check-prefix=RELATIVE +// RUN: not ld.lld -shared %t.o -o %t3.so 2>&1 | FileCheck %s \ +// RUN: --check-prefix=ABS + +// RELOC: Relocations [ +// RELOC: .rel.text { +// RELOC: 0x0 R_ARM_TARGET1 patatino 0x0 +// RELOC: } +// RELOC: ] + +.text + .word patatino(target1) + patatino: + +// RELATIVE: Disassembly of section .text: +// RELATIVE: $d.0: +// RELATIVE: 1000: 04 00 00 00 andeq r0, r0, r4 +// RELATIVE: SYMBOL TABLE: +// RELATIVE: 00001004 .text 00000000 patatino + +// ABS: can't create dynamic relocation R_ARM_TARGET1 against readonly segment