diff options
author | Fangrui Song <i@maskray.me> | 2024-04-23 17:02:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-23 17:02:21 -0700 |
commit | 99e7350235055654aaa923701bf36adaf01739d0 (patch) | |
tree | 3ca5bfe2b7d20cd4ee35df6fd9cc5244863d29db /llvm/lib/Object | |
parent | 9c4735e9b3be717eaf1ea524842b5968bf2c6513 (diff) | |
download | llvm-99e7350235055654aaa923701bf36adaf01739d0.zip llvm-99e7350235055654aaa923701bf36adaf01739d0.tar.gz llvm-99e7350235055654aaa923701bf36adaf01739d0.tar.bz2 |
IRSymTab: Record _GLOBAL_OFFSET_TABLE_ for ELF x86
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, if
there 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 symbol
table.
Note: The `PreservedSymbols` mechanism
(https://reviews.llvm.org/D112595) that just sets `FB_used` is not
applicable.
The `getRuntimeLibcallSymbols` for extracting lazy runtime library
symbols is for symbols that are "always" potentially used, but linkers
don't have the code model information to make a precise decision.
Pull Request: https://github.com/llvm/llvm-project/pull/89463
Diffstat (limited to 'llvm/lib/Object')
-rw-r--r-- | llvm/lib/Object/ModuleSymbolTable.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp index 07f7668..d8f520a 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( |