You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[aaelf64][pauthabi64] Remove addend in GDAT relocation operation
The GDAT(S + A) relocation operation requires a static linker to
create a GOT entry for (S + A). Requiring at least one GOT entry
for each unique tuple (S, A). Unfortunately no known static linker
has implemented this correctly, with one of two forms being
implemented instead:
* GDAT(S) with the addend ignored.
* GDAT(S) + A with a single GOT entry per S, and A added to the
value of GDAT(S).
These implementations are correct and consistent only for an
addend (A) of zero.
No known compiler uses non-zero addends in relocations that use
the GDAT(S+A) operation, although it is possible to generate
them using assembly language.
This change synchronizes the ABI with the behavior of existing
static linker implementations. The benefit of permitting code
generators [*] to use a non zero addend in GDAT(S + A) is judged
to be lower than implementing GDAT(S + A) correctly in existing
static linkers, many of which assume that there is a single
GOT entry per unique symbol S.
It is QoI whether a static linker gives an error if a non zero
addend is used for a relocation that uses the GDAT(S) operation.
FixesARM-software#217
Also resolvesARM-software#247
[*] The most common use case for a non-zero addend is in
constructing a C++ object with a vtable. The first two entries
in the vtable are the offset to top and a pointer to RTTI, the
vtable pointer in the object starts at offset 0x10. This offset
can be encoded in the relocation addend. We would save an add
instruction for each construction of a C++ object with a vtable
if addends were permitted.
Copy file name to clipboardExpand all lines: aaelf64/aaelf64.rst
+16-15Lines changed: 16 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1027,6 +1027,7 @@ In ELF32 **(Beta)** relocations additional care must be taken when relocating an
1027
1027
R_<CLS>_TLSIE_ADR_GOTTPREL_PAGE21,
1028
1028
R_<CLS>_TLSDESC_ADR_PAGE21
1029
1029
1030
+
Relocations using the ``GDAT(S)`` operation must have a zero addend. Previous versions of this document included the addend ``A`` in ``GDAT(S + A)`` resulting in a GOT entry for ``S + A``. With a zero addend ``GDAT(S + 0)`` is equivalent to ``GDAT(S)`` and ``GDAT(S) + 0``.
1030
1031
1031
1032
Static miscellaneous relocations
1032
1033
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1231,19 +1232,19 @@ The following tables record single instruction relocations and relocations that
@@ -1265,7 +1266,7 @@ The following tables record single instruction relocations and relocations that
1265
1266
| 308 |\-| R\_<CLS>\_GOTREL32 | S+A-GOT | Write bits [31:0] of X at byte-aligned place P. This represents a 32-bit offset relative to GOT, treated as signed; |
1266
1267
||||| Check that -2\ :sup:`31` <= X < 2\ :sup:`31`. |
| 315 |\-| R\_<CLS>\_GOTPCREL32 | G(GDAT(S+A))- P | Write bits [31:0] of X at byte-aligned place P. This represents a 32-bit offset relative to GOT entry for an address, |
1269
+
| 315 |\-| R\_<CLS>\_GOTPCREL32 | G(GDAT(S))- P| Write bits [31:0] of X at byte-aligned place P. This represents a 32-bit offset relative to GOT entry for an address, |
1269
1270
||||| treated as signed; Check that -2\ :sup:`31` <= X < 2\ :sup:`31`. |
| 309 | 25 | R\_<CLS>\_GOT\_LD\_PREL19 | G(GDAT(S+A))- P | Set a load-literal immediate field to bits [20:2] of X; check –2\ :sup:`20` <= X < 2\ :sup:`20` |
1282
+
| 309 | 25 | R\_<CLS>\_GOT\_LD\_PREL19 | G(GDAT(S))- P| Set a load-literal immediate field to bits [20:2] of X; check –2\ :sup:`20` <= X < 2\ :sup:`20` |
| 310 |\-| R\_<CLS>\_LD64\_GOTOFF\_LO15 | G(GDAT(S+A))- GOT | Set a LD/ST immediate field to bits [14:3] of X; check that 0 <= X < 2\ :sup:`15`, X&7 = 0 |
1284
+
| 310 |\-| R\_<CLS>\_LD64\_GOTOFF\_LO15 | G(GDAT(S))- GOT| Set a LD/ST immediate field to bits [14:3] of X; check that 0 <= X < 2\ :sup:`15`, X&7 = 0 |
| 311 | 26 | R\_<CLS>\_ADR\_GOT\_PAGE | Page(G(GDAT(S+A)))-Page(P) | Set the immediate value of an ADRP to bits [32:12] of X; check that –2\ :sup:`32` <= X < 2\ :sup:`32`|
1286
+
| 311 | 26 | R\_<CLS>\_ADR\_GOT\_PAGE | Page(G(GDAT(S)))-Page(P)| Set the immediate value of an ADRP to bits [32:12] of X; check that –2\ :sup:`32` <= X < 2\ :sup:`32`|
| 313 |\-| R\_<CLS>\_LD64\_GOTPAGE\_LO15 | G(GDAT(S+A))-Page(GOT) | Set the LD/ST immediate field to bits [14:3] of X; check that 0 <= X < 2\ :sup:`15`, X&7 = 0 |
1292
+
| 313 |\-| R\_<CLS>\_LD64\_GOTPAGE\_LO15 | G(GDAT(S))-Page(GOT)| Set the LD/ST immediate field to bits [14:3] of X; check that 0 <= X < 2\ :sup:`15`, X&7 = 0 |
|\-| 28 | R\_<CLS>\_LD32\_GOTPAGE\_LO14 | G(GDAT(S+A))-Page(GOT) | Set the LD/ST immediate field to bits [13:2] of X; check that 0 <= X < 2\ :sup:`14`, X&3 = 0 |
1294
+
|\-| 28 | R\_<CLS>\_LD32\_GOTPAGE\_LO14 | G(GDAT(S))-Page(GOT)| Set the LD/ST immediate field to bits [13:2] of X; check that 0 <= X < 2\ :sup:`14`, X&3 = 0 |
0 commit comments