Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -399,6 +399,9 @@ if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) return true; + if (&Body == ElfSym::GlobalOffsetTable) + return true; + error("relocation " + toString(Type) + " cannot refer to absolute symbol: " + toString(Body) + getLocation(S, Body, RelOff)); return true; Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -317,6 +317,9 @@ static DefinedRegular *End1; static DefinedRegular *End2; + // _GLOBAL_OFFSET_TABLE_ + static DefinedRegular *GlobalOffsetTable; + // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS. static DefinedRegular *MipsGp; static DefinedRegular *MipsGpDisp; Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -35,6 +35,7 @@ DefinedRegular *ElfSym::Edata2; DefinedRegular *ElfSym::End1; DefinedRegular *ElfSym::End2; +DefinedRegular *ElfSym::GlobalOffsetTable; DefinedRegular *ElfSym::MipsGp; DefinedRegular *ElfSym::MipsGpDisp; DefinedRegular *ElfSym::MipsLocalGp; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -827,7 +827,8 @@ // an undefined symbol in the .o files. // Given that the symbol is effectively unused, we just create a dummy // hidden one to avoid the undefined symbol error. - Symtab::X->addIgnored("_GLOBAL_OFFSET_TABLE_"); + ElfSym::GlobalOffsetTable = + Symtab::X->addIgnored("_GLOBAL_OFFSET_TABLE_"); // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For // static linking the linker is required to optimize away any references to @@ -1751,6 +1752,9 @@ if (ElfSym::Bss) ElfSym::Bss->Section = findSectionInScript(".bss"); + if (ElfSym::GlobalOffsetTable && InX::Got) + ElfSym::GlobalOffsetTable->Value = InX::Got->getVA(); + // Setup MIPS _gp_disp/__gnu_local_gp symbols which should // be equal to the _gp symbol's value. if (Config->EMachine == EM_MIPS && !ElfSym::MipsGp->Value) { Index: test/ELF/arm-got-relative.s =================================================================== --- test/ELF/arm-got-relative.s +++ test/ELF/arm-got-relative.s @@ -31,7 +31,7 @@ // CHECK-NEXT: 0x204C R_ARM_GLOB_DAT function 0x0 // CHECK: Name: _GLOBAL_OFFSET_TABLE_ -// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Value: 0x2048 // CHECK-NEXT: Size: // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None Index: test/ELF/arm-got-relative2.s =================================================================== --- test/ELF/arm-got-relative2.s +++ test/ELF/arm-got-relative2.s @@ -0,0 +1,52 @@ +// REQUIRES: arm +// RUN: llvm-mc -position-independent -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +// RUN: ld.lld %t.o -shared -o %t +// RUN: llvm-readobj -s -symbols -dyn-relocations %t | FileCheck %s +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s + .syntax unified + .text + .globl _start + .align 2 +_start: + .type _start, %function + ldr r3, .LGOT + ldr r2, .LGOT+4 +.LPIC: + add r0, pc, r3 + bx lr + .align 2 +.LGOT: + +.word _GLOBAL_OFFSET_TABLE_ - (.LPIC+8) + .word function(GOT) + + .globl function + .align 2 +function: + .type function, %function + bx lr + +// CHECK: Dynamic Relocations { +// CHECK-NEXT: 0x2048 R_ARM_GLOB_DAT function 0x0 + +// CHECK: Name: _GLOBAL_OFFSET_TABLE_ +// CHECK-NEXT: Value: 0x2048 +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: Absolute + +// CODE: Disassembly of section .text: +// CODE-NEXT: _start: +// CODE-NEXT: 1000: 08 30 9f e5 ldr r3, [pc, #8] +// CODE-NEXT: 1004: 08 20 9f e5 ldr r2, [pc, #8] +// CODE-NEXT: 1008: 03 00 8f e0 add r0, pc, r3 +// CODE-NEXT: 100c: 1e ff 2f e1 bx lr +// CODE:$d.1: +// (_GLOBAL_OFFSET_TABLE_ = 0x2048) - (0x1008 + 8) 0x1038 +// CODE-NEXT: 1010: 38 10 00 00 +// (Got(function) - GotBase = 0x4 +// CODE-NEXT: 1014: 00 00 00 00