[llvm-commits] [PATCH] ARM: conditional BL should use fixup_arm_condbranch
Måns Rullgård
mans at mansr.com
Thu Mar 22 17:04:52 PDT 2012
Jim Grosbach <grosbach at apple.com> writes:
> Hi Mans,
>
> Sorry for the previous terseness. What I get for replying when I'm in
> a hurry. I phrased things poorly and probably implied a bit of a
> different issue than I intended.
>
> The way this works is that the fixups direct the behavior of the
> encoder and when different encoding is required, be it bit twiddling
> or a different relocation, a different fixup is used. Typically this
> sort of thing is platform agnostic so we can use the same fixups for
> each. In this case, however, we're not so lucky. What we want to do is
> check the platform in the encoder and select the appropriate
> fixup. That will then allow the ELFObjectWriter and the
> MachObjectWriter to do the correct platform specific thing.
>
> FWIW, the Darwin problem with using a conditional branch fixup is that
> Darwin relies on a relocation to get interworking correct, and
> conditional fixups can (and do) get resolved statically by the
> assembler. The result is an incorrect mode switch in tail-recursive
> functions.
In my case, the branch could have been resolved statically, but the ELF
object writer emitted an R_ARM_CALL relocation anyway, which confused
the GNU linker. ELF relocations of calls and jumps are perhaps best
described by the spec:
There is one relocation (R_ARM_CALL) for unconditional function call
instructions (BLX and BL with the condition field set to 0xe), and one
for jump instructions (R_ARM_JUMP24). The principal difference between
the two relocation values is the handling of ARM/Thumb interworking:
on ARM architecture 5 and above, an instruction relocated by
R_ARM_CALL that calls a function that is entered in Thumb state may be
relocated by changing the instruction to BLX; an instruction relocated
by R_ARM_JUMP24 must use a veneer to effect the transition to Thumb
state. Conditional function call instructions (BL<cond>) must be
relocated using R_ARM_JUMP24.
This means we need to distinguish between two classes of branch
relocations:
- Unconditional immediate calls, which can be fully handled by exchanging
the BL instruction for a BLX if a mode switch is
required. (R_ARM_CALL)
- Non-call branches and conditional immediate calls, which require a
veneer for mode switching. (R_ARM_JUMP24)
By using the same fixup kind for both, the distinction is lost in the
object writers. Perhaps adding another fixup kind for conditional calls
(fixup_arm_condbl?) would be a solution. The Mach-o writer could handle
this identically to fixup_arm_bl, while the ELF writer would select the
appropriate relocation type. To me this seems cleaner than littering
the otherwise generic code emitter with platform-specifics.
--
Måns Rullgård
mans at mansr.com
More information about the llvm-commits
mailing list