Skip to content

Commit

Permalink
[ELF] Implement option to force PIC compatible Thunks
Browse files Browse the repository at this point in the history
By default LLD will generate position independent Thunks when the --pie or
--shared option is used. Reference to absolute addresses is permitted in
other cases. For some embedded systems position independent thunks are
needed for code that executes before the MMU has been set up. The option
--pic-veneer is used by ld.bfd to force position independent thunks.
    
The patch adds --pic-veneer as the option is needed for the Linux kernel
on Arm.
    
fixes pr39886
    
Differential Revision: https://reviews.llvm.org/D55505

llvm-svn: 351326
  • Loading branch information
smithp35 committed Jan 16, 2019
1 parent 3ec170c commit 13d1346
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 5 deletions.
1 change: 1 addition & 0 deletions lld/ELF/Config.h
Expand Up @@ -159,6 +159,7 @@ struct Configuration {
bool OFormatBinary;
bool Omagic;
bool OptRemarksWithHotness;
bool PicThunk;
bool Pie;
bool PrintGcSections;
bool PrintIcfSections;
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/Driver.cpp
Expand Up @@ -1006,6 +1006,7 @@ static void setConfigs(opt::InputArgList &Args) {
Config->Endianness = Config->IsLE ? endianness::little : endianness::big;
Config->IsMips64EL = (K == ELF64LEKind && M == EM_MIPS);
Config->Pic = Config->Pie || Config->Shared;
Config->PicThunk = Args.hasArg(OPT_pic_veneer, Config->Pic);
Config->Wordsize = Config->Is64 ? 8 : 4;

// ELF defines two different ways to store relocation addends as shown below:
Expand Down
3 changes: 3 additions & 0 deletions lld/ELF/Options.td
Expand Up @@ -255,6 +255,9 @@ defm use_android_relr_tags: B<"use-android-relr-tags",
"Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*",
"Use SHT_RELR / DT_RELR* tags (default)">;

def pic_veneer: F<"pic-veneer">,
HelpText<"Always generate position independent thunks (veneers)">;

defm pie: B<"pie",
"Create a position independent executable",
"Do not create a position independent executable (default)">;
Expand Down
10 changes: 5 additions & 5 deletions lld/ELF/Thunks.cpp
Expand Up @@ -722,7 +722,7 @@ Thunk::~Thunk() = default;
static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
fatal("unrecognized relocation type");
if (Config->Pic)
if (Config->PicThunk)
return make<AArch64ADRPThunk>(S);
return make<AArch64ABSLongThunk>(S);
}
Expand All @@ -739,7 +739,7 @@ static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
case R_ARM_JUMP24:
case R_ARM_CALL:
case R_ARM_THM_CALL:
if (Config->Pic)
if (Config->PicThunk)
return make<ARMV5PILongThunk>(S);
return make<ARMV5ABSLongThunk>(S);
}
Expand Down Expand Up @@ -794,13 +794,13 @@ static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
case R_ARM_PLT32:
case R_ARM_JUMP24:
case R_ARM_CALL:
if (Config->Pic)
if (Config->PicThunk)
return make<ARMV7PILongThunk>(S);
return make<ARMV7ABSLongThunk>(S);
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
if (Config->Pic)
if (Config->PicThunk)
return make<ThumbV7PILongThunk>(S);
return make<ThumbV7ABSLongThunk>(S);
}
Expand All @@ -820,7 +820,7 @@ static Thunk *addThunkPPC64(RelType Type, Symbol &S) {
if (S.isInPlt())
return make<PPC64PltCallStub>(S);

if (Config->Pic)
if (Config->PicThunk)
return make<PPC64PILongBranchThunk>(S);

return make<PPC64PDLongBranchThunk>(S);
Expand Down
2 changes: 2 additions & 0 deletions lld/docs/ld.lld.1
Expand Up @@ -311,6 +311,8 @@ Write optimization remarks in YAML format to
.Ar file .
.It Fl -opt-remarks-with-hotness
Include hotness information in the optimization remarks file.
.It Fl -pic-veneer
Always generate position independent thunks.
.It Fl -pie
Create a position independent executable.
.It Fl -print-gc-sections
Expand Down
87 changes: 87 additions & 0 deletions lld/test/ELF/arm-force-pi-thunk.s
@@ -0,0 +1,87 @@
// REQUIRES: arm
// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
// RUN: echo "SECTIONS { \
// RUN: . = SIZEOF_HEADERS; \
// RUN: .text_low : { *(.text_low) *(.text_low2) } \
// RUN: .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
// RUN: } " > %t.script
// RUN: ld.lld --pic-veneer --script %t.script %t -o %t2 2>&1
// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s

// Test that we can force generation of position independent thunks even when
// inputs are not pic.

.syntax unified
.section .text_low, "ax", %progbits
.thumb
.globl _start
_start: bx lr
.globl low_target
.type low_target, %function
low_target:
bl high_target
bl high_target2

.section .text_low2, "ax", %progbits
.thumb
.globl low_target2
.type low_target2, %function
low_target2:
bl high_target
bl high_target2

// CHECK: Disassembly of section .text_low:
// CHECK-NEXT: _start:
// CHECK-NEXT: 94: 70 47 bx lr
// CHECK: low_target:
// CHECK-NEXT: 96: 00 f0 03 f8 bl #6
// CHECK-NEXT: 9a: 00 f0 07 f8 bl #14
// CHECK-NEXT: 9e: d4 d4 bmi #-88
// CHECK: __ThumbV7PILongThunk_high_target:
// CHECK-NEXT: a0: 4f f6 55 7c movw r12, #65365
// CHECK-NEXT: a4: c0 f2 ff 1c movt r12, #511
// CHECK-NEXT: a8: fc 44 add r12, pc
// CHECK-NEXT: aa: 60 47 bx r12
// CHECK: __ThumbV7PILongThunk_high_target2:
// CHECK-NEXT: ac: 4f f6 69 7c movw r12, #65385
// CHECK-NEXT: b0: c0 f2 ff 1c movt r12, #511
// CHECK-NEXT: b4: fc 44 add r12, pc
// CHECK-NEXT: b6: 60 47 bx r12
// CHECK: low_target2:
// CHECK-NEXT: b8: ff f7 f2 ff bl #-28
// CHECK-NEXT: bc: ff f7 f6 ff bl #-20


.section .text_high, "ax", %progbits
.thumb
.globl high_target
.type high_target, %function
high_target:
bl low_target
bl low_target2

.section .text_high2, "ax", %progbits
.thumb
.globl high_target2
.type high_target2, %function
high_target2:
bl low_target
bl low_target2

// CHECK: Disassembly of section .text_high:
// CHECK-NEXT: high_target:
// CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4
// CHECK-NEXT: 2000004: 00 f0 06 f8 bl #12
// CHECK: __ThumbV7PILongThunk_low_target:
// CHECK-NEXT: 2000008: 40 f2 83 0c movw r12, #131
// CHECK-NEXT: 200000c: cf f6 00 6c movt r12, #65024
// CHECK-NEXT: 2000010: fc 44 add r12, pc
// CHECK-NEXT: 2000012: 60 47 bx r12
// CHECK: __ThumbV7PILongThunk_low_target2:
// CHECK-NEXT: 2000014: 40 f2 99 0c movw r12, #153
// CHECK-NEXT: 2000018: cf f6 00 6c movt r12, #65024
// CHECK-NEXT: 200001c: fc 44 add r12, pc
// CHECK-NEXT: 200001e: 60 47 bx r12
// CHECK: high_target2:
// CHECK-NEXT: 2000020: ff f7 f2 ff bl #-28
// CHECK-NEXT: 2000024: ff f7 f6 ff bl #-20

0 comments on commit 13d1346

Please sign in to comment.