mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
Ensure conditional BL instructions for ARM are given the fixup fixup_arm_condbranch.
Patch by Tim Northover! llvm-svn: 153737
This commit is contained in:
parent
f3c23907f5
commit
70a6f5ebc7
@ -78,7 +78,8 @@ public:
|
|||||||
{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
||||||
{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
||||||
{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
|
{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
|
||||||
{ "fixup_arm_bl", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
|
{ "fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||||
|
{ "fixup_arm_condbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||||
{ "fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
|
{ "fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||||
{ "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
{ "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
||||||
{ "fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
{ "fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
|
||||||
@ -128,7 +129,8 @@ public:
|
|||||||
if (A && ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_blx ||
|
if (A && ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_blx ||
|
||||||
(unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl ||
|
(unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl ||
|
||||||
(unsigned)Fixup.getKind() == ARM::fixup_arm_blx ||
|
(unsigned)Fixup.getKind() == ARM::fixup_arm_blx ||
|
||||||
(unsigned)Fixup.getKind() == ARM::fixup_arm_bl))
|
(unsigned)Fixup.getKind() == ARM::fixup_arm_uncondbl ||
|
||||||
|
(unsigned)Fixup.getKind() == ARM::fixup_arm_condbl))
|
||||||
IsResolved = false;
|
IsResolved = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +368,8 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
|
|||||||
|
|
||||||
case ARM::fixup_arm_condbranch:
|
case ARM::fixup_arm_condbranch:
|
||||||
case ARM::fixup_arm_uncondbranch:
|
case ARM::fixup_arm_uncondbranch:
|
||||||
case ARM::fixup_arm_bl:
|
case ARM::fixup_arm_uncondbl:
|
||||||
|
case ARM::fixup_arm_condbl:
|
||||||
case ARM::fixup_arm_blx:
|
case ARM::fixup_arm_blx:
|
||||||
// These values don't encode the low two bits since they're always zero.
|
// These values don't encode the low two bits since they're always zero.
|
||||||
// Offset by 8 just as above.
|
// Offset by 8 just as above.
|
||||||
@ -577,7 +580,8 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
|
|||||||
case ARM::fixup_arm_ldst_pcrel_12:
|
case ARM::fixup_arm_ldst_pcrel_12:
|
||||||
case ARM::fixup_arm_pcrel_10:
|
case ARM::fixup_arm_pcrel_10:
|
||||||
case ARM::fixup_arm_adr_pcrel_12:
|
case ARM::fixup_arm_adr_pcrel_12:
|
||||||
case ARM::fixup_arm_bl:
|
case ARM::fixup_arm_uncondbl:
|
||||||
|
case ARM::fixup_arm_condbl:
|
||||||
case ARM::fixup_arm_blx:
|
case ARM::fixup_arm_blx:
|
||||||
case ARM::fixup_arm_condbranch:
|
case ARM::fixup_arm_condbranch:
|
||||||
case ARM::fixup_arm_uncondbranch:
|
case ARM::fixup_arm_uncondbranch:
|
||||||
|
@ -178,7 +178,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARM::fixup_arm_bl:
|
case ARM::fixup_arm_uncondbl:
|
||||||
case ARM::fixup_arm_blx:
|
case ARM::fixup_arm_blx:
|
||||||
case ARM::fixup_arm_uncondbranch:
|
case ARM::fixup_arm_uncondbranch:
|
||||||
switch (Modifier) {
|
switch (Modifier) {
|
||||||
@ -190,6 +190,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ARM::fixup_arm_condbl:
|
||||||
case ARM::fixup_arm_condbranch:
|
case ARM::fixup_arm_condbranch:
|
||||||
Type = ELF::R_ARM_JUMP24;
|
Type = ELF::R_ARM_JUMP24;
|
||||||
break;
|
break;
|
||||||
|
@ -59,8 +59,21 @@ enum Fixups {
|
|||||||
// fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions.
|
// fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions.
|
||||||
fixup_arm_thumb_br,
|
fixup_arm_thumb_br,
|
||||||
|
|
||||||
// fixup_arm_bl - Fixup for ARM BL instructions.
|
// The following fixups handle the ARM BL instructions. These can be
|
||||||
fixup_arm_bl,
|
// conditionalised; however, the ARM ELF ABI requires a different relocation
|
||||||
|
// in that case: R_ARM_JUMP24 instead of R_ARM_CALL. The difference is that
|
||||||
|
// R_ARM_CALL is allowed to change the instruction to a BLX inline, which has
|
||||||
|
// no conditional version; R_ARM_JUMP24 would have to insert a veneer.
|
||||||
|
//
|
||||||
|
// MachO does not draw a distinction between the two cases, so it will treat
|
||||||
|
// fixup_arm_uncondbl and fixup_arm_condbl as identical fixups.
|
||||||
|
|
||||||
|
// fixup_arm_uncondbl - Fixup for unconditional ARM BL instructions.
|
||||||
|
fixup_arm_uncondbl,
|
||||||
|
|
||||||
|
// fixup_arm_condbl - Fixup for ARM BL instructions with nontrivial
|
||||||
|
// conditionalisation.
|
||||||
|
fixup_arm_condbl,
|
||||||
|
|
||||||
// fixup_arm_blx - Fixup for ARM BLX instructions.
|
// fixup_arm_blx - Fixup for ARM BLX instructions.
|
||||||
fixup_arm_blx,
|
fixup_arm_blx,
|
||||||
|
@ -597,8 +597,12 @@ uint32_t ARMMCCodeEmitter::
|
|||||||
getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||||
const MCOperand MO = MI.getOperand(OpIdx);
|
const MCOperand MO = MI.getOperand(OpIdx);
|
||||||
if (MO.isExpr())
|
if (MO.isExpr()) {
|
||||||
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_bl, Fixups);
|
if (HasConditionalBranch(MI))
|
||||||
|
return ::getBranchTargetOpValue(MI, OpIdx,
|
||||||
|
ARM::fixup_arm_condbl, Fixups);
|
||||||
|
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups);
|
||||||
|
}
|
||||||
|
|
||||||
return MO.getImm() >> 2;
|
return MO.getImm() >> 2;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,8 @@ static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType,
|
|||||||
case ARM::fixup_arm_adr_pcrel_12:
|
case ARM::fixup_arm_adr_pcrel_12:
|
||||||
case ARM::fixup_arm_condbranch:
|
case ARM::fixup_arm_condbranch:
|
||||||
case ARM::fixup_arm_uncondbranch:
|
case ARM::fixup_arm_uncondbranch:
|
||||||
case ARM::fixup_arm_bl:
|
case ARM::fixup_arm_uncondbl:
|
||||||
|
case ARM::fixup_arm_condbl:
|
||||||
case ARM::fixup_arm_blx:
|
case ARM::fixup_arm_blx:
|
||||||
RelocType = unsigned(macho::RIT_ARM_Branch24Bit);
|
RelocType = unsigned(macho::RIT_ARM_Branch24Bit);
|
||||||
// Report as 'long', even though that is not quite accurate.
|
// Report as 'long', even though that is not quite accurate.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
bl _printf
|
bl _printf
|
||||||
@ CHECK: bl _printf @ encoding: [A,A,A,0xeb]
|
@ CHECK: bl _printf @ encoding: [A,A,A,0xeb]
|
||||||
@ CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_bl
|
@ CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_uncondbl
|
||||||
|
|
||||||
mov r9, :lower16:(_foo)
|
mov r9, :lower16:(_foo)
|
||||||
movw r9, :lower16:(_foo)
|
movw r9, :lower16:(_foo)
|
||||||
|
@ -382,13 +382,16 @@ Lforward:
|
|||||||
@------------------------------------------------------------------------------
|
@------------------------------------------------------------------------------
|
||||||
|
|
||||||
bl _bar
|
bl _bar
|
||||||
|
bleq _bar
|
||||||
blx _bar
|
blx _bar
|
||||||
blls #28634268
|
blls #28634268
|
||||||
blx #32424576
|
blx #32424576
|
||||||
blx #16212288
|
blx #16212288
|
||||||
|
|
||||||
@ CHECK: bl _bar @ encoding: [A,A,A,0xeb]
|
@ CHECK: bl _bar @ encoding: [A,A,A,0xeb]
|
||||||
@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_bl
|
@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbl
|
||||||
|
@ CHECK: bleq _bar @ encoding: [A,A,A,0x0b]
|
||||||
|
@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_condbl
|
||||||
@ CHECK: blx _bar @ encoding: [A,A,A,0xfa]
|
@ CHECK: blx _bar @ encoding: [A,A,A,0xfa]
|
||||||
@ fixup A - offset: 0, value: _bar, kind: fixup_arm_blx
|
@ fixup A - offset: 0, value: _bar, kind: fixup_arm_blx
|
||||||
@ CHECK: blls #28634268 @ encoding: [0x27,0x3b,0x6d,0x9b]
|
@ CHECK: blls #28634268 @ encoding: [0x27,0x3b,0x6d,0x9b]
|
||||||
|
23
test/MC/ARM/elf-reloc-condcall.s
Normal file
23
test/MC/ARM/elf-reloc-condcall.s
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// RUN: llvm-mc -triple=armv7-linux-gnueabi -filetype=obj %s -o - | \
|
||||||
|
// RUN: elf-dump | FileCheck -check-prefix=OBJ %s
|
||||||
|
|
||||||
|
bleq some_label
|
||||||
|
bl some_label
|
||||||
|
blx some_label
|
||||||
|
// OBJ: .rel.text
|
||||||
|
|
||||||
|
// OBJ: 'r_offset', 0x00000000
|
||||||
|
// OBJ-NEXT: 'r_sym', 0x000004
|
||||||
|
// OBJ-NEXT: 'r_type', 0x1d
|
||||||
|
|
||||||
|
// OBJ: 'r_offset', 0x00000004
|
||||||
|
// OBJ-NEXT: 'r_sym', 0x000004
|
||||||
|
// OBJ-NEXT: 'r_type', 0x1c
|
||||||
|
|
||||||
|
// OBJ: 'r_offset', 0x00000008
|
||||||
|
// OBJ-NEXT: 'r_sym', 0x000004
|
||||||
|
// OBJ-NEXT: 'r_type', 0x1c
|
||||||
|
|
||||||
|
// OBJ: .symtab
|
||||||
|
// OBJ: Symbol 4
|
||||||
|
// OBJ-NEXT: some_label
|
Loading…
x
Reference in New Issue
Block a user