Skip to content

Commit ed94f78

Browse files
committed
[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. Fixes ARM-software#217 Also resolves ARM-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.
1 parent f14c8ff commit ed94f78

File tree

2 files changed

+30
-29
lines changed

2 files changed

+30
-29
lines changed

aaelf64/aaelf64.rst

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,7 @@ In ELF32 **(Beta)** relocations additional care must be taken when relocating an
10271027
R_<CLS>_TLSIE_ADR_GOTTPREL_PAGE21,
10281028
R_<CLS>_TLSDESC_ADR_PAGE21
10291029

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``.
10301031

10311032
Static miscellaneous relocations
10321033
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1231,19 +1232,19 @@ The following tables record single instruction relocations and relocations that
12311232
+------------+------------+--------------------------------+-------------------+----------------------------------------------------------------------+
12321233
| ELF64 Code | ELF32 Code | Name | Operation | Comment |
12331234
+============+============+================================+===================+======================================================================+
1234-
| 300 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G0 | G(GDAT(S+A)) -GOT | Set a MOV[NZ] immediate field to bits [15:0] of X (see notes below) |
1235+
| 300 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G0 | G(GDAT(S)) -GOT | Set a MOV[NZ] immediate field to bits [15:0] of X (see notes below) |
12351236
+------------+------------+--------------------------------+-------------------+----------------------------------------------------------------------+
1236-
| 301 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G0\_NC | G(GDAT(S+A)) -GOT | Set a MOVK immediate field to bits [15:0] of X. No overflow check |
1237+
| 301 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G0\_NC | G(GDAT(S)) -GOT | Set a MOVK immediate field to bits [15:0] of X. No overflow check |
12371238
+------------+------------+--------------------------------+-------------------+----------------------------------------------------------------------+
1238-
| 302 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G1 | G(GDAT(S+A)) -GOT | Set a MOV[NZ] immediate value to bits [31:16] of X (see notes below) |
1239+
| 302 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G1 | G(GDAT(S)) -GOT | Set a MOV[NZ] immediate value to bits [31:16] of X (see notes below) |
12391240
+------------+------------+--------------------------------+-------------------+----------------------------------------------------------------------+
1240-
| 303 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G1\_NC | G(GDAT(S+A)) -GOT | Set a MOVK immediate value to bits [31:16] of X. No overflow check |
1241+
| 303 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G1\_NC | G(GDAT(S)) -GOT | Set a MOVK immediate value to bits [31:16] of X. No overflow check |
12411242
+------------+------------+--------------------------------+-------------------+----------------------------------------------------------------------+
1242-
| 304 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G2 | G(GDAT(S+A)) -GOT | Set a MOV[NZ] immediate value to bits [47:32] of X (see notes below) |
1243+
| 304 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G2 | G(GDAT(S)) -GOT | Set a MOV[NZ] immediate value to bits [47:32] of X (see notes below) |
12431244
+------------+------------+--------------------------------+-------------------+----------------------------------------------------------------------+
1244-
| 305 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G2\_NC | G(GDAT(S+A)) -GOT | Set a MOVK immediate value to bits [47:32] of X. No overflow check |
1245+
| 305 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G2\_NC | G(GDAT(S)) -GOT | Set a MOVK immediate value to bits [47:32] of X. No overflow check |
12451246
+------------+------------+--------------------------------+-------------------+----------------------------------------------------------------------+
1246-
| 306 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G3 | G(GDAT(S+A)) -GOT | Set a MOV[NZ] immediate value to bits [63:48] of X (see notes below) |
1247+
| 306 | \- | R\_<CLS>\_MOVW\_GOTOFF\_G3 | G(GDAT(S)) -GOT | Set a MOV[NZ] immediate value to bits [63:48] of X (see notes below) |
12471248
+------------+------------+--------------------------------+-------------------+----------------------------------------------------------------------+
12481249

12491250
.. note::
@@ -1265,7 +1266,7 @@ The following tables record single instruction relocations and relocations that
12651266
| 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; |
12661267
| | | | | Check that -2\ :sup:`31` <= X < 2\ :sup:`31`. |
12671268
+------------+------------+----------------------+------------------+-------------------------------------------------------------------------------------------------------------------------+
1268-
| 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, |
12691270
| | | | | treated as signed; Check that -2\ :sup:`31` <= X < 2\ :sup:`31`. |
12701271
+------------+------------+----------------------+------------------+-------------------------------------------------------------------------------------------------------------------------+
12711272

@@ -1278,19 +1279,19 @@ The following tables record single instruction relocations and relocations that
12781279
+-------------+------------+-------------------------------+----------------------------+------------------------------------------------------------------------------------------------------+
12791280
| ELF64 Code | ELF32 Code | Name | Operation | Comment |
12801281
+=============+============+===============================+============================+======================================================================================================+
1281-
| 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` |
12821283
+-------------+------------+-------------------------------+----------------------------+------------------------------------------------------------------------------------------------------+
1283-
| 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 |
12841285
+-------------+------------+-------------------------------+----------------------------+------------------------------------------------------------------------------------------------------+
1285-
| 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`|
12861287
+-------------+------------+-------------------------------+----------------------------+------------------------------------------------------------------------------------------------------+
1287-
| 312 | \- | R\_<CLS>\_LD64\_GOT\_LO12\_NC | G(GDAT(S+A)) | Set the LD/ST immediate field to bits [11:3] of X. No overflow check; check that X&7 = 0 |
1288+
| 312 | \- | R\_<CLS>\_LD64\_GOT\_LO12\_NC | G(GDAT(S)) | Set the LD/ST immediate field to bits [11:3] of X. No overflow check; check that X&7 = 0 |
12881289
+-------------+------------+-------------------------------+----------------------------+------------------------------------------------------------------------------------------------------+
1289-
| \- | 27 | R\_<CLS>\_LD32\_GOT\_LO12\_NC | G(GDAT(S+A)) | Set the LD/ST immediate field to bits [11:2] of X. No overflow check; check that X&3 = 0 |
1290+
| \- | 27 | R\_<CLS>\_LD32\_GOT\_LO12\_NC | G(GDAT(S)) | Set the LD/ST immediate field to bits [11:2] of X. No overflow check; check that X&3 = 0 |
12901291
+-------------+------------+-------------------------------+----------------------------+------------------------------------------------------------------------------------------------------+
1291-
| 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 |
12921293
+-------------+------------+-------------------------------+----------------------------+------------------------------------------------------------------------------------------------------+
1293-
| \- | 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 |
12941295
+-------------+------------+-------------------------------+----------------------------+------------------------------------------------------------------------------------------------------+
12951296

12961297

0 commit comments

Comments
 (0)