[lld] r288129 - [ELF][MIPS] Do not change MipsGotSection state in the getPageEntryOffset method

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


Author: atanasyan
Date: Tue Nov 29 04:23:56 2016
New Revision: 288129

URL: http://llvm.org/viewvc/llvm-project?rev=288129&view=rev
Log:
[ELF][MIPS] Do not change MipsGotSection state in the getPageEntryOffset method

The MipsGotSection::getPageEntryOffset calculates index of GOT entry
with a "page" address. Previously this method changes the state
of MipsGotSection because it modifies PageIndexMap field. That leads
to the unpredictable results if getPageEntryOffset called from multiple threads.

The patch makes getPageEntryOffset constant. To do so it calculates GOT
entry index but does not update PageIndexMap field. Later in the
MipsGotSection::writeTo method linker calculates "page" addresses and
writes them to the output.

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    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/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=288129&r1=288128&r2=288129&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Nov 29 04:23:56 2016
@@ -423,7 +423,7 @@ static typename ELFT::uint getSymVA(uint
     // should be initialized by 'page address'. This address is high 16-bits
     // of sum the symbol's value and the addend.
     return In<ELFT>::MipsGot->getVA() +
-           In<ELFT>::MipsGot->getPageEntryOffset(Body.getVA<ELFT>(A)) -
+           In<ELFT>::MipsGot->getPageEntryOffset(Body, A) -
            In<ELFT>::MipsGot->getGp();
   case R_MIPS_GOT_OFF:
   case R_MIPS_GOT_OFF32:

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=288129&r1=288128&r2=288129&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Nov 29 04:23:56 2016
@@ -470,8 +470,7 @@ void MipsGotSection<ELFT>::addEntry(Symb
     // sections referenced by GOT relocations. Then later in the `finalize`
     // method calculate number of "pages" required to cover all saved output
     // section and allocate appropriate number of GOT entries.
-    auto *OutSec = cast<DefinedRegular<ELFT>>(&Sym)->Section->OutSec;
-    OutSections.insert(OutSec);
+    PageIndexMap.insert({cast<DefinedRegular<ELFT>>(&Sym)->Section->OutSec, 0});
     return;
   }
   if (Sym.isTls()) {
@@ -528,18 +527,25 @@ template <class ELFT> bool MipsGotSectio
   return true;
 }
 
+static uint64_t getMipsPageAddr(uint64_t Addr) {
+  return (Addr + 0x8000) & ~0xffff;
+}
+
+static uint64_t getMipsPageCount(uint64_t Size) {
+  return (Size + 0xfffe) / 0xffff + 1;
+}
+
 template <class ELFT>
 typename MipsGotSection<ELFT>::uintX_t
-MipsGotSection<ELFT>::getPageEntryOffset(uintX_t EntryValue) {
-  // Initialize the entry by the %hi(EntryValue) expression
-  // but without right-shifting.
-  EntryValue = (EntryValue + 0x8000) & ~0xffff;
-  // Take into account MIPS GOT header.
-  // See comment in the MipsGotSection::writeTo.
-  size_t NewIndex = PageIndexMap.size();
-  auto P = PageIndexMap.insert(std::make_pair(EntryValue, NewIndex));
-  assert(!P.second || PageIndexMap.size() <= PageEntriesNum);
-  return (HeaderEntriesNum + P.first->second) * sizeof(uintX_t);
+MipsGotSection<ELFT>::getPageEntryOffset(const SymbolBody &B,
+                                         uintX_t Addend) const {
+  const OutputSectionBase *OutSec =
+      cast<DefinedRegular<ELFT>>(&B)->Section->OutSec;
+  uintX_t SecAddr = getMipsPageAddr(OutSec->Addr);
+  uintX_t SymAddr = getMipsPageAddr(B.getVA<ELFT>(Addend));
+  uintX_t Index = PageIndexMap.lookup(OutSec) + (SymAddr - SecAddr) / 0xffff;
+  assert(Index < PageEntriesNum);
+  return (HeaderEntriesNum + Index) * sizeof(uintX_t);
 }
 
 template <class ELFT>
@@ -589,20 +595,19 @@ unsigned MipsGotSection<ELFT>::getLocalE
 }
 
 template <class ELFT> void MipsGotSection<ELFT>::finalize() {
-  size_t EntriesNum = TlsEntries.size();
-  // Take into account MIPS GOT header.
-  // See comment in the MipsGotSection::writeTo.
   PageEntriesNum = 0;
-  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 + 0xfffe) / 0xffff + 1;
+  for (std::pair<const OutputSectionBase *, size_t> &P : PageIndexMap) {
+    // For each output section referenced by GOT page relocations calculate
+    // and save into PageIndexMap 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. And take in account the case when the section intersects
+    // page boundaries.
+    P.second = PageEntriesNum;
+    PageEntriesNum += getMipsPageCount(P.first->Size);
   }
-  EntriesNum += getLocalEntriesNum() + GlobalEntries.size();
-  Size = EntriesNum * sizeof(uintX_t);
+  Size = (getLocalEntriesNum() + GlobalEntries.size() + TlsEntries.size()) *
+         sizeof(uintX_t);
 }
 
 template <class ELFT> bool MipsGotSection<ELFT>::empty() const {
@@ -640,9 +645,13 @@ template <class ELFT> void MipsGotSectio
   P[1] = uintX_t(1) << (ELFT::Is64Bits ? 63 : 31);
   Buf += HeaderEntriesNum * sizeof(uintX_t);
   // Write 'page address' entries to the local part of the GOT.
-  for (std::pair<uintX_t, size_t> &L : PageIndexMap) {
-    uint8_t *Entry = Buf + L.second * sizeof(uintX_t);
-    writeUint<ELFT>(Entry, L.first);
+  for (std::pair<const OutputSectionBase *, size_t> &L : PageIndexMap) {
+    size_t PageCount = getMipsPageCount(L.first->Size);
+    uintX_t FirstPageAddr = getMipsPageAddr(L.first->Addr);
+    for (size_t PI = 0; PI < PageCount; ++PI) {
+      uint8_t *Entry = Buf + (L.second + PI) * sizeof(uintX_t);
+      writeUint<ELFT>(Entry, FirstPageAddr + PI * 0x10000);
+    }
   }
   Buf += PageEntriesNum * sizeof(uintX_t);
   auto AddEntry = [&](const GotEntry &SA) {

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=288129&r1=288128&r2=288129&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Tue Nov 29 04:23:56 2016
@@ -104,7 +104,7 @@ public:
   void addEntry(SymbolBody &Sym, uintX_t Addend, RelExpr Expr);
   bool addDynTlsEntry(SymbolBody &Sym);
   bool addTlsIndex();
-  uintX_t getPageEntryOffset(uintX_t Addr);
+  uintX_t getPageEntryOffset(const SymbolBody &B, uintX_t Addend) const;
   uintX_t getBodyEntryOffset(const SymbolBody &B, uintX_t Addend) const;
   uintX_t getGlobalDynOffset(const SymbolBody &B) const;
 
@@ -168,10 +168,9 @@ private:
   static const unsigned HeaderEntriesNum = 2;
   // Number of allocated "Page" entries.
   uint32_t PageEntriesNum = 0;
-  // Output sections referenced by MIPS GOT relocations.
-  llvm::SmallPtrSet<const OutputSectionBase *, 10> OutSections;
-  // Map from "page" address to the GOT index.
-  llvm::DenseMap<uintX_t, size_t> PageIndexMap;
+  // Map output sections referenced by MIPS GOT relocations
+  // to the first index of "Page" entries allocated for this section.
+  llvm::SmallDenseMap<const OutputSectionBase *, size_t> PageIndexMap;
 
   typedef std::pair<const SymbolBody *, uintX_t> GotEntry;
   typedef std::vector<GotEntry> GotEntries;

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=288129&r1=288128&r2=288129&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-64-got.s (original)
+++ lld/trunk/test/ELF/mips-64-got.s Tue Nov 29 04:23:56 2016
@@ -50,7 +50,7 @@
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x30018
 # GOT-NEXT:       Access: -32728
-# GOT-NEXT:       Initial: 0x0
+# GOT-NEXT:       Initial: 0x30000
 # GOT-NEXT:     }
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x30020

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=288129&r1=288128&r2=288129&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-got-redundant.s (original)
+++ lld/trunk/test/ELF/mips-got-redundant.s Tue Nov 29 04:23:56 2016
@@ -22,7 +22,7 @@
 # CHECK-NEXT:   Entry {
 # CHECK-NEXT:     Address: 0x20010
 # CHECK-NEXT:     Access: -32736
-# CHECK-NEXT:     Initial: 0x0
+# CHECK-NEXT:     Initial: 0x50000
 #                          ^-- redundant
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Entry {

Modified: lld/trunk/test/ELF/mips-got16.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-got16.s?rev=288129&r1=288128&r2=288129&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-got16.s (original)
+++ lld/trunk/test/ELF/mips-got16.s Tue Nov 29 04:23:56 2016
@@ -11,11 +11,11 @@
 # CHECK-NEXT: __start:
 # CHECK-NEXT:    10000:       8f 88 80 18     lw      $8, -32744($gp)
 # CHECK-NEXT:    10004:       21 08 00 2c     addi    $8, $8, 44
-# CHECK-NEXT:    10008:       8f 88 80 1c     lw      $8, -32740($gp)
+# CHECK-NEXT:    10008:       8f 88 80 24     lw      $8, -32732($gp)
 # CHECK-NEXT:    1000c:       21 08 90 00     addi    $8, $8, -28672
-# CHECK-NEXT:    10010:       8f 88 80 20     lw      $8, -32736($gp)
+# CHECK-NEXT:    10010:       8f 88 80 28     lw      $8, -32728($gp)
 # CHECK-NEXT:    10014:       21 08 90 04     addi    $8, $8, -28668
-# CHECK-NEXT:    10018:       8f 88 80 20     lw      $8, -32736($gp)
+# CHECK-NEXT:    10018:       8f 88 80 28     lw      $8, -32728($gp)
 # CHECK-NEXT:    1001c:       21 08 10 04     addi    $8, $8, 4100
 # CHECK-NEXT:    10020:       8f 88 80 30     lw      $8, -32720($gp)
 # CHECK-NEXT:    10024:       21 08 10 08     addi    $8, $8, 4104
@@ -54,32 +54,32 @@
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x2000C
 # GOT-NEXT:       Access: -32740
-# GOT-NEXT:       Initial: 0x40000
-#                          ^-- (0x39000 + 0x8000) & ~0xffff
+# GOT-NEXT:       Initial: 0x20000
+#                          ^-- redundant unused entry
 # GOT-NEXT:     }
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x20010
 # GOT-NEXT:       Access: -32736
-# GOT-NEXT:       Initial: 0x50000
-#                          ^-- (0x39000 + 0x10004 + 0x8000) & ~0xffff
-#                          ^-- (0x39000 + 0x18004 + 0x8000) & ~0xffff
+# GOT-NEXT:       Initial: 0x30000
+#                          ^-- redundant unused entry
 # GOT-NEXT:     }
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x20014
 # GOT-NEXT:       Access: -32732
-# GOT-NEXT:       Initial: 0x0
-#                          ^-- redundant unused entry
+# GOT-NEXT:       Initial: 0x40000
+#                          ^-- (0x39000 + 0x8000) & ~0xffff
 # GOT-NEXT:     }
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x20018
 # GOT-NEXT:       Access: -32728
-# GOT-NEXT:       Initial: 0x0
-#                          ^-- redundant unused entry
+# GOT-NEXT:       Initial: 0x50000
+#                          ^-- (0x39000 + 0x10004 + 0x8000) & ~0xffff
+#                          ^-- (0x39000 + 0x18004 + 0x8000) & ~0xffff
 # GOT-NEXT:     }
 # GOT-NEXT:     Entry {
 # GOT-NEXT:       Address: 0x2001C
 # GOT-NEXT:       Access: -32724
-# GOT-NEXT:       Initial: 0x0
+# GOT-NEXT:       Initial: 0x60000
 #                          ^-- redundant unused entry
 # GOT-NEXT:     }
 # GOT-NEXT:     Entry {

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=288129&r1=288128&r2=288129&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-xgot-order.s (original)
+++ lld/trunk/test/ELF/mips-xgot-order.s Tue Nov 29 04:23:56 2016
@@ -20,7 +20,7 @@
 # CHECK-NEXT:    20018:       20 42 00 00     addi    $2, $2, 0
 
 # CHECK:      Contents of section .got:
-# CHECK-NEXT:  30000 00000000 80000000 00040000 00000000
+# CHECK-NEXT:  30000 00000000 80000000 00040000 00050000
 #                                      ^ %hi(loc)
 #                                               ^ redundant entry
 # CHECK-NEXT:  30010 00020010 00020000 00040000




More information about the llvm-commits mailing list