Hi Lee,
Thanks for the reply.
Lee Smith Lee.Smith@arm.com writes:
To the extent that I do understand your request I think you are asking for one new _dynamic relocation_ code to be allocated. (A dynamic relocation is one that is usually performed by a dynamic linker (because, for example, the referred-to symbol is not available until load time). A static linker is not forbidden from performing - or partly performing and re-writing - a dynamic relocation emitted by a compiler or assembler).
That's right, it's a dynamic relocation. The reason I waffled on about ET_* types was that, in contrast to all other dynamic relocations, these relocations are also used in static executables (i.e. those that are not processed by a dynamic linker/loader). It is then the executable's responsibility to apply the relocations to itself.
For now I have assumed that you do not need R_ARM_THM_IRELATIVE - this relocation does not relocate instructions (such being anathema to Linux loaders) so it does not depend on the instruction set in any way. In common with most dynamic relocations this one relocates data.
Right. The point about it applying to all bits of a 4-byte field was that, like R_ARM_RELATIVE, this is a data rather than an instruction relocation.
The relocation value is:
call(B(S) + A)
where call(X) represents the value of r0 after performing an indirect branch-with-link-and-exchange (BLX) to address X.
So, firstly, this relocation ONLY applies to calls between ARM state and Thumb state and vice versa (BLX)? That seems very odd ... I hope you intend BL not BLX ...
Sorry, by "indirect", I meant "via a register". The dynamic linker loads B(S) + A into a register and executes a BLX to that address.
Secondly, the value of r0 after the BLX is whatever it was before the BLX! BL[X] rd writes r14, not r0. The destination address can be in any register rd. So how should I interpret this? I think (hope) you mean:
I mean the target of the called function (B(S) + A) returns the final relocation value in r0. So the dynamic linker does:
mov B(S) + A,rX blx rX ...relocation value is now in r0...
The relocation value is (in ARM terminology) (B(S) + A) | T where:
- B(S) is the origin of the segment in which symbol S is defined. ("Origin" is whatever the loader and static linker agree it is - perhaps the base address, perhaps not).
- A is the addend - a byte offset within the segment.
- T is the Thumb bit - 1 if S is of type STT_FUNC and defines a Thumb code address.
I'm not sure about including the thumb bit. R_ARM_IRELATIVE is supposed to be R_ARM_RELATIVE with an extra call "tacked on" at the end. Since R_ARM_RELATIVE doesn't include the thumb bit, I thought it was more consistent to leave it out here too.
It doesn't matter much either way in practice. The relocation is only going to be used with symbol 0.
The call part of the relocation value is the important part. Since the current EABI spec (wisely) has no equivalent of the "call()" operation, I had to invent it as part of this submission. :-)
Anyway ... Possible misunderstandings aside, I would propose to allocate relocation number 16. That's reserved for future dynamic relocations. It was briefly defined as R_ARM_THM_XPC22 and AFAIK never used by anybody.
Although it's marked as obselete, binutils does still process R_ARM_THM_XPC22. I could remove that support, but maybe it would be worth considering a relocation that hasn't been used in other ways?
Thanks, Richard