-
Notifications
You must be signed in to change notification settings - Fork 11k
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
IRSymTab: Record _GLOBAL_OFFSET_TABLE_ for ELF x86 #89463
IRSymTab: Record _GLOBAL_OFFSET_TABLE_ for ELF x86 #89463
Conversation
Created using spr 1.3.5-bogner
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-lld-elf Author: Fangrui Song (MaskRay) ChangesIn ELF, relocatable files generated for x86-32 and some code models of Fix #61101: record that Full diff: https://github.com/llvm/llvm-project/pull/89463.diff 8 Files Affected:
diff --git a/lld/test/ELF/lto/i386-global-offset-table.ll b/lld/test/ELF/lto/i386-global-offset-table.ll
new file mode 100644
index 00000000000000..e470763a3eb2ec
--- /dev/null
+++ b/lld/test/ELF/lto/i386-global-offset-table.ll
@@ -0,0 +1,22 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.bc
+; RUN: ld.lld %t.bc -o %t
+
+target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+define dso_local void @f() {
+entry:
+ ret void
+}
+
+define dso_local void @_start() {
+entry:
+ call void @f()
+ ret void
+}
+
+!llvm.module.flags = !{!0, !1}
+
+!0 = !{i32 8, !"PIC Level", i32 2}
+!1 = !{i32 7, !"PIE Level", i32 2}
diff --git a/lld/test/ELF/lto/x86-64-global-offset-table.ll b/lld/test/ELF/lto/x86-64-global-offset-table.ll
new file mode 100644
index 00000000000000..1db1027e7a21c5
--- /dev/null
+++ b/lld/test/ELF/lto/x86-64-global-offset-table.ll
@@ -0,0 +1,57 @@
+; REQUIRES: x86
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o
+
+; RUN: cat a.ll medium.ll | llvm-as - -o medium.bc
+; RUN: ld.lld -pie --no-relax medium.bc b.o -o medium
+; RUN: llvm-objdump -d medium | FileCheck %s
+
+; RUN: cat a.ll large.ll | llvm-as - -o large.bc
+; RUN: ld.lld -pie large.bc b.o -o large
+; RUN: llvm-objdump -d large | FileCheck %s
+
+; RUN: cat a.ll medium.ll ref.ll | llvm-as - -o ref.bc
+; RUN: ld.lld -pie --no-relax -u ref ref.bc b.o -o ref
+; RUN: llvm-objdump -d ref | FileCheck %s
+
+; CHECK: movabsq
+
+;--- a.ll
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@i = external global i32
+
+define dso_local void @_start() {
+entry:
+ %0 = load i32, ptr @i
+ %inc = add nsw i32 %0, 1
+ store i32 %inc, ptr @i
+ ret void
+}
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 8, !"PIC Level", i32 2}
+!1 = !{i32 7, !"PIE Level", i32 2}
+!2 = !{i32 1, !"Large Data Threshold", i64 0}
+
+;--- medium.ll
+!3 = !{i32 1, !"Code Model", i32 3}
+
+;--- large.ll
+!3 = !{i32 1, !"Code Model", i32 4}
+
+;--- ref.ll
+@_GLOBAL_OFFSET_TABLE_ = external global [0 x i8]
+
+define dso_local ptr @ref() {
+entry:
+ ret ptr @_GLOBAL_OFFSET_TABLE_
+}
+
+;--- b.s
+.data
+.globl i
+i:
+.long 0
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp
index 07f76688fa43e7..d8f520ad02c2f2 100644
--- a/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -175,6 +175,20 @@ void ModuleSymbolTable::CollectAsmSymbols(
AsmSymbol(Key, BasicSymbolRef::Flags(Res));
}
});
+
+ // In ELF, object code generated for x86-32 and some code models of x86-64 may
+ // reference the special symbol _GLOBAL_OFFSET_TABLE_ that is not used in the
+ // IR. Record it like inline asm symbols.
+ Triple TT(M.getTargetTriple());
+ if (!TT.isOSBinFormatELF() || !TT.isX86())
+ return;
+ auto CM = M.getCodeModel();
+ if (TT.getArch() == Triple::x86 || CM == CodeModel::Medium ||
+ CM == CodeModel::Large) {
+ AsmSymbol("_GLOBAL_OFFSET_TABLE_",
+ BasicSymbolRef::Flags(BasicSymbolRef::SF_Undefined |
+ BasicSymbolRef::SF_Global));
+ }
}
void ModuleSymbolTable::CollectAsmSymvers(
diff --git a/llvm/test/LTO/X86/codemodel-2.ll b/llvm/test/LTO/X86/codemodel-2.ll
index 5cd9731606f2bd..fc1074bcf2235c 100644
--- a/llvm/test/LTO/X86/codemodel-2.ll
+++ b/llvm/test/LTO/X86/codemodel-2.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
-; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s
; RUN: llvm-objdump --no-print-imm-hex -d %t.s.0 | FileCheck %s --check-prefix=CHECK-LARGE
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/codemodel-3.ll b/llvm/test/LTO/X86/codemodel-3.ll
index 947221e9f36dc5..13702dfbca2da4 100644
--- a/llvm/test/LTO/X86/codemodel-3.ll
+++ b/llvm/test/LTO/X86/codemodel-3.ll
@@ -1,6 +1,7 @@
; RUN: llvm-as %s -o %t0.o
; RUN: llvm-as < %p/Inputs/codemodel-3.ll > %t1.o
-; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
+; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px -r %t0.o,_GLOBAL_OFFSET_TABLE_, \
+; RUN: -r %t1.o,_GLOBAL_OFFSET_TABLE_, %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/llvm/test/LTO/X86/largedatathreshold-1.ll b/llvm/test/LTO/X86/largedatathreshold-1.ll
index e3be5c11baaac2..dfd8319511b617 100644
--- a/llvm/test/LTO/X86/largedatathreshold-1.ll
+++ b/llvm/test/LTO/X86/largedatathreshold-1.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
-; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s
; RUN: llvm-objdump -d %t.s.0 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/largedatathreshold-2.ll b/llvm/test/LTO/X86/largedatathreshold-2.ll
index 103c066b744d0f..59438bbdb5027f 100644
--- a/llvm/test/LTO/X86/largedatathreshold-2.ll
+++ b/llvm/test/LTO/X86/largedatathreshold-2.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
-; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s
; RUN: llvm-objdump -d %t.s.0 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/largedatathreshold-3.ll b/llvm/test/LTO/X86/largedatathreshold-3.ll
index 3c0653db334d85..fea7987ff15566 100644
--- a/llvm/test/LTO/X86/largedatathreshold-3.ll
+++ b/llvm/test/LTO/X86/largedatathreshold-3.ll
@@ -1,6 +1,7 @@
; RUN: llvm-as %s -o %t0.o
; RUN: llvm-as < %p/Inputs/largedatathreshold.ll > %t1.o
-; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
+; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px -r %t0.o,_GLOBAL_OFFSET_TABLE_, \
+; RUN: -r %t1.o,_GLOBAL_OFFSET_TABLE_, %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
; CHECK: 'Large Data Threshold': IDs have conflicting values
|
@llvm/pr-subscribers-lld Author: Fangrui Song (MaskRay) ChangesIn ELF, relocatable files generated for x86-32 and some code models of Fix #61101: record that Full diff: https://github.com/llvm/llvm-project/pull/89463.diff 8 Files Affected:
diff --git a/lld/test/ELF/lto/i386-global-offset-table.ll b/lld/test/ELF/lto/i386-global-offset-table.ll
new file mode 100644
index 00000000000000..e470763a3eb2ec
--- /dev/null
+++ b/lld/test/ELF/lto/i386-global-offset-table.ll
@@ -0,0 +1,22 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.bc
+; RUN: ld.lld %t.bc -o %t
+
+target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+define dso_local void @f() {
+entry:
+ ret void
+}
+
+define dso_local void @_start() {
+entry:
+ call void @f()
+ ret void
+}
+
+!llvm.module.flags = !{!0, !1}
+
+!0 = !{i32 8, !"PIC Level", i32 2}
+!1 = !{i32 7, !"PIE Level", i32 2}
diff --git a/lld/test/ELF/lto/x86-64-global-offset-table.ll b/lld/test/ELF/lto/x86-64-global-offset-table.ll
new file mode 100644
index 00000000000000..1db1027e7a21c5
--- /dev/null
+++ b/lld/test/ELF/lto/x86-64-global-offset-table.ll
@@ -0,0 +1,57 @@
+; REQUIRES: x86
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o
+
+; RUN: cat a.ll medium.ll | llvm-as - -o medium.bc
+; RUN: ld.lld -pie --no-relax medium.bc b.o -o medium
+; RUN: llvm-objdump -d medium | FileCheck %s
+
+; RUN: cat a.ll large.ll | llvm-as - -o large.bc
+; RUN: ld.lld -pie large.bc b.o -o large
+; RUN: llvm-objdump -d large | FileCheck %s
+
+; RUN: cat a.ll medium.ll ref.ll | llvm-as - -o ref.bc
+; RUN: ld.lld -pie --no-relax -u ref ref.bc b.o -o ref
+; RUN: llvm-objdump -d ref | FileCheck %s
+
+; CHECK: movabsq
+
+;--- a.ll
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@i = external global i32
+
+define dso_local void @_start() {
+entry:
+ %0 = load i32, ptr @i
+ %inc = add nsw i32 %0, 1
+ store i32 %inc, ptr @i
+ ret void
+}
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 8, !"PIC Level", i32 2}
+!1 = !{i32 7, !"PIE Level", i32 2}
+!2 = !{i32 1, !"Large Data Threshold", i64 0}
+
+;--- medium.ll
+!3 = !{i32 1, !"Code Model", i32 3}
+
+;--- large.ll
+!3 = !{i32 1, !"Code Model", i32 4}
+
+;--- ref.ll
+@_GLOBAL_OFFSET_TABLE_ = external global [0 x i8]
+
+define dso_local ptr @ref() {
+entry:
+ ret ptr @_GLOBAL_OFFSET_TABLE_
+}
+
+;--- b.s
+.data
+.globl i
+i:
+.long 0
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp
index 07f76688fa43e7..d8f520ad02c2f2 100644
--- a/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -175,6 +175,20 @@ void ModuleSymbolTable::CollectAsmSymbols(
AsmSymbol(Key, BasicSymbolRef::Flags(Res));
}
});
+
+ // In ELF, object code generated for x86-32 and some code models of x86-64 may
+ // reference the special symbol _GLOBAL_OFFSET_TABLE_ that is not used in the
+ // IR. Record it like inline asm symbols.
+ Triple TT(M.getTargetTriple());
+ if (!TT.isOSBinFormatELF() || !TT.isX86())
+ return;
+ auto CM = M.getCodeModel();
+ if (TT.getArch() == Triple::x86 || CM == CodeModel::Medium ||
+ CM == CodeModel::Large) {
+ AsmSymbol("_GLOBAL_OFFSET_TABLE_",
+ BasicSymbolRef::Flags(BasicSymbolRef::SF_Undefined |
+ BasicSymbolRef::SF_Global));
+ }
}
void ModuleSymbolTable::CollectAsmSymvers(
diff --git a/llvm/test/LTO/X86/codemodel-2.ll b/llvm/test/LTO/X86/codemodel-2.ll
index 5cd9731606f2bd..fc1074bcf2235c 100644
--- a/llvm/test/LTO/X86/codemodel-2.ll
+++ b/llvm/test/LTO/X86/codemodel-2.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
-; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s
; RUN: llvm-objdump --no-print-imm-hex -d %t.s.0 | FileCheck %s --check-prefix=CHECK-LARGE
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/codemodel-3.ll b/llvm/test/LTO/X86/codemodel-3.ll
index 947221e9f36dc5..13702dfbca2da4 100644
--- a/llvm/test/LTO/X86/codemodel-3.ll
+++ b/llvm/test/LTO/X86/codemodel-3.ll
@@ -1,6 +1,7 @@
; RUN: llvm-as %s -o %t0.o
; RUN: llvm-as < %p/Inputs/codemodel-3.ll > %t1.o
-; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
+; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px -r %t0.o,_GLOBAL_OFFSET_TABLE_, \
+; RUN: -r %t1.o,_GLOBAL_OFFSET_TABLE_, %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/llvm/test/LTO/X86/largedatathreshold-1.ll b/llvm/test/LTO/X86/largedatathreshold-1.ll
index e3be5c11baaac2..dfd8319511b617 100644
--- a/llvm/test/LTO/X86/largedatathreshold-1.ll
+++ b/llvm/test/LTO/X86/largedatathreshold-1.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
-; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s
; RUN: llvm-objdump -d %t.s.0 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/largedatathreshold-2.ll b/llvm/test/LTO/X86/largedatathreshold-2.ll
index 103c066b744d0f..59438bbdb5027f 100644
--- a/llvm/test/LTO/X86/largedatathreshold-2.ll
+++ b/llvm/test/LTO/X86/largedatathreshold-2.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
-; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s
; RUN: llvm-objdump -d %t.s.0 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/largedatathreshold-3.ll b/llvm/test/LTO/X86/largedatathreshold-3.ll
index 3c0653db334d85..fea7987ff15566 100644
--- a/llvm/test/LTO/X86/largedatathreshold-3.ll
+++ b/llvm/test/LTO/X86/largedatathreshold-3.ll
@@ -1,6 +1,7 @@
; RUN: llvm-as %s -o %t0.o
; RUN: llvm-as < %p/Inputs/largedatathreshold.ll > %t1.o
-; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
+; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px -r %t0.o,_GLOBAL_OFFSET_TABLE_, \
+; RUN: -r %t1.o,_GLOBAL_OFFSET_TABLE_, %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
; CHECK: 'Large Data Threshold': IDs have conflicting values
|
@llvm/pr-subscribers-lto Author: Fangrui Song (MaskRay) ChangesIn ELF, relocatable files generated for x86-32 and some code models of Fix #61101: record that Full diff: https://github.com/llvm/llvm-project/pull/89463.diff 8 Files Affected:
diff --git a/lld/test/ELF/lto/i386-global-offset-table.ll b/lld/test/ELF/lto/i386-global-offset-table.ll
new file mode 100644
index 00000000000000..e470763a3eb2ec
--- /dev/null
+++ b/lld/test/ELF/lto/i386-global-offset-table.ll
@@ -0,0 +1,22 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.bc
+; RUN: ld.lld %t.bc -o %t
+
+target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+define dso_local void @f() {
+entry:
+ ret void
+}
+
+define dso_local void @_start() {
+entry:
+ call void @f()
+ ret void
+}
+
+!llvm.module.flags = !{!0, !1}
+
+!0 = !{i32 8, !"PIC Level", i32 2}
+!1 = !{i32 7, !"PIE Level", i32 2}
diff --git a/lld/test/ELF/lto/x86-64-global-offset-table.ll b/lld/test/ELF/lto/x86-64-global-offset-table.ll
new file mode 100644
index 00000000000000..1db1027e7a21c5
--- /dev/null
+++ b/lld/test/ELF/lto/x86-64-global-offset-table.ll
@@ -0,0 +1,57 @@
+; REQUIRES: x86
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o
+
+; RUN: cat a.ll medium.ll | llvm-as - -o medium.bc
+; RUN: ld.lld -pie --no-relax medium.bc b.o -o medium
+; RUN: llvm-objdump -d medium | FileCheck %s
+
+; RUN: cat a.ll large.ll | llvm-as - -o large.bc
+; RUN: ld.lld -pie large.bc b.o -o large
+; RUN: llvm-objdump -d large | FileCheck %s
+
+; RUN: cat a.ll medium.ll ref.ll | llvm-as - -o ref.bc
+; RUN: ld.lld -pie --no-relax -u ref ref.bc b.o -o ref
+; RUN: llvm-objdump -d ref | FileCheck %s
+
+; CHECK: movabsq
+
+;--- a.ll
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@i = external global i32
+
+define dso_local void @_start() {
+entry:
+ %0 = load i32, ptr @i
+ %inc = add nsw i32 %0, 1
+ store i32 %inc, ptr @i
+ ret void
+}
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 8, !"PIC Level", i32 2}
+!1 = !{i32 7, !"PIE Level", i32 2}
+!2 = !{i32 1, !"Large Data Threshold", i64 0}
+
+;--- medium.ll
+!3 = !{i32 1, !"Code Model", i32 3}
+
+;--- large.ll
+!3 = !{i32 1, !"Code Model", i32 4}
+
+;--- ref.ll
+@_GLOBAL_OFFSET_TABLE_ = external global [0 x i8]
+
+define dso_local ptr @ref() {
+entry:
+ ret ptr @_GLOBAL_OFFSET_TABLE_
+}
+
+;--- b.s
+.data
+.globl i
+i:
+.long 0
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp
index 07f76688fa43e7..d8f520ad02c2f2 100644
--- a/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -175,6 +175,20 @@ void ModuleSymbolTable::CollectAsmSymbols(
AsmSymbol(Key, BasicSymbolRef::Flags(Res));
}
});
+
+ // In ELF, object code generated for x86-32 and some code models of x86-64 may
+ // reference the special symbol _GLOBAL_OFFSET_TABLE_ that is not used in the
+ // IR. Record it like inline asm symbols.
+ Triple TT(M.getTargetTriple());
+ if (!TT.isOSBinFormatELF() || !TT.isX86())
+ return;
+ auto CM = M.getCodeModel();
+ if (TT.getArch() == Triple::x86 || CM == CodeModel::Medium ||
+ CM == CodeModel::Large) {
+ AsmSymbol("_GLOBAL_OFFSET_TABLE_",
+ BasicSymbolRef::Flags(BasicSymbolRef::SF_Undefined |
+ BasicSymbolRef::SF_Global));
+ }
}
void ModuleSymbolTable::CollectAsmSymvers(
diff --git a/llvm/test/LTO/X86/codemodel-2.ll b/llvm/test/LTO/X86/codemodel-2.ll
index 5cd9731606f2bd..fc1074bcf2235c 100644
--- a/llvm/test/LTO/X86/codemodel-2.ll
+++ b/llvm/test/LTO/X86/codemodel-2.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
-; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s
; RUN: llvm-objdump --no-print-imm-hex -d %t.s.0 | FileCheck %s --check-prefix=CHECK-LARGE
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/codemodel-3.ll b/llvm/test/LTO/X86/codemodel-3.ll
index 947221e9f36dc5..13702dfbca2da4 100644
--- a/llvm/test/LTO/X86/codemodel-3.ll
+++ b/llvm/test/LTO/X86/codemodel-3.ll
@@ -1,6 +1,7 @@
; RUN: llvm-as %s -o %t0.o
; RUN: llvm-as < %p/Inputs/codemodel-3.ll > %t1.o
-; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
+; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px -r %t0.o,_GLOBAL_OFFSET_TABLE_, \
+; RUN: -r %t1.o,_GLOBAL_OFFSET_TABLE_, %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/llvm/test/LTO/X86/largedatathreshold-1.ll b/llvm/test/LTO/X86/largedatathreshold-1.ll
index e3be5c11baaac2..dfd8319511b617 100644
--- a/llvm/test/LTO/X86/largedatathreshold-1.ll
+++ b/llvm/test/LTO/X86/largedatathreshold-1.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
-; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s
; RUN: llvm-objdump -d %t.s.0 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/largedatathreshold-2.ll b/llvm/test/LTO/X86/largedatathreshold-2.ll
index 103c066b744d0f..59438bbdb5027f 100644
--- a/llvm/test/LTO/X86/largedatathreshold-2.ll
+++ b/llvm/test/LTO/X86/largedatathreshold-2.ll
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
-; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s
; RUN: llvm-objdump -d %t.s.0 | FileCheck %s
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/LTO/X86/largedatathreshold-3.ll b/llvm/test/LTO/X86/largedatathreshold-3.ll
index 3c0653db334d85..fea7987ff15566 100644
--- a/llvm/test/LTO/X86/largedatathreshold-3.ll
+++ b/llvm/test/LTO/X86/largedatathreshold-3.ll
@@ -1,6 +1,7 @@
; RUN: llvm-as %s -o %t0.o
; RUN: llvm-as < %p/Inputs/largedatathreshold.ll > %t1.o
-; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
+; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px -r %t0.o,_GLOBAL_OFFSET_TABLE_, \
+; RUN: -r %t1.o,_GLOBAL_OFFSET_TABLE_, %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
; CHECK: 'Large Data Threshold': IDs have conflicting values
|
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.
A few questions about tests below. Also, ModuleSymbolTable::CollectAsmSymbols is called when building the ModuleSummaryIndex for ThinLTO - I don't see any ThinLTO tests modified or added here - do we need one to make sure nothing surprising happens in that mode?
@@ -0,0 +1,22 @@ | |||
; REQUIRES: x86 |
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.
What is this test testing?
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.
Thanks for the review. Added a file-level comment.
; RUN: ld.lld -pie --no-relax -u ref ref.bc b.o -o ref | ||
; RUN: llvm-objdump -d ref | FileCheck %s | ||
|
||
; CHECK: movabsq |
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.
What is this checking for related to the GLOBAL_OFFSET_TABLE? Can you add a comment?
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.
Added The IR symbol table references _GLOBAL_OFFSET_TABLE_, which causes lld to define the symbol.
@@ -1,5 +1,5 @@ | |||
; RUN: llvm-as %s -o %t.o | |||
; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s | |||
; RUN: llvm-lto2 run -r %t.o,_start,px -r %t.o,_GLOBAL_OFFSET_TABLE_, %t.o -o %t.s |
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.
Why is it needed here and in other tests now?
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 x86-64 medium/large code model, the IR symbol table now references _GLOBAL_OFFSET_TABLE_
, which requires llvm-lto2 to provide it to avoid a missing symbol resolution for
error
I was trying to understand why we couldn't resolve |
Created using spr 1.3.5-bogner
lld only defines Codegen passes may reference a runtime library function or linker-defined symbols |
Linker-defined symbols seem different from runtime library symbols. Runtime library symbols have to be provided by some input object file. We can either do something similar to this PR and mark all LTO bitcode files as requiring any potential runtime library symbol (there are a lot, so it might take up noticeable space in the bitcode files), or have the linker special case them (which is what I believe lld does). But for linker-defined symbols, it seems like it's a fixable phase ordering issue by defining them after parsing object files created by LTO. Then we don't have to start special casing any of these types of symbols. Perhaps I'm missing something though. |
I think this patch is the right solution. We want the symbol table to be complete before This could be solved by adding a pass: making the linker try probing For runtime library symbols, ideally we the solution should be in LLVMLTO instead of linkers. However, given that we have to be very conservative, that'd cause a lot of overhead in bitcode files, so we accepted to workaround in linkers. |
ah, so you're saying that LTO bitcode files should be more like a normal object file and declare everything in their symbol table up front before actually creating object files. this is so that we can follow ELF linking logic to determine which subset of LTO bitcode files we want to link (after LTO-ing them and creating an object file)? I was missing the part where we performed normal ELF linking logic on bitcode files as well. although linker-created symbols don't really participate in this the same way normal symbols do... it still seems a weird to me that we can't move the call to I think this is a similar but reversed argument to your argument about the linker needing to know about runtime library calls, which I agree ideally would be in LTO bitcode files. the difference is that for runtime library calls, adding all potentially created runtime calls to the bitcode symbol table is expensive. but changing the order in which we call thoughts? |
(fwiw I think this change is an acceptable alternative, especially if the number of linker-defined symbols across all architectures that we need to special case is small) |
The intent was always that LTO would tell the linker which symbols may be used by the combined object file, and that it wouldn't be handled by the individual bitcode files. See |
More importantly, there would be no purpose in embedding the list in every object file. The bitcode symbol table is like a cache for the information in the rest of the bitcode file, and the behavior of the LLVM backend linked into lld is what ultimately matters for LTO because that's what generates library calls. Since the list is the same for every bitcode file, and it would go out of date if producer version != consumer version, the "cache" in the individual bitcode files would serve no purpose because |
The commit message states:
That mechanism and Technically linkers can add the special case to |
Isn't that just an implementation detail of lld? Basically, the behavior of
Right, LTO (on behalf of the LLVM backend) should be the source of truth of this information, and it can be accessed via |
I think it's related to an implementation detail of lld and other linkers, but more related to the LTO symbol resolution scheme. The IR symbol table should strive to provide a full picture. In this case, it knows the architecture and the code model and can make a best guess of whether
I hope that the linker only defines The IRSymTab code will likely be extended to be smarter on function-local inline asm symbols (beside current model-level inline asm symbols). |
Okay, that makes sense. |
@@ -0,0 +1,71 @@ | |||
; REQUIRES: x86 | |||
;; LTO-generated felocatable files may reference _GLOBAL_OFFSET_TABLE_ while |
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.
s/felocat/relocat/
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.
Thanks. Fixed
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.
lgtm with one comment fix below.
@@ -1,18 +1,25 @@ | |||
; REQUIRES: x86 | |||
; RUN: llvm-as %s -o %t.bc | |||
; RUN: ld.lld %t.bc -o %t | |||
;; LTO-generated felocatable files may reference _GLOBAL_OFFSET_TABLE_ while |
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.
relocatable
Created using spr 1.3.5-bogner
In ELF, relocatable files generated for x86-32 and some code models of
x86-64 (medium, large) may reference the special symbol
_GLOBAL_OFFSET_TABLE_
that is not used in the IR. In an LTO link, ifthere is no regular relocatable file referencing the special symbol, the
linker may not define the symbol and lead to a spurious "undefined
symbol" error.
Fix #61101: record that
_GLOBAL_OFFSET_TABLE_
is used in the IR symboltable.
Note: The
PreservedSymbols
mechanism(https://reviews.llvm.org/D112595) that just sets
FB_used
is notapplicable.
The
getRuntimeLibcallSymbols
for extracting lazy runtime librarysymbols is for symbols that are "always" potentially used, but linkers
don't have the code model information to make a precise decision.