forked from OSchip/llvm-project
[lld][ARM] Add relocations to perform function calls
Added relocations to perform function calls with and without passing arguments. ARM-only, Thumb-only and mixed mode code generations are supported. Only simple veneers (direct instruction modification) are supported as ARM-Thumb interwork. Differential Revision: http://reviews.llvm.org/D7223 llvm-svn: 227961
This commit is contained in:
parent
1702eb1840
commit
b635ae8388
|
@ -16,14 +16,61 @@
|
|||
using namespace lld;
|
||||
using namespace elf;
|
||||
|
||||
static Reference::Addend readAddend_THM_MOV(const uint8_t *location) {
|
||||
const auto halfHi = uint16_t(
|
||||
*reinterpret_cast<const llvm::support::ulittle16_t *>(location));
|
||||
const auto halfLo = uint16_t(
|
||||
*reinterpret_cast<const llvm::support::ulittle16_t *>(location + 2));
|
||||
|
||||
const uint16_t imm8 = halfLo & 0xFF;
|
||||
const uint16_t imm3 = (halfLo >> 12) & 0x7;
|
||||
|
||||
const uint16_t imm4 = halfHi & 0xF;
|
||||
const uint16_t bitI = (halfHi >> 10) & 0x1;
|
||||
|
||||
const auto result = int16_t((imm4 << 12) | (bitI << 11) | (imm3 << 8) | imm8);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Reference::Addend readAddend_ARM_MOV(const uint8_t *location) {
|
||||
const auto value = uint32_t(
|
||||
*reinterpret_cast<const llvm::support::ulittle32_t *>(location));
|
||||
|
||||
const uint32_t imm12 = value & 0xFFF;
|
||||
const uint32_t imm4 = (value >> 16) & 0xF;
|
||||
|
||||
const auto result = int32_t((imm4 << 12) | imm12);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Reference::Addend readAddend_THM_CALL(const uint8_t *location) {
|
||||
const auto halfHi = uint16_t(
|
||||
*reinterpret_cast<const llvm::support::ulittle16_t *>(location));
|
||||
const auto halfLo = uint16_t(
|
||||
*reinterpret_cast<const llvm::support::ulittle16_t *>(location + 2));
|
||||
|
||||
const uint16_t imm10 = halfHi & 0x3FF;
|
||||
const uint16_t bitS = (halfHi >> 10) & 0x1;
|
||||
|
||||
const uint16_t imm11 = halfLo & 0x7FF;
|
||||
const uint16_t bitJ2 = (halfLo >> 11) & 0x1;
|
||||
const uint16_t bitI2 = (~(bitJ2 ^ bitS)) & 0x1;
|
||||
const uint16_t bitJ1 = (halfLo >> 13) & 0x1;
|
||||
const uint16_t bitI1 = (~(bitJ1 ^ bitS)) & 0x1;
|
||||
|
||||
const auto result = int32_t((bitS << 24) | (bitI1 << 23) | (bitI2 << 22) |
|
||||
(imm10 << 12) | (imm11 << 1));
|
||||
return llvm::SignExtend64<25>(result);
|
||||
}
|
||||
|
||||
static Reference::Addend readAddend_ARM_CALL(const uint8_t *location) {
|
||||
const auto value = int32_t(
|
||||
*reinterpret_cast<const llvm::support::little32_t *>(location));
|
||||
const auto value = uint32_t(
|
||||
*reinterpret_cast<const llvm::support::ulittle32_t *>(location));
|
||||
|
||||
const bool isBLX = (value & 0xF0000000) == 0xF0000000;
|
||||
const int32_t bitH = isBLX ? ((value & 0x1000000) >> 24) : 0;
|
||||
const uint32_t bitH = isBLX ? ((value & 0x1000000) >> 24) : 0;
|
||||
|
||||
const int32_t result = ((value & 0xFFFFFF) << 2) | (bitH << 1);
|
||||
const auto result = int32_t(((value & 0xFFFFFF) << 2) | (bitH << 1));
|
||||
return llvm::SignExtend64<26>(result);
|
||||
}
|
||||
|
||||
|
@ -33,8 +80,18 @@ static Reference::Addend readAddend(const uint8_t *location,
|
|||
case R_ARM_ABS32:
|
||||
return int32_t(
|
||||
*reinterpret_cast<const llvm::support::little32_t *>(location));
|
||||
case R_ARM_THM_CALL:
|
||||
case R_ARM_THM_JUMP24:
|
||||
return readAddend_THM_CALL(location);
|
||||
case R_ARM_CALL:
|
||||
case R_ARM_JUMP24:
|
||||
return readAddend_ARM_CALL(location);
|
||||
case R_ARM_MOVW_ABS_NC:
|
||||
case R_ARM_MOVT_ABS:
|
||||
return readAddend_ARM_MOV(location);
|
||||
case R_ARM_THM_MOVW_ABS_NC:
|
||||
case R_ARM_THM_MOVT_ABS:
|
||||
return readAddend_THM_MOV(location);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -48,23 +105,102 @@ static inline void applyArmReloc(uint8_t *location, uint32_t result,
|
|||
~mask) | (result & mask);
|
||||
}
|
||||
|
||||
/// \brief R_ARM_ABS32 - (S + A) | T => S + A
|
||||
static inline void applyThmReloc(uint8_t *location, uint16_t resHi,
|
||||
uint16_t resLo, uint16_t maskHi,
|
||||
uint16_t maskLo = 0xFFFF) {
|
||||
assert(!(resHi & ~maskHi) && !(resLo & ~maskLo));
|
||||
*reinterpret_cast<llvm::support::ulittle16_t *>(location) =
|
||||
(uint16_t(*reinterpret_cast<llvm::support::ulittle16_t *>(location)) &
|
||||
~maskHi) | (resHi & maskHi);
|
||||
location += 2;
|
||||
*reinterpret_cast<llvm::support::ulittle16_t *>(location) =
|
||||
(uint16_t(*reinterpret_cast<llvm::support::ulittle16_t *>(location)) &
|
||||
~maskLo) | (resLo & maskLo);
|
||||
}
|
||||
|
||||
/// \brief R_ARM_ABS32 - (S + A) | T
|
||||
static void relocR_ARM_ABS32(uint8_t *location, uint64_t P, uint64_t S,
|
||||
int64_t A) {
|
||||
uint32_t result = (uint32_t)(S + A);
|
||||
int64_t A, bool addressesThumb) {
|
||||
uint64_t T = addressesThumb;
|
||||
uint32_t result = (uint32_t)((S + A) | T);
|
||||
|
||||
DEBUG_WITH_TYPE(
|
||||
"ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
|
||||
llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
|
||||
llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
|
||||
llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
|
||||
llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
|
||||
llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
|
||||
applyArmReloc(location, result);
|
||||
}
|
||||
|
||||
/// \brief R_ARM_CALL - ((S + A) | T) - P => S + A - P
|
||||
/// \brief Relocate B/BL instructions. useJs defines whether J1 & J2 are used
|
||||
static void relocR_ARM_THM_B_L(uint8_t *location, uint32_t result, bool useJs) {
|
||||
result = (result & 0x01FFFFFE) >> 1;
|
||||
|
||||
const uint16_t imm10 = (result >> 11) & 0x3FF;
|
||||
const uint16_t bitS = (result >> 23) & 0x1;
|
||||
const uint16_t resHi = (bitS << 10) | imm10;
|
||||
|
||||
const uint16_t imm11 = result & 0x7FF;
|
||||
const uint16_t bitJ2 = useJs ? ((result >> 21) & 0x1) : bitS;
|
||||
const uint16_t bitI2 = (~(bitJ2 ^ bitS)) & 0x1;
|
||||
const uint16_t bitJ1 = useJs ? ((result >> 22) & 0x1) : bitS;
|
||||
const uint16_t bitI1 = (~(bitJ1 ^ bitS)) & 0x1;
|
||||
const uint16_t resLo = (bitI1 << 13) | (bitI2 << 11) | imm11;
|
||||
|
||||
applyThmReloc(location, resHi, resLo, 0x7FF, 0x2FFF);
|
||||
}
|
||||
|
||||
/// \brief R_ARM_THM_CALL - ((S + A) | T) - P
|
||||
static void relocR_ARM_THM_CALL(uint8_t *location, uint64_t P, uint64_t S,
|
||||
int64_t A, bool useJs, bool addressesThumb) {
|
||||
uint64_t T = addressesThumb;
|
||||
const bool switchMode = !addressesThumb;
|
||||
|
||||
if (switchMode) {
|
||||
P &= ~0x3; // Align(P, 4) by rounding down
|
||||
}
|
||||
|
||||
uint32_t result = (uint32_t)(((S + A) | T) - P);
|
||||
|
||||
DEBUG_WITH_TYPE(
|
||||
"ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
|
||||
llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
|
||||
llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
|
||||
llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
|
||||
llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
|
||||
llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
|
||||
relocR_ARM_THM_B_L(location, result, useJs);
|
||||
|
||||
if (switchMode) {
|
||||
applyThmReloc(location, 0, 0, 0, 0x1001);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief R_ARM_THM_JUMP24 - ((S + A) | T) - P
|
||||
static void relocR_ARM_THM_JUMP24(uint8_t *location, uint64_t P, uint64_t S,
|
||||
int64_t A, bool addressesThumb) {
|
||||
uint64_t T = addressesThumb;
|
||||
uint32_t result = (uint32_t)(((S + A) | T) - P);
|
||||
|
||||
DEBUG_WITH_TYPE(
|
||||
"ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
|
||||
llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
|
||||
llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
|
||||
llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
|
||||
llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
|
||||
llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
|
||||
relocR_ARM_THM_B_L(location, result, true);
|
||||
}
|
||||
|
||||
/// \brief R_ARM_CALL - ((S + A) | T) - P
|
||||
static void relocR_ARM_CALL(uint8_t *location, uint64_t P, uint64_t S,
|
||||
int64_t A) {
|
||||
uint32_t result = (uint32_t)((S + A) - P);
|
||||
int64_t A, bool addressesThumb) {
|
||||
uint64_t T = addressesThumb;
|
||||
const bool switchMode = addressesThumb;
|
||||
|
||||
uint32_t result = (uint32_t)(((S + A) | T) - P);
|
||||
const uint32_t imm24 = (result & 0x03FFFFFC) >> 2;
|
||||
|
||||
DEBUG_WITH_TYPE(
|
||||
|
@ -72,8 +208,117 @@ static void relocR_ARM_CALL(uint8_t *location, uint64_t P, uint64_t S,
|
|||
llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
|
||||
llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
|
||||
llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
|
||||
llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
|
||||
llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
|
||||
applyArmReloc(location, imm24, 0xFFFFFF);
|
||||
|
||||
if (switchMode) {
|
||||
const uint32_t bitH = (result & 0x2) >> 1;
|
||||
applyArmReloc(location, (0xFA | bitH) << 24, 0xFF000000);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief R_ARM_JUMP24 - ((S + A) | T) - P
|
||||
static void relocR_ARM_JUMP24(uint8_t *location, uint64_t P, uint64_t S,
|
||||
int64_t A, bool addressesThumb) {
|
||||
uint64_t T = addressesThumb;
|
||||
uint32_t result = (uint32_t)(((S + A) | T) - P);
|
||||
const uint32_t imm24 = (result & 0x03FFFFFC) >> 2;
|
||||
|
||||
DEBUG_WITH_TYPE(
|
||||
"ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
|
||||
llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
|
||||
llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
|
||||
llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
|
||||
llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
|
||||
llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
|
||||
applyArmReloc(location, imm24, 0xFFFFFF);
|
||||
}
|
||||
|
||||
/// \brief Relocate ARM MOVW/MOVT instructions
|
||||
static void relocR_ARM_MOV(uint8_t *location, uint32_t result) {
|
||||
const uint32_t imm12 = result & 0xFFF;
|
||||
const uint32_t imm4 = (result >> 12) & 0xF;
|
||||
|
||||
applyArmReloc(location, (imm4 << 16) | imm12, 0xF0FFF);
|
||||
}
|
||||
|
||||
/// \brief R_ARM_MOVW_ABS_NC - (S + A) | T
|
||||
static void relocR_ARM_MOVW_ABS_NC(uint8_t *location, uint64_t P, uint64_t S,
|
||||
int64_t A, bool addressesThumb) {
|
||||
uint64_t T = addressesThumb;
|
||||
uint32_t result = (uint32_t)((S + A) | T);
|
||||
const uint32_t arg = result & 0x0000FFFF;
|
||||
|
||||
DEBUG_WITH_TYPE(
|
||||
"ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
|
||||
llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
|
||||
llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
|
||||
llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
|
||||
llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
|
||||
llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
|
||||
return relocR_ARM_MOV(location, arg);
|
||||
}
|
||||
|
||||
/// \brief R_ARM_MOVT_ABS - S + A
|
||||
static void relocR_ARM_MOVT_ABS(uint8_t *location, uint64_t P, uint64_t S,
|
||||
int64_t A) {
|
||||
uint32_t result = (uint32_t)(S + A);
|
||||
const uint32_t arg = (result & 0xFFFF0000) >> 16;
|
||||
|
||||
DEBUG_WITH_TYPE(
|
||||
"ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
|
||||
llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
|
||||
llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
|
||||
llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
|
||||
llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
|
||||
return relocR_ARM_MOV(location, arg);
|
||||
}
|
||||
|
||||
/// \brief Relocate Thumb MOVW/MOVT instructions
|
||||
static void relocR_ARM_THM_MOV(uint8_t *location, uint32_t result) {
|
||||
const uint16_t imm8 = result & 0xFF;
|
||||
const uint16_t imm3 = (result >> 8) & 0x7;
|
||||
const uint16_t resLo = (imm3 << 12) | imm8;
|
||||
|
||||
const uint16_t imm4 = (result >> 12) & 0xF;
|
||||
const uint16_t bitI = (result >> 11) & 0x1;
|
||||
const uint16_t resHi = (bitI << 10) | imm4;
|
||||
|
||||
applyThmReloc(location, resHi, resLo, 0x40F, 0x70FF);
|
||||
}
|
||||
|
||||
/// \brief R_ARM_THM_MOVW_ABS_NC - (S + A) | T
|
||||
static void relocR_ARM_THM_MOVW_ABS_NC(uint8_t *location, uint64_t P,
|
||||
uint64_t S, int64_t A,
|
||||
bool addressesThumb) {
|
||||
uint64_t T = addressesThumb;
|
||||
uint32_t result = (uint32_t)((S + A) | T);
|
||||
const uint32_t arg = result & 0x0000FFFF;
|
||||
|
||||
DEBUG_WITH_TYPE(
|
||||
"ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
|
||||
llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
|
||||
llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
|
||||
llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
|
||||
llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
|
||||
llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
|
||||
return relocR_ARM_THM_MOV(location, arg);
|
||||
}
|
||||
|
||||
/// \brief R_ARM_THM_MOVT_ABS - S + A
|
||||
static void relocR_ARM_THM_MOVT_ABS(uint8_t *location, uint64_t P, uint64_t S,
|
||||
int64_t A) {
|
||||
uint32_t result = (uint32_t)(S + A);
|
||||
const uint32_t arg = (result & 0xFFFF0000) >> 16;
|
||||
|
||||
DEBUG_WITH_TYPE(
|
||||
"ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
|
||||
llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
|
||||
llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
|
||||
llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
|
||||
llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
|
||||
return relocR_ARM_THM_MOV(location, arg);
|
||||
}
|
||||
|
||||
std::error_code ARMTargetRelocationHandler::applyRelocation(
|
||||
|
@ -92,14 +337,51 @@ std::error_code ARMTargetRelocationHandler::applyRelocation(
|
|||
const Reference::Addend addend =
|
||||
readAddend(location, ref.kindValue());
|
||||
|
||||
// Flags that the relocation addresses Thumb instruction
|
||||
bool addressesThumb = false;
|
||||
|
||||
if (const auto *definedAtom = dyn_cast<DefinedAtom>(ref.target())) {
|
||||
addressesThumb = (DefinedAtom::codeARMThumb == definedAtom->codeModel());
|
||||
}
|
||||
|
||||
switch (ref.kindValue()) {
|
||||
case R_ARM_NONE:
|
||||
break;
|
||||
case R_ARM_ABS32:
|
||||
relocR_ARM_ABS32(location, relocVAddress, targetVAddress, addend);
|
||||
relocR_ARM_ABS32(location, relocVAddress, targetVAddress, addend,
|
||||
addressesThumb);
|
||||
break;
|
||||
case R_ARM_THM_CALL:
|
||||
// TODO: consider adding bool variable to disable J1 & J2 for archs
|
||||
// before ARMv6
|
||||
relocR_ARM_THM_CALL(location, relocVAddress, targetVAddress, addend, true,
|
||||
addressesThumb);
|
||||
break;
|
||||
case R_ARM_CALL:
|
||||
relocR_ARM_CALL(location, relocVAddress, targetVAddress, addend);
|
||||
relocR_ARM_CALL(location, relocVAddress, targetVAddress, addend,
|
||||
addressesThumb);
|
||||
break;
|
||||
case R_ARM_JUMP24:
|
||||
relocR_ARM_JUMP24(location, relocVAddress, targetVAddress, addend,
|
||||
addressesThumb);
|
||||
break;
|
||||
case R_ARM_THM_JUMP24:
|
||||
relocR_ARM_THM_JUMP24(location, relocVAddress, targetVAddress, addend,
|
||||
addressesThumb);
|
||||
break;
|
||||
case R_ARM_MOVW_ABS_NC:
|
||||
relocR_ARM_MOVW_ABS_NC(location, relocVAddress, targetVAddress, addend,
|
||||
addressesThumb);
|
||||
break;
|
||||
case R_ARM_MOVT_ABS:
|
||||
relocR_ARM_MOVT_ABS(location, relocVAddress, targetVAddress, addend);
|
||||
break;
|
||||
case R_ARM_THM_MOVW_ABS_NC:
|
||||
relocR_ARM_THM_MOVW_ABS_NC(location, relocVAddress, targetVAddress, addend,
|
||||
addressesThumb);
|
||||
break;
|
||||
case R_ARM_THM_MOVT_ABS:
|
||||
relocR_ARM_THM_MOVT_ABS(location, relocVAddress, targetVAddress, addend);
|
||||
break;
|
||||
default:
|
||||
return make_unhandled_reloc_error();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# data main addr content
|
||||
# 0x400084 = 0x400074 + 0x10
|
||||
# CHECK: SYMBOL TABLE:
|
||||
# CHECK: 00400074 g F .text 0000001c main
|
||||
# CHECK: 00400074 g F .text {{[0-9a-f]+}} main
|
||||
# CHECK: 00401000 g .data 00000004 data
|
||||
|
||||
---
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
# call site offset PC(arm) _Z1fv addr
|
||||
# 0x400090 + (-0x24) + 0x8 = 0x400074
|
||||
# CHECK: SYMBOL TABLE:
|
||||
# CHECK: 00400074 g F .text 00000014 _Z1fv
|
||||
# CHECK: 00400088 g F .text 00000018 main
|
||||
# CHECK: 00400074 g F .text {{[0-9a-f]+}} _Z1fv
|
||||
# CHECK: 00400088 g F .text {{[0-9a-f]+}} main
|
||||
|
||||
---
|
||||
FileHeader:
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
# Check handling of R_ARM_JUMP24 relocation.
|
||||
# RUN: yaml2obj -format=elf %s > %t-o.o
|
||||
# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
|
||||
# RUN: --noinhibit-exec %t-o.o -o %t
|
||||
# RUN: llvm-objdump -s -t %t | FileCheck %s
|
||||
|
||||
# CHECK: Contents of section .text:
|
||||
# CHECK: 400094 04b08de2 f5ffffea 0030a0e1 0300a0e1
|
||||
# offset = -0x2C ^^
|
||||
# call site offset PC(arm) _Z1fv addr
|
||||
# 0x400098 + (-0x2C) + 0x8 = 0x400074
|
||||
# CHECK: SYMBOL TABLE:
|
||||
# CHECK: 00400074 g F .text {{[0-9a-f]+}} _Z1fv
|
||||
# CHECK: 00400090 g F .text {{[0-9a-f]+}} main
|
||||
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_ARM
|
||||
Flags: [ EF_ARM_EABI_VER5 ]
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 04B02DE500B08DE20030A0E30300A0E100D04BE204B09DE41EFF2FE100482DE904B08DE2FEFFFFEA0030A0E10300A0E10088BDE8
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Link: .symtab
|
||||
AddressAlign: 0x0000000000000004
|
||||
Info: .text
|
||||
Relocations:
|
||||
- Offset: 0x0000000000000024
|
||||
Symbol: _Z1fv
|
||||
Type: R_ARM_JUMP24
|
||||
Addend: 0
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
- Name: .bss
|
||||
Type: SHT_NOBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: _Z1fv
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
- Name: main
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x000000000000001C
|
||||
...
|
|
@ -0,0 +1,64 @@
|
|||
# Check handling of R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocation pair.
|
||||
# RUN: yaml2obj -format=elf %s > %t-o.o
|
||||
# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
|
||||
# RUN: --noinhibit-exec %t-o.o -o %t
|
||||
# RUN: llvm-objdump -s -t %t | FileCheck %s
|
||||
|
||||
# CHECK: Contents of section .text:
|
||||
# CHECK: 400074 04b02de5 00b08de2 003001e3 403040e3
|
||||
# addrL = 0x1000 ^^
|
||||
# addrH = 0x40 ^^
|
||||
# addrH addrL _ZL5data1 addr
|
||||
# (0x40 << 16) + 0x1000 = 0x401000
|
||||
# CHECK: SYMBOL TABLE:
|
||||
# CHECK: 00401000 l .bss 00000004 _ZL5data1
|
||||
# CHECK: 00400074 g F .text {{[0-9a-f]+}} main
|
||||
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_ARM
|
||||
Flags: [ EF_ARM_EABI_VER5 ]
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 04B02DE500B08DE2003000E3003040E30A20A0E3002083E50030A0E30300A0E100D04BE204B09DE41EFF2FE1
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Link: .symtab
|
||||
AddressAlign: 0x0000000000000004
|
||||
Info: .text
|
||||
Relocations:
|
||||
- Offset: 0x0000000000000008
|
||||
Symbol: _ZL5data1
|
||||
Type: R_ARM_MOVW_ABS_NC
|
||||
Addend: 0
|
||||
- Offset: 0x000000000000000C
|
||||
Symbol: _ZL5data1
|
||||
Type: R_ARM_MOVT_ABS
|
||||
Addend: 0
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
- Name: .bss
|
||||
Type: SHT_NOBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 411C0000
|
||||
Symbols:
|
||||
Local:
|
||||
- Name: _ZL5data1
|
||||
Type: STT_OBJECT
|
||||
Section: .bss
|
||||
Size: 0x0000000000000004
|
||||
Global:
|
||||
- Name: main
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
...
|
|
@ -0,0 +1,123 @@
|
|||
# Check ARM <=> Thumb interwork.
|
||||
# RUN: yaml2obj -format=elf -docnum 1 %s > %t-arm.o
|
||||
# RUN: yaml2obj -format=elf -docnum 2 %s > %t-thm.o
|
||||
# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
|
||||
# RUN: --noinhibit-exec %t-arm.o %t-thm.o -o %t
|
||||
|
||||
# Check R_ARM_CALL veneer to call Thumb code
|
||||
# RUN: llvm-objdump -s -t %t | FileCheck -check-prefix=ARM-CALL %s
|
||||
|
||||
# ARM-CALL: Contents of section .text:
|
||||
# ARM-CALL: 400074 00482de9 04b08de2 000000fa 0088bde8
|
||||
# offset = 0x0 ^^
|
||||
# call site offset PC(arm) _Z2f2v addr
|
||||
# 0x40007C + 0x0 + 0x8 = 0x400084
|
||||
# ARM-CALL: SYMBOL TABLE:
|
||||
# ARM-CALL: 00400074 g F .text {{[0-9a-f]+}} _Z1fv
|
||||
# ARM-CALL: 00400084 g F .text {{[0-9a-f]+}} _Z2f2v
|
||||
# ARM-CALL: 00400090 g F .text {{[0-9a-f]+}} main
|
||||
|
||||
# Check R_ARM_THM_CALL veneer to call ARM code
|
||||
# RUN: llvm-objdump -s -t %t | FileCheck -check-prefix=THM-CALL %s
|
||||
|
||||
# THM-CALL: Contents of section .text:
|
||||
# THM-CALL: 400094 00bffff7 eeef0023 184680bd
|
||||
# offset = -0x24 ^^
|
||||
# call site aligned = Align(0x400096, 4) = 0x400094
|
||||
# call site aligned offset PC(thm) _Z1fv addr
|
||||
# 0x400094 + (-0x24) + 0x4 = 0x400074
|
||||
# THM-CALL: SYMBOL TABLE:
|
||||
# THM-CALL: 00400074 g F .text {{[0-9a-f]+}} _Z1fv
|
||||
# THM-CALL: 00400084 g F .text {{[0-9a-f]+}} _Z2f2v
|
||||
# THM-CALL: 00400090 g F .text {{[0-9a-f]+}} main
|
||||
|
||||
# arm.o
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_ARM
|
||||
Flags: [ EF_ARM_EABI_VER5 ]
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 00482DE904B08DE2FEFFFFEB0088BDE8
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Link: .symtab
|
||||
AddressAlign: 0x0000000000000004
|
||||
Info: .text
|
||||
Relocations:
|
||||
- Offset: 0x0000000000000008
|
||||
Symbol: _Z2f2v
|
||||
Type: R_ARM_CALL
|
||||
Addend: 0
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
- Name: .bss
|
||||
Type: SHT_NOBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: _Z1fv
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Size: 0x0000000000000010
|
||||
- Name: _Z2f2v
|
||||
|
||||
# thm.o
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_ARM
|
||||
Flags: [ EF_ARM_EABI_VER5 ]
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 80B400AFBD465DF8047B704780B500AF00BFFFF7FEFF0023184680BD
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Link: .symtab
|
||||
AddressAlign: 0x0000000000000004
|
||||
Info: .text
|
||||
Relocations:
|
||||
- Offset: 0x0000000000000012
|
||||
Symbol: _Z1fv
|
||||
Type: R_ARM_THM_CALL
|
||||
Addend: 0
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
- Name: .bss
|
||||
Type: SHT_NOBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: _Z2f2v
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x0000000000000001
|
||||
Size: 0x000000000000000C
|
||||
- Name: main
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x000000000000000D
|
||||
Size: 0x0000000000000010
|
||||
- Name: _Z1fv
|
||||
...
|
|
@ -0,0 +1,61 @@
|
|||
# Check handling of R_ARM_THM_CALL relocation.
|
||||
# RUN: yaml2obj -format=elf %s > %t-o.o
|
||||
# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
|
||||
# RUN: --noinhibit-exec %t-o.o -o %t
|
||||
# RUN: llvm-objdump -s -t %t | FileCheck %s
|
||||
|
||||
# CHECK: Contents of section .text:
|
||||
# CHECK: 400084 fff7f6ff 00231846 80bd00bf
|
||||
# ^^ offset = -0x14
|
||||
# call site offset PC(thm) _Z1fv addr
|
||||
# 0x400084 + (-0x14) + 0x4 = 0x400074
|
||||
# CHECK: SYMBOL TABLE:
|
||||
# CHECK: 00400074 g F .text {{[0-9a-f]+}} _Z1fv
|
||||
# CHECK: 00400080 g F .text {{[0-9a-f]+}} main
|
||||
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_ARM
|
||||
Flags: [ EF_ARM_EABI_VER5 ]
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 80B400AFBD465DF8047B704780B500AFFFF7FEFF0023184680BD00BF
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Link: .symtab
|
||||
AddressAlign: 0x0000000000000004
|
||||
Info: .text
|
||||
Relocations:
|
||||
- Offset: 0x0000000000000010
|
||||
Symbol: _Z1fv
|
||||
Type: R_ARM_THM_CALL
|
||||
Addend: 0
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
- Name: .bss
|
||||
Type: SHT_NOBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: _Z1fv
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x0000000000000001
|
||||
Size: 0x000000000000000C
|
||||
- Name: main
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x000000000000000D
|
||||
Size: 0x000000000000000E
|
||||
...
|
|
@ -0,0 +1,59 @@
|
|||
# Check handling of R_ARM_THM_JUMP24 relocation.
|
||||
# RUN: yaml2obj -format=elf %s > %t-o.o
|
||||
# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
|
||||
# RUN: --noinhibit-exec %t-o.o -o %t
|
||||
# RUN: llvm-objdump -s -t %t | FileCheck %s
|
||||
|
||||
# CHECK: Contents of section .text:
|
||||
# CHECK: 400084 80b500af fff7f4bf 03461846 80bd00bf
|
||||
# ^^ offset = -0x18
|
||||
# call site offset PC(thm) _Z1fv addr
|
||||
# 0x400088 + (-0x18) + 0x4 = 0x400074
|
||||
# CHECK: SYMBOL TABLE:
|
||||
# CHECK: 00400074 g F .text {{[0-9a-f]+}} _Z1fv
|
||||
# CHECK: 00400084 g F .text {{[0-9a-f]+}} main
|
||||
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_ARM
|
||||
Flags: [ EF_ARM_EABI_VER5 ]
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 80B400AF00231846BD465DF8047B704780B500AFFFF7FEBF0346184680BD00BF
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Link: .symtab
|
||||
AddressAlign: 0x0000000000000004
|
||||
Info: .text
|
||||
Relocations:
|
||||
- Offset: 0x0000000000000014
|
||||
Symbol: _Z1fv
|
||||
Type: R_ARM_THM_JUMP24
|
||||
Addend: 0
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
- Name: .bss
|
||||
Type: SHT_NOBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: _Z1fv
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x0000000000000001
|
||||
- Name: main
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x0000000000000011
|
||||
...
|
|
@ -0,0 +1,70 @@
|
|||
# 1. Check handling of R_ARM_THM_MOVW_ABS_NC and R_THM_ARM_MOVT_ABS relocation pair.
|
||||
# 2. Check that instructions are not cropped for symbols that address Thumb code.
|
||||
# RUN: yaml2obj -format=elf %s > %t-o.o
|
||||
# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
|
||||
# RUN: --noinhibit-exec %t-o.o -o %t
|
||||
# RUN: llvm-objdump -s -t %t | FileCheck %s
|
||||
# RUN: llvm-objdump -s -t %t | FileCheck -check-prefix=INSN-CROP %s
|
||||
|
||||
# CHECK: Contents of section .text:
|
||||
# CHECK: 400074 {{[0-9a-f]+}} 41f20003 c0f24003 0a221a60
|
||||
# addrL = 0x1000 ^^
|
||||
# addrH = 0x40 ^^
|
||||
# addrH addrL _ZL5data1 addr
|
||||
# (0x40 << 16) + 0x1000 = 0x401000
|
||||
# CHECK: SYMBOL TABLE:
|
||||
# CHECK: 00401000 l .bss 00000004 _ZL5data1
|
||||
# CHECK: 00400074 g F .text {{[0-9a-f]+}} main
|
||||
#
|
||||
# INSN-CROP: Contents of section .text:
|
||||
# INSN-CROP: 400074 80b400af
|
||||
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_ARM
|
||||
Flags: [ EF_ARM_EABI_VER5 ]
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 80B400AF40F20003C0F200030A221A6000231846BD465DF8047B7047
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Link: .symtab
|
||||
AddressAlign: 0x0000000000000004
|
||||
Info: .text
|
||||
Relocations:
|
||||
- Offset: 0x0000000000000004
|
||||
Symbol: _ZL5data1
|
||||
Type: R_ARM_THM_MOVW_ABS_NC
|
||||
Addend: 0
|
||||
- Offset: 0x0000000000000008
|
||||
Symbol: _ZL5data1
|
||||
Type: R_ARM_THM_MOVT_ABS
|
||||
Addend: 0
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000001
|
||||
Content: ''
|
||||
- Name: .bss
|
||||
Type: SHT_NOBITS
|
||||
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
||||
AddressAlign: 0x0000000000000004
|
||||
Content: 411C0000
|
||||
Symbols:
|
||||
Local:
|
||||
- Name: _ZL5data1
|
||||
Type: STT_OBJECT
|
||||
Section: .bss
|
||||
Size: 0x0000000000000004
|
||||
Global:
|
||||
- Name: main
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x0000000000000001
|
||||
...
|
Loading…
Reference in New Issue