Skip to content

Commit f70c5be

Browse files
committedNov 22, 2017
[ELF] Fix DT_MIPS_LOCAL_GOTNO value for thunks and linker scripts
The MIPS GOT section has a number of local entries based on the number of pages needed for output sections referenced by GOT page relocations. The number is recorded in the DT_MIPS_LOCAL_GOTNO dynamic section tag. However, the dynamic tag is added before assignAddresses has been called, meaning that any section size used to calculate the value will not include size modifications caused by, for example, linker scripts and thunks. This change moves the calculation of DT_MIPS_LOCAL_GOTNO until writeTo, by which time the output section sizes have been finalized. Reviewers: ruiu, rafael Differential Revision: https://reviews.llvm.org/D39493 llvm-svn: 318828
1 parent 72e5d69 commit f70c5be

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed
 

‎lld/ELF/SyntheticSections.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,11 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
11271127
add({DT_MIPS_FLAGS, RHF_NOTPOT});
11281128
add({DT_MIPS_BASE_ADDRESS, Target->getImageBase()});
11291129
add({DT_MIPS_SYMTABNO, InX::DynSymTab->getNumSymbols()});
1130-
add({DT_MIPS_LOCAL_GOTNO, InX::MipsGot->getLocalEntriesNum()});
1130+
1131+
// The number of local GOT entries has not yet been finalized. This value
1132+
// will be set in writeTo().
1133+
add({DT_MIPS_LOCAL_GOTNO, uint64_t(0)});
1134+
11311135
if (const Symbol *B = InX::MipsGot->getFirstGlobalEntry())
11321136
add({DT_MIPS_GOTSYM, B->DynsymIndex});
11331137
else
@@ -1162,7 +1166,10 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
11621166
P->d_un.d_ptr = E.Sym->getVA();
11631167
break;
11641168
case Entry::PlainInt:
1165-
P->d_un.d_val = E.Val;
1169+
if (Config->EMachine == EM_MIPS && E.Tag == DT_MIPS_LOCAL_GOTNO)
1170+
P->d_un.d_val = InX::MipsGot->getLocalEntriesNum();
1171+
else
1172+
P->d_un.d_val = E.Val;
11661173
break;
11671174
}
11681175
++P;

‎lld/test/ELF/mips-got-script.s

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Check number of got entries is adjusted for linker script-added space.
2+
3+
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4+
# RUN: echo "SECTIONS { .data : { *(.data.1); . += 0x10000; *(.data.2) } }" > %t.script
5+
# RUN: ld.lld %t.o -shared -o %t.so -T %t.script
6+
# RUN: llvm-readobj -mips-plt-got -dynamic-table %t.so | FileCheck %s
7+
8+
# REQUIRES: mips
9+
10+
# CHECK: 0x7000000A MIPS_LOCAL_GOTNO 5
11+
# ^-- 2 * header + 3 local entries
12+
# CHECK: Local entries [
13+
# CHECK-NEXT: Entry {
14+
# CHECK-NEXT: Address:
15+
# CHECK-NEXT: Access: -32744
16+
# CHECK-NEXT: Initial: 0x0
17+
# ^-- loc1
18+
# CHECK-NEXT: }
19+
# CHECK-NEXT: Entry {
20+
# CHECK-NEXT: Address:
21+
# CHECK-NEXT: Access: -32740
22+
# CHECK-NEXT: Initial: 0x10000
23+
# ^-- loc2
24+
# CHECK-NEXT: }
25+
# CHECK-NEXT: Entry {
26+
# CHECK-NEXT: Address:
27+
# CHECK-NEXT: Access: -32736
28+
# CHECK-NEXT: Initial: 0x20000
29+
# ^-- redundant
30+
# CHECK-NEXT: }
31+
# CHECK-NEXT: ]
32+
33+
.text
34+
.globl foo
35+
foo:
36+
lw $t0, %got(loc1)($gp)
37+
addi $t0, $t0, %lo(loc1)
38+
lw $t0, %got(loc2)($gp)
39+
addi $t0, $t0, %lo(loc2)
40+
41+
.section .data.1,"aw",%progbits
42+
loc1:
43+
.word 0
44+
45+
.section .data.2,"aw",%progbits
46+
loc2:
47+
.word 0

0 commit comments

Comments
 (0)