[lld] r288127 - [ELF][MIPS] Fix calculation of GOT "page address" entries number

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 29 02:23:47 PST 2016


Author: atanasyan
Date: Tue Nov 29 04:23:46 2016
New Revision: 288127

URL: http://llvm.org/viewvc/llvm-project?rev=288127&view=rev
Log:
[ELF][MIPS] Fix calculation of GOT "page address" entries number

If output section which referenced by R_MIPS_GOT_PAGE or R_MIPS_GOT16
relocations is small (less that 0x10000 bytes) and occupies two adjacent
0xffff-bytes pages, current formula gives incorrect number of required "page"
GOT entries. The problem is that in time of calculation we do not know
the section address and so we cannot calculate number of 0xffff-bytes
pages exactly.

This patch fix the formula. Now it gives a correct number of pages in
the worst case when "small" section intersects 0xffff-bytes page
boundary. From the other side, sometimes it adds one more redundant GOT
entry for each output section. But usually number of output sections
referenced by GOT relocations is small.

Added:
    lld/trunk/test/ELF/mips-got-page.s
Modified:
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/test/ELF/mips-64-got.s
    lld/trunk/test/ELF/mips-got-redundant.s
    lld/trunk/test/ELF/mips-got16.s
    lld/trunk/test/ELF/mips-xgot-order.s

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=288127&r1=288126&r2=288127&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Nov 29 04:23:46 2016
@@ -538,7 +538,7 @@ MipsGotSection<ELFT>::getPageEntryOffset
   // See comment in the MipsGotSection::writeTo.
   size_t NewIndex = PageIndexMap.size() + 2;
   auto P = PageIndexMap.insert(std::make_pair(EntryValue, NewIndex));
-  assert(!P.second || PageIndexMap.size() <= PageEntriesNum);
+  assert(!P.second || PageIndexMap.size() <= (PageEntriesNum - 2));
   return (uintX_t)P.first->second * sizeof(uintX_t);
 }
 
@@ -594,14 +594,14 @@ template <class ELFT> void MipsGotSectio
   size_t EntriesNum = TlsEntries.size();
   // Take into account MIPS GOT header.
   // See comment in the MipsGotSection::writeTo.
-  PageEntriesNum += 2;
+  PageEntriesNum = 2;
   for (const OutputSectionBase *OutSec : OutSections) {
     // Calculate an upper bound of MIPS GOT entries required to store page
     // addresses of local symbols. We assume the worst case - each 64kb
     // page of the output section has at least one GOT relocation against it.
     // Add 0x8000 to the section's size because the page address stored
     // in the GOT entry is calculated as (value + 0x8000) & ~0xffff.
-    PageEntriesNum += (OutSec->Size + 0x8000 + 0xfffe) / 0xffff;
+    PageEntriesNum += (OutSec->Size + 0xfffe) / 0xffff + 1;
   }
   EntriesNum += getLocalEntriesNum() + GlobalEntries.size();
   Size = EntriesNum * sizeof(uintX_t);

Modified: lld/trunk/test/ELF/mips-64-got.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-64-got.s?rev=288127&r1=288126&r2=288127&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-64-got.s (original)
+++ lld/trunk/test/ELF/mips-64-got.s Tue Nov 29 04:23:46 2016
@@ -14,9 +14,9 @@
 
 # CHECK-NEXT:    20000:   df 82 80 20   ld      $2, -32736($gp)
 # CHECK-NEXT:    20004:   64 42 00 18   daddiu  $2,  $2, 24
-# CHECK-NEXT:    20008:   24 42 80 38   addiu   $2,  $2, -32712
-# CHECK-NEXT:    2000c:   24 42 80 28   addiu   $2,  $2, -32728
-# CHECK-NEXT:    20010:   24 42 80 30   addiu   $2,  $2, -32720
+# CHECK-NEXT:    20008:   24 42 80 40   addiu   $2,  $2, -32704
+# CHECK-NEXT:    2000c:   24 42 80 30   addiu   $2,  $2, -32720
+# CHECK-NEXT:    20010:   24 42 80 38   addiu   $2,  $2, -32712
 
 # CHECK: 0000000000020018   .text   00000000 foo
 # CHECK: 0000000000037ff0   .got    00000000 .hidden _gp
@@ -50,18 +50,23 @@
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x30018
 # GOT-NEXT:       Access: -32728
-# GOT-NEXT:       Initial: 0x20014
+# GOT-NEXT:       Initial: 0x0
 # GOT-NEXT:     }
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x30020
 # GOT-NEXT:       Access: -32720
+# GOT-NEXT:       Initial: 0x20014
+# GOT-NEXT:     }
+# GOT-NEXT:     Entry {
+# GOT-NEXT:       Address: 0x30028
+# GOT-NEXT:       Access: -32712
 # GOT-NEXT:       Initial: 0x20018
 # GOT-NEXT:     }
 # GOT-NEXT:   ]
 # GOT-NEXT:   Global entries [
 # GOT-NEXT:     Entry {
-# GOT-NEXT:       Address: 0x30028
-# GOT-NEXT:       Access: -32712
+# GOT-NEXT:       Address: 0x30030
+# GOT-NEXT:       Access: -32704
 # GOT-NEXT:       Initial: 0x0
 # GOT-NEXT:       Value: 0x0
 # GOT-NEXT:       Type: Function

Added: lld/trunk/test/ELF/mips-got-page.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-got-page.s?rev=288127&view=auto
==============================================================================
--- lld/trunk/test/ELF/mips-got-page.s (added)
+++ lld/trunk/test/ELF/mips-got-page.s Tue Nov 29 04:23:46 2016
@@ -0,0 +1,40 @@
+# Check the case when small section (less that 0x10000 bytes) occupies
+# two adjacent 0xffff-bytes pages. We need to create two GOT entries
+# for R_MIPS_GOT_PAGE relocations.
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -o %t.o %s
+# RUN: ld.lld --section-start .rodata=0x27FFC -shared -o %t.so %t.o
+# RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK:       Name: bar
+# CHECK-NEXT:  Value: 0x28000
+#                     ^ page-address = (0x28000 + 0x8000) & ~0xffff = 0x30000
+
+# CHECK:       Name: foo
+# CHECK-NEXT:  Value: 0x27FFC
+#                     ^ page-address = (0x27ffc + 0x8000) & ~0xffff = 0x20000
+
+# CHECK:      Local entries [
+# CHECK-NEXT:   Entry {
+# CHECK-NEXT:     Address:
+# CHECK-NEXT:     Access: -32736
+# CHECK-NEXT:     Initial: 0x20000
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Entry {
+# CHECK-NEXT:     Address:
+# CHECK-NEXT:     Access: -32728
+# CHECK-NEXT:     Initial: 0x30000
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+  .text
+  ld      $v0,%got_page(foo)($gp)
+  ld      $v0,%got_page(bar)($gp)
+
+  .rodata
+foo:
+  .word 0
+bar:
+  .word 0

Modified: lld/trunk/test/ELF/mips-got-redundant.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-got-redundant.s?rev=288127&r1=288126&r2=288127&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-got-redundant.s (original)
+++ lld/trunk/test/ELF/mips-got-redundant.s Tue Nov 29 04:23:46 2016
@@ -22,6 +22,12 @@
 # CHECK-NEXT:   Entry {
 # CHECK-NEXT:     Address: 0x20010
 # CHECK-NEXT:     Access: -32736
+# CHECK-NEXT:     Initial: 0x0
+#                          ^-- redundant
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Entry {
+# CHECK-NEXT:     Address: 0x20014
+# CHECK-NEXT:     Access: -32732
 # CHECK-NEXT:     Initial: 0x40008
 #                          ^-- glb1
 # CHECK-NEXT:   }

Modified: lld/trunk/test/ELF/mips-got16.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-got16.s?rev=288127&r1=288126&r2=288127&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-got16.s (original)
+++ lld/trunk/test/ELF/mips-got16.s Tue Nov 29 04:23:46 2016
@@ -17,9 +17,9 @@
 # CHECK-NEXT:    10014:       21 08 90 04     addi    $8, $8, -28668
 # CHECK-NEXT:    10018:       8f 88 80 20     lw      $8, -32736($gp)
 # CHECK-NEXT:    1001c:       21 08 10 04     addi    $8, $8, 4100
-# CHECK-NEXT:    10020:       8f 88 80 28     lw      $8, -32728($gp)
+# CHECK-NEXT:    10020:       8f 88 80 30     lw      $8, -32720($gp)
 # CHECK-NEXT:    10024:       21 08 10 08     addi    $8, $8, 4104
-# CHECK-NEXT:    10028:       8f 88 80 2c     lw      $8, -32724($gp)
+# CHECK-NEXT:    10028:       8f 88 80 34     lw      $8, -32716($gp)
 #
 # CHECK: SYMBOL TABLE:
 # CHECK: 00051008         .data           00000000 .hidden bar
@@ -72,15 +72,27 @@
 # GOT-NEXT:     }
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x20018
-# GOT-NEXT:       Access: -327
+# GOT-NEXT:       Access: -32728
+# GOT-NEXT:       Initial: 0x0
+#                          ^-- redundant unused entry
+# GOT-NEXT:     }
+# GOT-NEXT:     Entry {
+# GOT-NEXT:       Address: 0x2001C
+# GOT-NEXT:       Access: -32724
+# GOT-NEXT:       Initial: 0x0
+#                          ^-- redundant unused entry
+# GOT-NEXT:     }
+# GOT-NEXT:     Entry {
+# GOT-NEXT:       Address: 0x20020
+# GOT-NEXT:       Access: -32720
 # GOT-NEXT:       Initial: 0x51008
 #                          ^-- 'bar' address
 # GOT-NEXT:     }
 # GOT-NEXT:   ]
 # GOT-NEXT:   Global entries [
 # GOT-NEXT:     Entry {
-# GOT-NEXT:       Address: 0x2001C
-# GOT-NEXT:       Access: -32724
+# GOT-NEXT:       Address: 0x20024
+# GOT-NEXT:       Access: -32716
 # GOT-NEXT:       Initial: 0x0
 # GOT-NEXT:       Value: 0x0
 # GOT-NEXT:       Type: None

Modified: lld/trunk/test/ELF/mips-xgot-order.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-xgot-order.s?rev=288127&r1=288126&r2=288127&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-xgot-order.s (original)
+++ lld/trunk/test/ELF/mips-xgot-order.s Tue Nov 29 04:23:46 2016
@@ -10,22 +10,23 @@
 # CHECK:      Disassembly of section .text:
 # CHECK-NEXT: __start:
 # CHECK-NEXT:    20000:       3c 02 00 00     lui     $2, 0
-# CHECK-NEXT:    20004:       8c 42 80 20     lw      $2, -32736($2)
+# CHECK-NEXT:    20004:       8c 42 80 24     lw      $2, -32732($2)
 # CHECK-NEXT:    20008:       3c 02 00 00     lui     $2, 0
-# CHECK-NEXT:    2000c:       8c 42 80 24     lw      $2, -32732($2)
+# CHECK-NEXT:    2000c:       8c 42 80 28     lw      $2, -32728($2)
 #
 # CHECK:      bar:
-# CHECK-NEXT:    20010:       8c 42 80 1c     lw      $2, -32740($2)
+# CHECK-NEXT:    20010:       8c 42 80 20     lw      $2, -32736($2)
 # CHECK-NEXT:    20014:       8c 42 80 18     lw      $2, -32744($2)
 # CHECK-NEXT:    20018:       20 42 00 00     addi    $2, $2, 0
 
 # CHECK:      Contents of section .got:
-# CHECK-NEXT:  30000 00000000 80000000 00040000 00020010
+# CHECK-NEXT:  30000 00000000 80000000 00040000 00000000
 #                                      ^ %hi(loc)
-#                                               ^ %got(bar)
-# CHECK-NEXT:  30010 00020000 00040000
-#                    ^ %got_hi/lo(start)
-#                             ^ %got_hi/lo(loc)
+#                                               ^ redundant entry
+# CHECK-NEXT:  30010 00020010 00020000 00040000
+#                    ^ %got(bar)
+#                             ^ %got_hi/lo(start)
+#                                      ^ %got_hi/lo(loc)
 
 # CHECK: 00040000         .data           00000000 loc
 # CHECK: 00020000         .text           00000000 __start




More information about the llvm-commits mailing list