[ELF] Be more precise about Thumb state bit in ARM thunks

The symbols generated for Thunks have type STT_FUNC, to permit a thunk to
be reused via a blx instruction the Thumb bit (0) needs to be set properly.

Differential Revision: https://reviews.llvm.org/D34036

llvm-svn: 305065
This commit is contained in:
Peter Smith 2017-06-09 09:51:51 +00:00
parent ad0973557c
commit 28285576cb
2 changed files with 45 additions and 3 deletions

View File

@ -143,7 +143,7 @@ void ThumbV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const {
void ThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) {
ThunkSym = addSyntheticLocal(
Saver.save("__Thumbv7ABSLongThunk_" + Destination.getName()), STT_FUNC,
Offset, size(), &IS);
Offset | 0x1, size(), &IS);
addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, &IS);
}
@ -176,7 +176,7 @@ void ThumbV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const {
0x60, 0x47, // bx r12
};
uint64_t S = getARMThunkDestVA(Destination);
uint64_t P = ThunkSym->getVA();
uint64_t P = ThunkSym->getVA() & ~0x1;
memcpy(Buf, Data, sizeof(Data));
Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, S - P - 12);
Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, S - P - 8);
@ -185,7 +185,7 @@ void ThumbV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const {
void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) {
ThunkSym = addSyntheticLocal(
Saver.save("__ThumbV7PILongThunk_" + Destination.getName()), STT_FUNC,
Offset, size(), &IS);
Offset | 0x1, size(), &IS);
addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, &IS);
}

View File

@ -0,0 +1,42 @@
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o %t2 2>&1
// RUN: llvm-readobj --symbols %t2 | FileCheck %s
// RUN: ld.lld --shared %t -o %t3 2>&1
// RUN: llvm-readobj --symbols %t3 | FileCheck -check-prefix=CHECK-PI %s
// REQUIRES: arm
// Check that the symbols generated for Thunks have the correct symbol type
// of STT_FUNC and the correct value of bit 0 (0 for ARM 1 for Thumb)
.syntax unified
.section .text.thumb, "ax", %progbits
.thumb
.balign 0x1000
.globl thumb_fn
.type thumb_fn, %function
thumb_fn:
b.w arm_fn
.section .text.arm, "ax", %progbits
.arm
.balign 0x1000
.globl arm_fn
.type arm_fn, %function
arm_fn:
b thumb_fn
// CHECK: Name: __Thumbv7ABSLongThunk_arm_fn
// CHECK-NEXT: Value: 0x11005
// CHECK-NEXT: Size: 10
// CHECK-NEXT: Binding: Local (0x0)
// CHECK-NEXT: Type: Function (0x2)
// CHECK: Name: __ARMv7ABSLongThunk_thumb_fn
// CHECK-NEXT: Value: 0x11010
// CHECK-NEXT: Size: 12
// CHECK-NEXT: Binding: Local (0x0)
// CHECK-NEXT: Type: Function (0x2)
// CHECK-PI: Name: __ThumbV7PILongThunk_arm_fn
// CHECK-PI-NEXT: Value: 0x1005
// CHECK-PI-NEXT: Size: 12
// CHECK-PI-NEXT: Binding: Local (0x0)
// CHECK-PI-NEXT: Type: Function (0x2)