diff --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp --- a/lld/ELF/Arch/X86.cpp +++ b/lld/ELF/Arch/X86.cpp @@ -97,7 +97,7 @@ case R_386_PC32: return R_PC; case R_386_GOTPC: - return R_GOTONLY_PC_FROM_END; + return R_GOTPLTONLY_PC; case R_386_TLS_IE: return R_GOT; case R_386_GOT32: diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -121,7 +121,7 @@ return R_GOTREL_FROM_END; case R_X86_64_GOTPC32: case R_X86_64_GOTPC64: - return R_GOTONLY_PC_FROM_END; + return R_GOTPLTONLY_PC; case R_X86_64_NONE: return R_NONE; default: diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -624,8 +624,8 @@ return Sym.getGotVA() + A; case R_GOTONLY_PC: return In.Got->getVA() + A - P; - case R_GOTONLY_PC_FROM_END: - return In.Got->getVA() + A - P + In.Got->getSize(); + case R_GOTPLTONLY_PC: + return In.GotPlt->getVA() + A - P; case R_GOTREL: return Sym.getVA(A) - In.Got->getVA(); case R_GOTREL_FROM_END: diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -33,7 +33,7 @@ R_ADDEND, R_GOT, R_GOTONLY_PC, - R_GOTONLY_PC_FROM_END, + R_GOTPLTONLY_PC, R_GOTREL, R_GOTREL_FROM_END, R_GOT_FROM_END, diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -402,7 +402,7 @@ R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD, R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, - R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOT_FROM_END, + R_GOTPLTONLY_PC, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOT_FROM_END, R_TLSGD_PC, R_PPC_CALL_PLT, R_TLSDESC_CALL, R_AARCH64_TLSDESC_PAGE, R_HINT, R_TLSLD_HINT, R_TLSIE_HINT>(E)) return true; @@ -1067,7 +1067,7 @@ // This relocation does not require got entry, but it is relative to got and // needs it to be created. Here we request for that. - if (oneof(Expr)) In.Got->HasGotOffRel = true; diff --git a/lld/test/ELF/i386-gotpc-dynamic.s b/lld/test/ELF/i386-gotpc-dynamic.s --- a/lld/test/ELF/i386-gotpc-dynamic.s +++ b/lld/test/ELF/i386-gotpc-dynamic.s @@ -20,13 +20,29 @@ # CHECK-NEXT: AddressAlignment: # CHECK-NEXT: EntrySize: # CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 8 +# CHECK-NEXT: Name: .got.plt +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x3000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } -## 0x1000 + 4144 = 0x2030 -# DISASM: 1000: {{.*}} movl $4144, %eax +## 0x3000 - 0x1000 = 8192 +# DISASM: 1000: {{.*}} movl $8192, %eax .section .foo,"ax",@progbits foo: - movl $bar@got-., %eax # R_386_GOTPC + movl $_GLOBAL_OFFSET_TABLE_@got-., %eax # R_386_GOTPC .local bar bar: diff --git a/lld/test/ELF/i386-gotpc.s b/lld/test/ELF/i386-gotpc.s --- a/lld/test/ELF/i386-gotpc.s +++ b/lld/test/ELF/i386-gotpc.s @@ -24,5 +24,5 @@ // DISASM: Disassembly of section .text: // DISASM-NEXT: .text: -// DISASM-NEXT: 1000: {{.*}} movl $4144, %eax -// 0x2030 - 0x1000 = 0x1030 +// DISASM-NEXT: 1000: {{.*}} movl $8192, %eax +// 0x3000 - 0x1000 = 8192 diff --git a/lld/test/ELF/relocation-i686.s b/lld/test/ELF/relocation-i686.s --- a/lld/test/ELF/relocation-i686.s +++ b/lld/test/ELF/relocation-i686.s @@ -67,7 +67,7 @@ // CHECK: Disassembly of section .R_386_GOTPC: // CHECK-NEXT: R_386_GOTPC: -// CHECK-NEXT: 401014: {{.*}} movl $4204, %eax +// CHECK-NEXT: 401014: {{.*}} movl $8172, %eax .section .dynamic_reloc, "ax",@progbits call bar diff --git a/lld/test/ELF/x86-64-reloc-gotoff64.s b/lld/test/ELF/x86-64-reloc-gotoff64.s --- a/lld/test/ELF/x86-64-reloc-gotoff64.s +++ b/lld/test/ELF/x86-64-reloc-gotoff64.s @@ -6,6 +6,7 @@ // SECTION: .dynamic DYNAMIC 0000000000002000 // SECTION: .got PROGBITS 0000000000002070 002070 000000 +// SECTION: .got.plt PROGBITS 0000000000003000 003000 000018 // All the _GLOBAL_OFFSET_TABLE_ occurrences below refer to the address // of GOT base, not the address of the symbol _GLOBAL_OFFSET_TABLE_. These @@ -20,9 +21,9 @@ // extern long _DYNAMIC[] __attribute__((visibility("hidden"))); // long* dynamic() { return _DYNAMIC; } -// 0x2070 (.got end) - 0x1007 = 4201 +// 0x3000 (.got.plt start) - 0x1007 = 8185 // 0x2000 (_DYNAMIC) - 0x2070 (.got end) = -112 -// CHECK: 1000: {{.*}} leaq 4201(%rip), %rdx +// CHECK: 1000: {{.*}} leaq 8185(%rip), %rdx // CHECK-NEXT: 1007: {{.*}} movabsq $-112, %rax .global dynamic dynamic: diff --git a/lld/test/ELF/x86-64-reloc-gotpc64.s b/lld/test/ELF/x86-64-reloc-gotpc64.s --- a/lld/test/ELF/x86-64-reloc-gotpc64.s +++ b/lld/test/ELF/x86-64-reloc-gotpc64.s @@ -5,10 +5,11 @@ // RUN: llvm-objdump -d %t.so | FileCheck %s // SECTION: .got PROGBITS 0000000000002070 002070 000000 +// SECTION: .got.plt PROGBITS 0000000000003000 003000 000018 -// 0x2070 (.got end) - 0x1000 = 4208 +// 0x3000 (.got.plt start) - 0x1000 = 8192 // CHECK: gotpc64: -// CHECK-NEXT: 1000: {{.*}} movabsq $4208, %r11 +// CHECK-NEXT: 1000: {{.*}} movabsq $8192, %r11 .global gotpc64 gotpc64: movabsq $_GLOBAL_OFFSET_TABLE_-., %r11