[PATCH] D33280: [LLD][ELF] Support R_ARM_SBREL32 Relocation

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed May 17 22:29:00 PDT 2017


LGTM with a short summary of the explanation as a comment.

Cheers,
Rafael


Peter Smith <peter.smith at linaro.org> writes:

> The TL;DR answer is that only RW symbols are used in the ABI defined
> RWPI variant of the procedure calling standard [*].
>
> In theory the R_ARM_SBREL32 relocation can use RO symbols as the
> official ABI definition of B is loose.
> "B(S) is the addressing origin of the output segment defining the
> symbol S. The origin is not required to be the base address of the
> segment. This value must always be word-aligned."
>
> In the way  R_ARM_SBREL32 is used as part of -frwpi it only uses RW
> symbols (RWPI = Read Write Position Independent). There is another
> option -fropi (ROPI Read Only Position Independent) that addresses
> read only data via an offset from the PC, this requires the code and
> read-only data to be in the same PT_LOAD segment. This is covered a
> bit more in the original RFC
> http://lists.llvm.org/pipermail/llvm-dev/2015-December/093022.html
>
> There are a couple of ways I've seen multiple bases be supported,
> either for RO or RW. Both require additional compiler support and
> involve either reserving another base register for RO or have the
> first data member of RW contain an indirection table to another base.
> These were both custom toolchain options and not part of the ABI.
>
> [*] The ARM procedure call standard only defines RWPI
> 6.3 Read-Write Position Independence (RWPI)
> Code compiled or assembled for execution environments that require
> read-write position independence (for example, the single
> address-space DLL-like model) use a static base to address writable
> data. Core register r9 is renamed as SB and used to hold the static
> base address: consequently this register may not be used for holding
> other values at any time
> [Although not mandated by this standard, compilers usually formulate
> the address of a static datum by loading the offset of the datum from
> SB, and adding SB to it. Usually, the offset is a 32-bit value loaded
> PC-relative from a literal pool. Usually, the literal value is subject
> to R_ARM_SBREL32-type relocation at static link time. The offset of a
> datum from SB is clearly a
> property of the layout of an executable, which is fixed at static link
> time. It does not depend on where the data is loaded, which is
> captured by the value of SB at run time. ]
>
>
>
> On 17 May 2017 at 18:05, Rafael Avila de Espindola
> <rafael.espindola at gmail.com> wrote:
>> Peter Smith via Phabricator <reviews at reviews.llvm.org> writes:
>>
>>> peter.smith created this revision.
>>> Herald added subscribers: javed.absar, emaste, rengolin, aemerson.
>>>
>>> This change adds support for the R_ARM_SBREL32 relocation. The relocation is a base relative relocation that is produced by clang/llvm when -frwpi is used. The use case for the -frwpi option is position independent data for embedded systems that do not have a GOT. With -frwpi all read-write data is accessed via an offset from a base register (usually r9), where r9 is set at run time to where the RW data has been loaded. The base of the RW data is known as the static base.
>>>
>>> Resolving the relocation is simple it is (S + A) - B where B is the static base. Choosing the location of and obtaining the value of the static base is more complicated. For lld I have chosen to use the base of the program segment containing the RW to be the static base. This supports the most common use case where there is a single PT_LOAD segment for the data.
>>
>> If the assembly has
>>
>>       .long   ro_symbol(sbrel)
>>       .long   rw_symbol(sbrel)
>>
>> How does the program know at runtime to use a different base for each?
>> Or it is just not valid to use sbrel with ro symbols?
>>
>> Cheers,
>> Rafael


More information about the llvm-commits mailing list