Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -212,9 +212,20 @@ // _GLOBAL_OFFSET_TABLE_ and _SDA_BASE_ from the 32-bit ABI. It is used to // represent the TOC base which is offset by 0x8000 bytes from the start of // the .got section. - ElfSym::GlobalOffsetTable = addOptionalRegular( - (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_", - Out::ElfHeader, Target->GotBaseSymOff); + // We do not allow _GLOBAL_OFFSET_TABLE_ to be defined by input objects as the + // correctness of some relocations depends on its value. + StringRef GotTableSymName = + (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_"; + if (Symbol *S = Symtab->find(GotTableSymName)) { + if (S->isDefined()) + error(toString(S->File) + " cannot redefine linker defined symbol '" + + GotTableSymName + "'"); + else + ElfSym::GlobalOffsetTable = Symtab->addDefined( + GotTableSymName, STV_HIDDEN, STT_NOTYPE, Target->GotBaseSymOff, + /*Size=*/0, STB_GLOBAL, Out::ElfHeader, + /*File=*/nullptr); + } // __ehdr_start is the location of ELF file headers. Note that we define // this symbol unconditionally even when using a linker script, which Index: lld/trunk/test/ELF/global-offset-table-position-redef-err.s =================================================================== --- lld/trunk/test/ELF/global-offset-table-position-redef-err.s +++ lld/trunk/test/ELF/global-offset-table-position-redef-err.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s + +# On some targets the location of the _GLOBAL_OFFSET_TABLE_ symbol table can +# matter for the correctness of some relocations. Follow the example of ld.gold +# and give a multiple definition error if input objects attempt to redefine it. + +# CHECK: ld.lld: error: {{.*o}} cannot redefine linker defined symbol '_GLOBAL_OFFSET_TABLE_' + +.data +.global _GLOBAL_OFFSET_TABLE_ +_GLOBAL_OFFSET_TABLE_: +.word 0