From fb837c648cfff182c4d1e4b9514ece206b3fa7d2 Mon Sep 17 00:00:00 2001 From: Xi Ruoyao Date: Mon, 25 Jul 2022 14:22:58 +0800 Subject: [PATCH] fix the detail for PC-relative relocations and add explanation In the BFD code (under review now), we have: #define RELOCATE_CALC_PC32_HI20(relocation, pc) \ ({ \ bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \ pc = pc & (~(bfd_vma)0xfff); \ if (lo > 0x7ff) \ { \ relocation += 0x1000; \ } \ relocation &= ~(bfd_vma)0xfff; \ relocation -= pc; \ }) #define RELOCATE_CALC_PC64_HI32(relocation, pc) \ ({ \ bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \ if (lo > 0x7ff) \ { \ relocation -= 0x100000000; \ } \ relocation -= (pc & ~(bfd_vma)0xffffffff); \ }) Pay attention at `relocation += 0x1000` and `relocation -= 0x100000000`. Currently our detailed description does not strictly match it. This will puzzle the engineer implementing or reviewing the relocs for other linkers (gold/lld/mold) and cause we criticized by the upstream reviewers. Fix the pseudo-code in the "detail" column and add two footnotes as explanation about why the additional operation is needed. --- docs/LoongArch-ELF-ABI-CN.adoc | 24 +++++++++++++----------- docs/LoongArch-ELF-ABI-EN.adoc | 27 ++++++++++++++++----------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/docs/LoongArch-ELF-ABI-CN.adoc b/docs/LoongArch-ELF-ABI-CN.adoc index da43fb8..e139a9b 100644 --- a/docs/LoongArch-ELF-ABI-CN.adoc +++ b/docs/LoongArch-ELF-ABI-CN.adoc @@ -698,7 +698,8 @@ v2.00 |71 |R_LARCH_PCALA_HI20 |相对 PC 偏移 32/64 位的 [31 ... 12] 位 -|`+(*(uint32_t *) PC) [24 ... 5] = (((S+A) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = ((hi20(S+A) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[`hi20(x)` 定义为 `(x + 0x800) & ~0xfff`。`+ 0x800` +使得结果能够和视为 12 位带符号数的 `x & 0xfff` 相加。] `+注意:所有相对 PC 偏移计算都不包含低12位。+` @@ -710,17 +711,18 @@ v2.00 |73 |R_LARCH_PCALA64_LO20 |相对 PC 偏移 64 位的 [51 ... 32] 位 -|`+(*(uint32_t *) PC) [24 ... 5] = (S+A - (PC & ~0xffffffff)) [51 ... 32]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi32(S+A) - (PC & ~0xffffffff)) [51 ... 32]+` footnote:foot_hi32[`hi32(x)` 定义为 `x - ((x & 0x800) << 21)`。`-((x & 0x800) << 21)` 使得结果能够和 `x & 0xfff` 视为 12 位带符号数并扩展到 32 +位的结果,以及 `hi20(x)` 相加。] |74 |R_LARCH_PCALA64_HI12 |相对 PC 偏移 64 位的 [63 ... 52] 位 -|`+(*(uint32_t *) PC) [21 ... 10] = (S+A - (PC & ~0xffffffff)) [63 ... 52]+` +|`+(*(uint32_t *) PC) [21 ... 10] = (hi32(S+A) - (PC & ~0xffffffff)) [63 ... 52]+` footnote:foot_hi32[] |75 |R_LARCH_GOT_PC_HI20 |GOT 表项相对 PC 偏移 32/64 位的 [31 ... 12] 位 -|`+(*(uint32_t *) PC) [24 ... 5] = (((GP+G) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi20(GP+G) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[] |76 |R_LARCH_GOT_PC_LO12 @@ -730,12 +732,12 @@ v2.00 |77 |R_LARCH_GOT64_PC_LO20 |GOT 表项相对 PC 偏移 64 位的 [51 ... 32] 位 -|`+(*(uint32_t *) PC) [24 ... 5] = (GP+G - (PC & ~0xffffffff)) [51 ... 32]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi32(GP+G) - (PC & ~0xffffffff)) [51 ... 32]+` footnote:foot_hi32[] |78 |R_LARCH_GOT64_PC_HI12 |GOT 表项相对 PC 偏移 64 位的 [63 ... 52] 位 -|`+(*(uint32_t *) PC) [21 ... 10] = (GP+G - (PC & ~0xffffffff)) [63 ... 52]+` +|`+(*(uint32_t *) PC) [21 ... 10] = (hi32(GP+G) - (PC & ~0xffffffff)) [63 ... 52]+` footnote:foot_hi32[] |79 |R_LARCH_GOT_HI20 @@ -780,7 +782,7 @@ v2.00 |87 |R_LARCH_TLS_IE_PC_HI20 |TLS IE 符号 GOT 表项相对 PC 偏移 32/64 位的 [31 ... 12] 位 -|`+(*(uint32_t *) PC) [24 ... 5] = (((GP+IE) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi20(GP+IE) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[] |88 |R_LARCH_TLS_IE_PC_LO12 @@ -790,12 +792,12 @@ v2.00 |89 |R_LARCH_TLS_IE64_PC_LO20 |TLS IE 符号 GOT 表项相对 PC 偏移 64 位的 [51 ... 32] 位 -|`+(*(uint32_t *) PC) [24 ... 5] = (GP+IE - (PC & ~0xffffffff)) [51 ... 32]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi32(GP+IE) - (PC & ~0xffffffff)) [51 ... 32]+` footnote:foot_hi32[] |90 |R_LARCH_TLS_IE64_PC_HI12 |TLS IE 符号 GOT 表项相对 PC 偏移 64 位的 [63 ... 52] 位 -|`+(*(uint32_t *) PC) [21 ... 10] = (GP+IE - (PC & ~0xffffffff)) [63 ... 52]+` +|`+(*(uint32_t *) PC) [21 ... 10] = (hi32(GP+IE) - (PC & ~0xffffffff)) [63 ... 52]+` footnote:foot_hi32[] |91 |R_LARCH_TLS_IE_HI20 @@ -820,7 +822,7 @@ v2.00 |95 |R_LARCH_TLS_LD_PC_HI20 |TLS LD 符号 GOT 表项相对 PC 偏移 32/64 位的 [31 ... 12] 位 -|`+(*(uint32_t *) PC) [24 ... 5] = (((GP+GD) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi20(GP+GD) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[] |96 |R_LARCH_TLS_LD_HI20 @@ -830,7 +832,7 @@ v2.00 |97 |R_LARCH_TLS_GD_PC_HI20 |TLS GD 符号 GOT 表项相对 PC 偏移 32/64 位的 [31 ... 12] 位 -|`+(*(uint32_t *) PC) [24 ... 5] = (((GP+GD) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi20(GP+GD) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[] |98 |R_LARCH_TLS_GD_HI20 diff --git a/docs/LoongArch-ELF-ABI-EN.adoc b/docs/LoongArch-ELF-ABI-EN.adoc index 005f7a1..c29a03d 100644 --- a/docs/LoongArch-ELF-ABI-EN.adoc +++ b/docs/LoongArch-ELF-ABI-EN.adoc @@ -696,7 +696,9 @@ with check 28-bit signed overflow and 4-bit aligned |71 |R_LARCH_PCALA_HI20 |[31 ... 12] bits of 32/64-bit PC-relative offset -|`+(*(uint32_t *) PC) [24 ... 5] = (((S+A) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi20(S+A) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[`hi20(x)` is defined as `(x + 0x800) & ~0xfff`. +The additional `+ 0x800` makes the result suitable for an addition with +`x & 0xfff` as a 12-bit signed integer.] `+Note: The lower 12 bits are not included when calculating the PC-relative offset.+` @@ -708,17 +710,20 @@ with check 28-bit signed overflow and 4-bit aligned |73 |R_LARCH_PCALA64_LO20 |[51 ... 32] bits of 64-bit PC-relative offset -|`+(*(uint32_t *) PC) [24 ... 5] = (S+A - (PC & ~0xffffffff)) [51 ... 32]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi32(S+A) - (PC & ~0xffffffff)) [51 ... 32]+` footnote:foot_hi32[`hi32(x)` is defined as +`x - ((x & 0x800) << 21)`. The additional `-((x & 0x800) << 21)` makes the +result suitable for addition with `x & 0xfff` as a 12-bit signed integer +extended to 32-bit and `hi20(x)`.] |74 |R_LARCH_PCALA64_HI12 |[63 ... 52] bits of 64-bit PC-relative offset -|`+(*(uint32_t *) PC) [21 ... 10] = (S+A - (PC & ~0xffffffff)) [63 ... 52]+` +|`+(*(uint32_t *) PC) [21 ... 10] = (hi32(S+A) - (PC & ~0xffffffff)) [63 ... 52]+` footnote:foot_hi32[] |75 |R_LARCH_GOT_PC_HI20 |[31 ... 12] bits of 32/64-bit PC-relative offset to GOT entry -|`+(*(uint32_t *) PC) [24 ... 5] = (((GP+G) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi20(GP+G) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[] |76 |R_LARCH_GOT_PC_LO12 @@ -728,12 +733,12 @@ with check 28-bit signed overflow and 4-bit aligned |77 |R_LARCH_GOT64_PC_LO20 |[51 ... 32] bits of 64-bit PC-relative offset to GOT entry -|`+(*(uint32_t *) PC) [24 ... 5] = (GP+G - (PC & ~0xffffffff)) [51 ... 32]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi32(GP+G) - (PC & ~0xffffffff)) [51 ... 32]+` footnote:foot_hi32[] |78 |R_LARCH_GOT64_PC_HI12 |[63 ... 52] bits of 64-bit PC-relative offset to GOT entry -|`+(*(uint32_t *) PC) [21 ... 10] = (GP+G - (PC & ~0xffffffff)) [63 ... 52]+` +|`+(*(uint32_t *) PC) [21 ... 10] = (hi32(GP+G) - (PC & ~0xffffffff)) [63 ... 52]+` footnote:foot_hi32[] |79 |R_LARCH_GOT_HI20 @@ -778,7 +783,7 @@ with check 28-bit signed overflow and 4-bit aligned |87 |R_LARCH_TLS_IE_PC_HI20 |[31 ... 12] bits of 32/64-bit PC-relative offset to TLS IE GOT entry -|`+(*(uint32_t *) PC) [24 ... 5] = (((GP+IE) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi20(GP+IE) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[] |88 |R_LARCH_TLS_IE_PC_LO12 @@ -788,12 +793,12 @@ with check 28-bit signed overflow and 4-bit aligned |89 |R_LARCH_TLS_IE64_PC_LO20 |[51 ... 32] bits of 64-bit PC-relative offset to TLS IE GOT entry -|`+(*(uint32_t *) PC) [24 ... 5] = (GP+IE - (PC & ~0xffffffff)) [51 ... 32]+` +|`+(*(uint32_t *) PC) [24 ... 5] = (hi32(GP+IE) - (PC & ~0xffffffff)) [51 ... 32]+` footnote:foot_hi32[] |90 |R_LARCH_TLS_IE64_PC_HI12 |[63 ... 52] bits of 64-bit PC-relative offset to TLS IE GOT entry -|`+(*(uint32_t *) PC) [21 ... 10] = (GP+IE - (PC & ~0xffffffff)) [63 ... 52]+` +|`+(*(uint32_t *) PC) [21 ... 10] = (hi32(GP+IE) - (PC & ~0xffffffff)) [63 ... 52]+` footnote:foot_hi32[] |91 |R_LARCH_TLS_IE_HI20 @@ -818,7 +823,7 @@ with check 28-bit signed overflow and 4-bit aligned |95 |R_LARCH_TLS_LD_PC_HI20 |[31 ... 12] bits of 32/64-bit PC-relative offset to TLS LD GOT entry -|`+(*(uint32_t *) PC) [24 ... 5] = (((GP+GD) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = hi20(GP+GD) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[] |96 |R_LARCH_TLS_LD_HI20 @@ -828,7 +833,7 @@ with check 28-bit signed overflow and 4-bit aligned |97 |R_LARCH_TLS_GD_PC_HI20 |[31 ... 12] bits of 32/64-bit PC-relative offset to TLS GD GOT entry -|`+(*(uint32_t *) PC) [24 ... 5] = (((GP+GD) & ~0xfff) - (PC & ~0xfff)) [31 ... 12]+` +|`+(*(uint32_t *) PC) [24 ... 5] = hi20(GP+GD) - (PC & ~0xfff)) [31 ... 12]+` footnote:foot_hi20[] |98 |R_LARCH_TLS_GD_HI20