llvm.org GIT mirror llvm / cb0809b
Ensure conditional BL instructions for ARM are given the fixup fixup_arm_condbranch. Patch by Tim Northover! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153737 91177308-0d34-0410-b5e6-96231b3b80d8 James Molloy 8 years ago
8 changed file(s) with 61 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
7777 { "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
7878 { "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
7979 { "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
80 { "fixup_arm_bl", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
80 { "fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
81 { "fixup_arm_condbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
8182 { "fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
8283 { "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
8384 { "fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
127128 if (A && ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_blx ||
128129 (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl ||
129130 (unsigned)Fixup.getKind() == ARM::fixup_arm_blx ||
130 (unsigned)Fixup.getKind() == ARM::fixup_arm_bl))
131 (unsigned)Fixup.getKind() == ARM::fixup_arm_uncondbl ||
132 (unsigned)Fixup.getKind() == ARM::fixup_arm_condbl))
131133 IsResolved = false;
132134 }
133135
365367
366368 case ARM::fixup_arm_condbranch:
367369 case ARM::fixup_arm_uncondbranch:
368 case ARM::fixup_arm_bl:
370 case ARM::fixup_arm_uncondbl:
371 case ARM::fixup_arm_condbl:
369372 case ARM::fixup_arm_blx:
370373 // These values don't encode the low two bits since they're always zero.
371374 // Offset by 8 just as above.
576579 case ARM::fixup_arm_ldst_pcrel_12:
577580 case ARM::fixup_arm_pcrel_10:
578581 case ARM::fixup_arm_adr_pcrel_12:
579 case ARM::fixup_arm_bl:
582 case ARM::fixup_arm_uncondbl:
583 case ARM::fixup_arm_condbl:
580584 case ARM::fixup_arm_blx:
581585 case ARM::fixup_arm_condbranch:
582586 case ARM::fixup_arm_uncondbranch:
177177 break;
178178 }
179179 break;
180 case ARM::fixup_arm_bl:
180 case ARM::fixup_arm_uncondbl:
181181 case ARM::fixup_arm_blx:
182182 case ARM::fixup_arm_uncondbranch:
183183 switch (Modifier) {
189189 break;
190190 }
191191 break;
192 case ARM::fixup_arm_condbl:
192193 case ARM::fixup_arm_condbranch:
193194 Type = ELF::R_ARM_JUMP24;
194195 break;
5858 // fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions.
5959 fixup_arm_thumb_br,
6060
61 // fixup_arm_bl - Fixup for ARM BL instructions.
62 fixup_arm_bl,
61 // The following fixups handle the ARM BL instructions. These can be
62 // conditionalised; however, the ARM ELF ABI requires a different relocation
63 // in that case: R_ARM_JUMP24 instead of R_ARM_CALL. The difference is that
64 // R_ARM_CALL is allowed to change the instruction to a BLX inline, which has
65 // no conditional version; R_ARM_JUMP24 would have to insert a veneer.
66 //
67 // MachO does not draw a distinction between the two cases, so it will treat
68 // fixup_arm_uncondbl and fixup_arm_condbl as identical fixups.
69
70 // fixup_arm_uncondbl - Fixup for unconditional ARM BL instructions.
71 fixup_arm_uncondbl,
72
73 // fixup_arm_condbl - Fixup for ARM BL instructions with nontrivial
74 // conditionalisation.
75 fixup_arm_condbl,
6376
6477 // fixup_arm_blx - Fixup for ARM BLX instructions.
6578 fixup_arm_blx,
596596 getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
597597 SmallVectorImpl &Fixups) const {
598598 const MCOperand MO = MI.getOperand(OpIdx);
599 if (MO.isExpr())
600 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_bl, Fixups);
599 if (MO.isExpr()) {
600 if (HasConditionalBranch(MI))
601 return ::getBranchTargetOpValue(MI, OpIdx,
602 ARM::fixup_arm_condbl, Fixups);
603 return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups);
604 }
601605
602606 return MO.getImm() >> 2;
603607 }
8181 case ARM::fixup_arm_adr_pcrel_12:
8282 case ARM::fixup_arm_condbranch:
8383 case ARM::fixup_arm_uncondbranch:
84 case ARM::fixup_arm_bl:
84 case ARM::fixup_arm_uncondbl:
85 case ARM::fixup_arm_condbl:
8586 case ARM::fixup_arm_blx:
8687 RelocType = unsigned(macho::RIT_ARM_Branch24Bit);
8788 // Report as 'long', even though that is not quite accurate.
22
33 bl _printf
44 @ CHECK: bl _printf @ encoding: [A,A,A,0xeb]
5 @ CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_bl
5 @ CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_uncondbl
66
77 mov r9, :lower16:(_foo)
88 movw r9, :lower16:(_foo)
381381 @------------------------------------------------------------------------------
382382
383383 bl _bar
384 bleq _bar
384385 blx _bar
385386 blls #28634268
386387 blx #32424576
387388 blx #16212288
388389
389390 @ CHECK: bl _bar @ encoding: [A,A,A,0xeb]
390 @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_bl
391 @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbl
392 @ CHECK: bleq _bar @ encoding: [A,A,A,0x0b]
393 @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_condbl
391394 @ CHECK: blx _bar @ encoding: [A,A,A,0xfa]
392395 @ fixup A - offset: 0, value: _bar, kind: fixup_arm_blx
393396 @ CHECK: blls #28634268 @ encoding: [0x27,0x3b,0x6d,0x9b]
0 // RUN: llvm-mc -triple=armv7-linux-gnueabi -filetype=obj %s -o - | \
1 // RUN: elf-dump | FileCheck -check-prefix=OBJ %s
2
3 bleq some_label
4 bl some_label
5 blx some_label
6 // OBJ: .rel.text
7
8 // OBJ: 'r_offset', 0x00000000
9 // OBJ-NEXT: 'r_sym', 0x000004
10 // OBJ-NEXT: 'r_type', 0x1d
11
12 // OBJ: 'r_offset', 0x00000004
13 // OBJ-NEXT: 'r_sym', 0x000004
14 // OBJ-NEXT: 'r_type', 0x1c
15
16 // OBJ: 'r_offset', 0x00000008
17 // OBJ-NEXT: 'r_sym', 0x000004
18 // OBJ-NEXT: 'r_type', 0x1c
19
20 // OBJ: .symtab
21 // OBJ: Symbol 4
22 // OBJ-NEXT: some_label