[lld] [llvm] IRSymTab: Record _GLOBAL_OFFSET_TABLE_ for ELF x86 (PR #89463)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 19 16:34:42 PDT 2024
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/89463
>From 6d4cbc5f98fc4e5863302cded35cedb550c576ed Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Fri, 19 Apr 2024 15:21:25 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.5-bogner
---
lld/test/ELF/lto/i386-global-offset-table.ll | 22 +++++++
.../ELF/lto/x86-64-global-offset-table.ll | 57 +++++++++++++++++++
llvm/lib/Object/ModuleSymbolTable.cpp | 14 +++++
llvm/test/LTO/X86/codemodel-2.ll | 2 +-
llvm/test/LTO/X86/codemodel-3.ll | 3 +-
llvm/test/LTO/X86/largedatathreshold-1.ll | 2 +-
llvm/test/LTO/X86/largedatathreshold-2.ll | 2 +-
llvm/test/LTO/X86/largedatathreshold-3.ll | 3 +-
8 files changed, 100 insertions(+), 5 deletions(-)
create mode 100644 lld/test/ELF/lto/i386-global-offset-table.ll
create mode 100644 lld/test/ELF/lto/x86-64-global-offset-table.ll
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"
+
+ at 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
+ at _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
More information about the llvm-commits
mailing list