Skip to content
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

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions lld/test/ELF/lto/i386-global-offset-table.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
; REQUIRES: x86
Copy link
Contributor

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?

Copy link
Member Author

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.

;; LTO-generated felocatable files may reference _GLOBAL_OFFSET_TABLE_ while
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

relocatable

;; the IR does not mention _GLOBAL_OFFSET_TABLE_.
;; Test that there is no spurious "undefined symbol" error.

; RUN: rm -rf %t && mkdir %t && cd %t
; RUN: llvm-as %s -o a.bc
; RUN: ld.lld -pie a.bc -o a
; RUN: llvm-nm a | FileCheck %s

; CHECK: d _GLOBAL_OFFSET_TABLE_

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"

@i = global i32 0

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}

!0 = !{i32 8, !"PIC Level", i32 2}
!1 = !{i32 7, !"PIE Level", i32 2}
71 changes: 71 additions & 0 deletions lld/test/ELF/lto/x86-64-global-offset-table.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
; REQUIRES: x86
;; LTO-generated relocatable files may reference _GLOBAL_OFFSET_TABLE_ while
;; the IR does not mention _GLOBAL_OFFSET_TABLE_.
;; Test that there is no spurious "undefined symbol" error.

; RUN: rm -rf %t && split-file %s %t && cd %t
; RUN: opt -module-summary b.ll -o b.bc

;; Test Thin LTO.
; RUN: cat a.ll medium.ll | opt -module-summary - -o medium.bc
; RUN: ld.lld -pie --no-relax medium.bc b.bc -o medium
; RUN: llvm-objdump -dt medium | FileCheck %s

;; Test regular LTO.
; RUN: cat a.ll large.ll | llvm-as - -o large.bc
; RUN: ld.lld -pie large.bc b.bc -o large
; RUN: llvm-objdump -dt large | FileCheck %s

;; Explicit reference of _GLOBAL_OFFSET_TABLE_ is fine.
; RUN: cat a.ll medium.ll ref.ll | opt -module-summary - -o ref.bc
; RUN: ld.lld -pie -u ref ref.bc b.bc -y _GLOBAL_OFFSET_TABLE_ -o ref 2>&1 | FileCheck %s --check-prefix=TRACE
; RUN: llvm-objdump -dt ref | FileCheck %s

; TRACE: ref.bc: reference to _GLOBAL_OFFSET_TABLE_
; TRACE-NEXT: ref.bc: reference to _GLOBAL_OFFSET_TABLE_
; TRACE-NEXT: <internal>: definition of _GLOBAL_OFFSET_TABLE_
; TRACE-NEXT: ref.lto.ref.o: reference to _GLOBAL_OFFSET_TABLE_

;; The IR symbol table references _GLOBAL_OFFSET_TABLE_, which causes lld to define the symbol.
; CHECK: .got.plt 0000000000000000 .hidden _GLOBAL_OFFSET_TABLE_
; CHECK: movabsq
Copy link
Contributor

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?

Copy link
Member Author

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.


;--- 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.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 = global i32 0
14 changes: 14 additions & 0 deletions llvm/lib/Object/ModuleSymbolTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/LTO/X86/codemodel-2.ll
Original file line number Diff line number Diff line change
@@ -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
Copy link
Contributor

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?

Copy link
Member Author

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

; RUN: llvm-objdump --no-print-imm-hex -d %t.s.0 | FileCheck %s --check-prefix=CHECK-LARGE

target triple = "x86_64-unknown-linux-gnu"
Expand Down
3 changes: 2 additions & 1 deletion llvm/test/LTO/X86/codemodel-3.ll
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/LTO/X86/largedatathreshold-1.ll
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/LTO/X86/largedatathreshold-2.ll
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
3 changes: 2 additions & 1 deletion llvm/test/LTO/X86/largedatathreshold-3.ll
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Loading