Hi Richard,
As you might know, Richard Earnshaw, maintainer of "ELF for the ARM Architecture" is currently on sabbatical and does not return until the end of February. I note that nobody else on arm.eabi has picked up the baton ... :-) so ...
I don't fully understand your request. You need to assume that I know nothing at all about either Linux or GCC (not quite true, but a good starting point :-)). In particular, details need to be spelled out without recourse to "standard" (for Linux/GCC) terminology. Sorry. However, this mail might give you what you need without further explanation.
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).
The name of the relocation is merely a convention. R_ARM_IRELATIVE is as good as any.
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.
To allocate a code I don't need to understand its meaning. Richard and I will need to understand that before the next documentation update but I suspect Richard already understand it. :-) However, I really don't understand your explanation of call(B(S) + A). You state below:
An R_ARM_IRELATIVE relocation applies to all bits of a 4-byte field. There are no alignment restrictions on the field.
Yes, no problem, that's usual for ARM relocation directives.
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 ...
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:
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.
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.
Pro tem I suggest you use relocation number 16. If that causes you any problem please mail me again and I'll find an alternative in the space 140-159.
Kind regards,
Lee
-- Lee Smith, ARM Fellow and Director of Technology, SDD ARM Limited 110 Fulbourn Road Cambridge CB1 9NJ UK
-----Original Message----- From: Richard Sandiford [mailto:richard.sandiford@linaro.org] Sent: 04 February 2011 12:34 To: arm.eabi Cc: linaro-toolchain@lists.linaro.org Subject: Request for new relocation: R_ARM_IRELATIVE
Hi,
I'm working in the Linaro toolchain team on adding ARM support for GNU indirect functions (STT_GNU_IFUNCs). The indirect function feature requires a new relocation type, which is typically called R_FOO_IRELATIVE. I'd therefore like to propose a new R_ARM_IRELATIVE relocation type for the ARM EABI.
This relocation is only used in ET_EXEC and ET_DYN objects. If the object has a PT_DYNAMIC tag, then the relocation may only appear in the DT_REL(A) table; it cannot appear in the DT_JMPREL table. (Note that this is a deliberate divergence from the x86 and x86_64 behaviour, which does allow the IRELATIVE relocation to be used in DT_JMPREL table, but which requires it to be applied at load time, regardless of bind-now vs. lazy semantics. However, the proposed ARM behaviour matches that of other targets like PowerPC.)
Static ET_EXEC objects may have R_ARM_IRELATIVE relocations. In this case, the relocations are stored in a relocation table that contains no other type of relocation (not even R_ARM_NONE). The static linker defines two symbols:
__rel_iplt_start, which the linker points to the start of this table __rel_iplt_end, which the linker points to the last byte of this table plus one.
The two symbols are equal if the executable has no R_ARM_IRELATIVE relocations. It is the executable's responsibility to apply these relocations as appropriate. If the static linker emits a symbol table, then it is not defined whether the linker includes __rel_iplt_start and __rel_iplt_end in that symbol table.
The static linker may (or may not) define __rel_iplt_start and __rel_iplt_end in dynamic objects. However, if it does define them, the symbols must refer to part of the DT_REL(A) table, and it is still the dynamic linker's responsibility to apply the relocations.
An R_ARM_IRELATIVE relocation applies to all bits of a 4-byte field. There are no alignment restrictions on the field. 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.
The dynamic linker must have applied all earlier DT_REL(A) relocations before calling X. It is undefined whether later DT_REL(A) relocations have been applied or not, and X must not make any assumptions about the status of those relocations.
If there is an R_ARM_IRELATIVE relocation with symbol S and addend A, then the relocation value:
call(B(S) + A)
is considered to be a load-time constant. It is possible for an object to have more than one R_ARM_IRELATIVE relocation with the same value of B(S) + A, and in such a case, it is not defined whether the dynamic linker invokes the target function each time, or whether it caches the results of earlier calls.
I realise this isn't the cleanest extension in the world. As Alan Modra noted on the binutils list, the choice of __rel_iplt_start and __rel_iplt_end is particularly unfortunate, since the relocations are not specific to "PLTs". However, the GNU extension has been defined this way, so unfortunately there isn't much room for target-specific variation.
Thanks, Richard
-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.