-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[llvm][lld] Support R_AARCH64_GOTPCREL32 #72584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lld-elf @llvm/pr-subscribers-mc Author: None (PiJoules) ChangesThis is the follopw implementation to Full diff: https://github.com/llvm/llvm-project/pull/72584.diff 5 Files Affected:
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 048f0ec30ebd283..32cff73955028e4 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -165,6 +165,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
case R_AARCH64_ADR_GOT_PAGE:
case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
return R_AARCH64_GOT_PAGE_PC;
+ case R_AARCH64_GOTPCREL32:
+ return R_GOT_PC;
case R_AARCH64_NONE:
return R_NONE;
default:
@@ -374,6 +376,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
write32(loc, val);
break;
case R_AARCH64_PLT32:
+ case R_AARCH64_GOTPCREL32:
checkInt(loc, val, 32, rel);
write32(loc, val);
break;
diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..7ea55bfc5b00aad
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
@@ -0,0 +1,36 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -S %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
+
+
+// SEC: Name: .got (58)
+// SEC-NEXT: Type: SHT_PROGBITS (0x1)
+// SEC-NEXT: Flags [ (0x3)
+// SEC-NEXT: SHF_ALLOC (0x2)
+// SEC-NEXT: SHF_WRITE (0x1)
+// SEC-NEXT: ]
+// SEC-NEXT: Address: 0x20350
+// SEC-NEXT: Offset: 0x350
+// SEC-NEXT: Size: 8
+// SEC-NEXT: Link: 0
+// SEC-NEXT: Info: 0
+// SEC-NEXT: AddressAlignment: 8
+// SEC-NEXT: EntrySize: 0
+
+ .section .data
+ .globl bar
+bar:
+
+ .globl _start
+_start:
+// bar@GOTPCREL = 0x20350 (got entry for `bar`) - 0x30358 (.) = 0xfffefff8
+// bar@GOTPCREL+4 = 0x20350 (got entry for `bar`) - 0x3035c (.) + 4 = 0xfffefff8
+// bar@GOTPCREL-4 = 0x20350 (got entry for `bar`) - 0x30360 (.) + 4 = 0xfffeffec
+// CHECK: Contents of section .data:
+// CHECK: 30358 f8fffeff f8fffeff ecfffeff
+ .word bar@GOTPCREL
+ .word bar@GOTPCREL+4
+ .word bar@GOTPCREL-4
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index b507109b19e1b90..fcaea2aceed5209 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -59,6 +59,7 @@ ELF_RELOC(R_AARCH64_ADR_GOT_PAGE, 0x137)
ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC, 0x138)
ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 0x139)
ELF_RELOC(R_AARCH64_PLT32, 0x13a)
+ELF_RELOC(R_AARCH64_GOTPCREL32, 0x13b)
ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 0x200)
ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 0x201)
ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC, 0x202)
@@ -166,6 +167,7 @@ ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE, 0x01a)
ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC, 0x01b)
ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14, 0x01c)
ELF_RELOC(R_AARCH64_P32_PLT32, 0x01d)
+ELF_RELOC(R_AARCH64_P32_GOTPCREL32, 0x01e)
ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PREL21, 0x050)
ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PAGE21, 0x051)
ELF_RELOC(R_AARCH64_P32_TLSGD_ADD_LO12_NC, 0x052)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 9de40661298ccad..996fd1614d19f57 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -120,7 +120,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
assert((!Target.getSymA() ||
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
- Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) &&
+ Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
+ Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
"Should only be expression-level modifiers here");
assert((!Target.getSymB() ||
@@ -202,7 +203,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
case FK_Data_2:
return R_CLS(ABS16);
case FK_Data_4:
- return R_CLS(ABS32);
+ return Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL
+ ? R_CLS(GOTPCREL32)
+ : R_CLS(ABS32);
case FK_Data_8:
if (IsILP32) {
Ctx.reportError(Fixup.getLoc(),
diff --git a/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..afbcaad9e1dfdcc
--- /dev/null
+++ b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | \
+// RUN: llvm-readobj -r - | FileCheck %s
+
+ .section .data
+this:
+ .word this@GOTPCREL
+ .word extern_sym@GOTPCREL+4
+ .word negative_offset@GOTPCREL-4
+
+// CHECK: Section ({{.*}}) .rela.data
+// CHECK-NEXT: 0x0 R_AARCH64_GOTPCREL32 this 0x0
+// CHECK-NEXT: 0x4 R_AARCH64_GOTPCREL32 extern_sym 0x4
+// CHECK-NEXT: 0x8 R_AARCH64_GOTPCREL32 negative_offset 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: }
|
@llvm/pr-subscribers-backend-aarch64 Author: None (PiJoules) ChangesThis is the follopw implementation to Full diff: https://github.com/llvm/llvm-project/pull/72584.diff 5 Files Affected:
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 048f0ec30ebd283..32cff73955028e4 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -165,6 +165,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
case R_AARCH64_ADR_GOT_PAGE:
case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
return R_AARCH64_GOT_PAGE_PC;
+ case R_AARCH64_GOTPCREL32:
+ return R_GOT_PC;
case R_AARCH64_NONE:
return R_NONE;
default:
@@ -374,6 +376,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
write32(loc, val);
break;
case R_AARCH64_PLT32:
+ case R_AARCH64_GOTPCREL32:
checkInt(loc, val, 32, rel);
write32(loc, val);
break;
diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..7ea55bfc5b00aad
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
@@ -0,0 +1,36 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -S %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
+
+
+// SEC: Name: .got (58)
+// SEC-NEXT: Type: SHT_PROGBITS (0x1)
+// SEC-NEXT: Flags [ (0x3)
+// SEC-NEXT: SHF_ALLOC (0x2)
+// SEC-NEXT: SHF_WRITE (0x1)
+// SEC-NEXT: ]
+// SEC-NEXT: Address: 0x20350
+// SEC-NEXT: Offset: 0x350
+// SEC-NEXT: Size: 8
+// SEC-NEXT: Link: 0
+// SEC-NEXT: Info: 0
+// SEC-NEXT: AddressAlignment: 8
+// SEC-NEXT: EntrySize: 0
+
+ .section .data
+ .globl bar
+bar:
+
+ .globl _start
+_start:
+// bar@GOTPCREL = 0x20350 (got entry for `bar`) - 0x30358 (.) = 0xfffefff8
+// bar@GOTPCREL+4 = 0x20350 (got entry for `bar`) - 0x3035c (.) + 4 = 0xfffefff8
+// bar@GOTPCREL-4 = 0x20350 (got entry for `bar`) - 0x30360 (.) + 4 = 0xfffeffec
+// CHECK: Contents of section .data:
+// CHECK: 30358 f8fffeff f8fffeff ecfffeff
+ .word bar@GOTPCREL
+ .word bar@GOTPCREL+4
+ .word bar@GOTPCREL-4
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index b507109b19e1b90..fcaea2aceed5209 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -59,6 +59,7 @@ ELF_RELOC(R_AARCH64_ADR_GOT_PAGE, 0x137)
ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC, 0x138)
ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 0x139)
ELF_RELOC(R_AARCH64_PLT32, 0x13a)
+ELF_RELOC(R_AARCH64_GOTPCREL32, 0x13b)
ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 0x200)
ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 0x201)
ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC, 0x202)
@@ -166,6 +167,7 @@ ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE, 0x01a)
ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC, 0x01b)
ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14, 0x01c)
ELF_RELOC(R_AARCH64_P32_PLT32, 0x01d)
+ELF_RELOC(R_AARCH64_P32_GOTPCREL32, 0x01e)
ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PREL21, 0x050)
ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PAGE21, 0x051)
ELF_RELOC(R_AARCH64_P32_TLSGD_ADD_LO12_NC, 0x052)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 9de40661298ccad..996fd1614d19f57 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -120,7 +120,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
assert((!Target.getSymA() ||
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
- Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) &&
+ Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
+ Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
"Should only be expression-level modifiers here");
assert((!Target.getSymB() ||
@@ -202,7 +203,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
case FK_Data_2:
return R_CLS(ABS16);
case FK_Data_4:
- return R_CLS(ABS32);
+ return Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL
+ ? R_CLS(GOTPCREL32)
+ : R_CLS(ABS32);
case FK_Data_8:
if (IsILP32) {
Ctx.reportError(Fixup.getLoc(),
diff --git a/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..afbcaad9e1dfdcc
--- /dev/null
+++ b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | \
+// RUN: llvm-readobj -r - | FileCheck %s
+
+ .section .data
+this:
+ .word this@GOTPCREL
+ .word extern_sym@GOTPCREL+4
+ .word negative_offset@GOTPCREL-4
+
+// CHECK: Section ({{.*}}) .rela.data
+// CHECK-NEXT: 0x0 R_AARCH64_GOTPCREL32 this 0x0
+// CHECK-NEXT: 0x4 R_AARCH64_GOTPCREL32 extern_sym 0x4
+// CHECK-NEXT: 0x8 R_AARCH64_GOTPCREL32 negative_offset 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: }
|
I only discovered the |
a0b6255
to
958ec66
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than one line about the ILP32 code LGTM.
Please do tell us if you need ILP32 support and we can add the code to the ABI.
958ec66
to
718b1c5
Compare
@@ -0,0 +1,11 @@ | |||
// REQUIRES: aarch64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Newer tests place overflow tests (RUN: not ld.lld ...
) and regular tests (RUN: ld.lld ...
) in one file so that the boundary is clearer.
aarch64-reloc-plt32.s
is a good example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For PLT32 I can put all the tests in one file since foo@PLT
can be relaxed to foo
if it's defined in one of the other input files, but I don't think the same can work for foo@GOTPCREL
since this can't be relaxed to anything that could be defined in a separate input file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you perhaps have another example I can follow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps you can use more than one symbol in a test.
Since the error message contains the bounds (in [-2147483648, 2147483647]
), I think we don't need to make an extreme test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated tests
I don't have any more comments, thanks for making the earlier changes. Happy for MaskRay to approve when his comments have been addressed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is mostly good, just needing some test changes.
718b1c5
to
2353935
Compare
This is the follopw implementation to ARM-software/abi-aa#223 that supports this relocation in llvm and lld.
2353935
to
43a19d6
Compare
This is the follopw implementation to ARM-software/abi-aa#223 that supports this relocation in llvm and lld.
This reverts the MC changes from commit 04a906e, which cause failures when linking with gold on arm64.
Partially revert "[llvm][lld] Support R_AARCH64_GOTPCREL32 (llvm#72584)"
…lvm#72584)"" This reverts commit f1cbfe9, which ended up causing other failures.
Revert "Partially revert "[llvm][lld] Support R_AARCH64_GOTPCREL32 (llvm#72584)""
We have identified that some Rust projects are broken from here, such as rust-lang/rust#141737 and tikv/tikv#18465. Can we revert this until the GNU linker also supports |
You're suggesting to only revert the AArch64ELFObjectWriter part, right? |
I don't think it's reasonable to request reverting the lld/ELF or AArch64 assembler changes. The affected code path is only used when the input IR is in a specific form. If Rust needs compatibility with GNU ld or older lld, it should stop emitting IR that triggers this path. Additionally, the linked rust-lang/rust#141737 does not explain why you assert this is an LLVM issue rather than a Rust one. |
@MaskRay Rust is not generating this pattern, LLVM is. Are you suggesting that the RelLookupTableConverter pass should be disabled on aarch64? |
Just a question: is it reasonable, like https://github.com/rust-lang/llvm-project/pull/181/files removes unnamed_addr in the RelLookupTableConverter pass? I don't see any problem with retaining unnamed_addr on IR. |
I don't have a Rust development environment, but these components are likely involved:
Implementing a workaround in LLVM's Transforms or CodeGen sections might seem appealing for broader IR producer support, but we generally aim to avoid adding linker compatibility checks... |
It looks like removing unnamed_addr avoids the use of the GOTPCREL relocations: https://llvm.godbolt.org/z/js9vx39ar |
@MaskRay I don't think this can be worked around by changing the IR Rust produces. The IR that Rust generates is very boring. All the decisions that ultimately lead to the use of this unsupported relocation are made by LLVM, so this needs to be fixed in LLVM, either by not using this relocation at all, or by never producing IR that can lead to the use of this relocation. The former seems cleaner to me, but I'm ok with either variant. |
Disabling RelLookupTableConverter.cpp looks good to me. It's a tradeoff between dynamic relocations/startup time and slightly more instructions at the single user. |
Okay, in that case I think doing something along the lines of @dianqk's workaround in https://github.com/rust-lang/llvm-project/pull/181/files would be best. That allows RelLookupTableConverter to still generally work, but prevents it from generating GOTPCREL relocations. |
…REL relocations (#142304) Follow #72584 (comment), the patch will drop the `unnamed_addr` attribute when generating relative lookup tables. I'm not very confident about this patch, but it does resolve rust-lang/rust#140686, rust-lang/rust#141306 and rust-lang/rust#141737. But I don't think this will result in worse problems. > LLVM provides that the calculation of such a constant initializer will not overflow at link time under the medium code model if x is an unnamed_addr function. However, it does not provide this guarantee for a constant initializer folded into a function body. This intrinsic can be used to avoid the possibility of overflows when loading from such a constant. ([‘llvm.load.relative’ Intrinsic](https://llvm.org/docs/LangRef.html#id2592)) This is my concern. I'm not sure how unnamed_addr provides this guarantee, and I haven't found any test cases.
…ating GOTPCREL relocations (#142304) Follow llvm/llvm-project#72584 (comment), the patch will drop the `unnamed_addr` attribute when generating relative lookup tables. I'm not very confident about this patch, but it does resolve rust-lang/rust#140686, rust-lang/rust#141306 and rust-lang/rust#141737. But I don't think this will result in worse problems. > LLVM provides that the calculation of such a constant initializer will not overflow at link time under the medium code model if x is an unnamed_addr function. However, it does not provide this guarantee for a constant initializer folded into a function body. This intrinsic can be used to avoid the possibility of overflows when loading from such a constant. ([‘llvm.load.relative’ Intrinsic](https://llvm.org/docs/LangRef.html#id2592)) This is my concern. I'm not sure how unnamed_addr provides this guarantee, and I haven't found any test cases.
…REL relocations (llvm#142304) Follow llvm#72584 (comment), the patch will drop the `unnamed_addr` attribute when generating relative lookup tables. I'm not very confident about this patch, but it does resolve rust-lang/rust#140686, rust-lang/rust#141306 and rust-lang/rust#141737. But I don't think this will result in worse problems. > LLVM provides that the calculation of such a constant initializer will not overflow at link time under the medium code model if x is an unnamed_addr function. However, it does not provide this guarantee for a constant initializer folded into a function body. This intrinsic can be used to avoid the possibility of overflows when loading from such a constant. ([‘llvm.load.relative’ Intrinsic](https://llvm.org/docs/LangRef.html#id2592)) This is my concern. I'm not sure how unnamed_addr provides this guarantee, and I haven't found any test cases. (cherry picked from commit aa09dbb)
…REL relocations (llvm#142304) Follow llvm#72584 (comment), the patch will drop the `unnamed_addr` attribute when generating relative lookup tables. I'm not very confident about this patch, but it does resolve rust-lang/rust#140686, rust-lang/rust#141306 and rust-lang/rust#141737. But I don't think this will result in worse problems. > LLVM provides that the calculation of such a constant initializer will not overflow at link time under the medium code model if x is an unnamed_addr function. However, it does not provide this guarantee for a constant initializer folded into a function body. This intrinsic can be used to avoid the possibility of overflows when loading from such a constant. ([‘llvm.load.relative’ Intrinsic](https://llvm.org/docs/LangRef.html#id2592)) This is my concern. I'm not sure how unnamed_addr provides this guarantee, and I haven't found any test cases. (cherry picked from commit aa09dbb)
…ating GOTPCREL relocations (#142304) Follow llvm/llvm-project#72584 (comment), the patch will drop the `unnamed_addr` attribute when generating relative lookup tables. I'm not very confident about this patch, but it does resolve rust-lang/rust#140686, rust-lang/rust#141306 and rust-lang/rust#141737. But I don't think this will result in worse problems. > LLVM provides that the calculation of such a constant initializer will not overflow at link time under the medium code model if x is an unnamed_addr function. However, it does not provide this guarantee for a constant initializer folded into a function body. This intrinsic can be used to avoid the possibility of overflows when loading from such a constant. ([‘llvm.load.relative’ Intrinsic](https://llvm.org/docs/LangRef.html#id2592)) This is my concern. I'm not sure how unnamed_addr provides this guarantee, and I haven't found any test cases. (cherry picked from commit aa09dbb)
…REL relocations (llvm#142304) Follow llvm#72584 (comment), the patch will drop the `unnamed_addr` attribute when generating relative lookup tables. I'm not very confident about this patch, but it does resolve rust-lang/rust#140686, rust-lang/rust#141306 and rust-lang/rust#141737. But I don't think this will result in worse problems. > LLVM provides that the calculation of such a constant initializer will not overflow at link time under the medium code model if x is an unnamed_addr function. However, it does not provide this guarantee for a constant initializer folded into a function body. This intrinsic can be used to avoid the possibility of overflows when loading from such a constant. ([‘llvm.load.relative’ Intrinsic](https://llvm.org/docs/LangRef.html#id2592)) This is my concern. I'm not sure how unnamed_addr provides this guarantee, and I haven't found any test cases.
This is the follopw implementation to
ARM-software/abi-aa#223 that supports this relocation in llvm and lld.