Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -825,9 +825,16 @@ // The situation is even stranger on x86_64 where the assembly doesn't // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as // 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_"); + // For ARM the clang assembler may not have treated _GLOBAL_OFFSET_TABLE_ as + // special so we may encounter a R_ARM_REL32 to _GLOBAL_OFFSET_TABLE_ which + // will only evaluate correctly if _GLOBAL_OFFSET_TABLE_ is at the base of the + // .got section. for other architectures, given that the symbol is + // effectively unused, we just create a dummy hidden one to avoid the + // undefined symbol error. + if (Config->EMachine == EM_ARM && InX::Got) + addOptionalRegular("_GLOBAL_OFFSET_TABLE_", InX::Got, 0); + else + 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 Index: test/ELF/arm-got-relative.s =================================================================== --- test/ELF/arm-got-relative.s +++ test/ELF/arm-got-relative.s @@ -16,9 +16,9 @@ bx lr .align 2 .LGOT: - // gas implicitly uses (GOT_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC - // llvm-mc needs the (GOT_PREL) suffix or it generates R_ARM_REL32 - .word _GLOBAL_OFFSET_TABLE_(GOT_PREL) - (.LPIC+8) + // gas implicitly uses (R_ARM_BASE_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC + // llvm-mc generates R_ARM_REL32, this will need updating when MC changes + .word _GLOBAL_OFFSET_TABLE_ - (.LPIC+8) .word function(GOT) .globl function @@ -28,17 +28,17 @@ bx lr // CHECK: Dynamic Relocations { -// CHECK-NEXT: 0x204C R_ARM_GLOB_DAT function 0x0 +// CHECK-NEXT: 0x2048 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 // CHECK-NEXT: Other [ // CHECK-NEXT: STV_HIDDEN // CHECK-NEXT: ] -// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: Section: .got // CODE: Disassembly of section .text: // CODE-NEXT: _start: @@ -49,5 +49,5 @@ // CODE:$d.1: // (_GLOBAL_OFFSET_TABLE_ = 0x2048) - (0x1008 + 8) 0x1038 // CODE-NEXT: 1010: 38 10 00 00 -// (Got(function) - GotBase = 0x4 -// CODE-NEXT: 1014: 04 00 00 00 +// (Got(function) - GotBase = 0x0 +// CODE-NEXT: 1014: 00 00 00 00