summaryrefslogtreecommitdiffstats
path: root/lld/ELF/SyntheticSections.cpp
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2016-11-29 10:23:46 +0000
committerSimon Atanasyan <simon@atanasyan.com>2016-11-29 10:23:46 +0000
commit80f3d9ce939d0ff796c88ab82248dbfaed95f028 (patch)
treede9b12c2127c2a411f7a3f38a937598de0371f87 /lld/ELF/SyntheticSections.cpp
parentc211c6c8844a46f8ac795ef7998b81772bc99103 (diff)
downloadbcm5719-llvm-80f3d9ce939d0ff796c88ab82248dbfaed95f028.tar.gz
bcm5719-llvm-80f3d9ce939d0ff796c88ab82248dbfaed95f028.zip
[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. llvm-svn: 288127
Diffstat (limited to 'lld/ELF/SyntheticSections.cpp')
-rw-r--r--lld/ELF/SyntheticSections.cpp6
1 files changed, 3 insertions, 3 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 2da21771ef2..bb43a5b265b 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -538,7 +538,7 @@ MipsGotSection<ELFT>::getPageEntryOffset(uintX_t EntryValue) {
// 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 MipsGotSection<ELFT>::finalize() {
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);
OpenPOWER on IntegriCloud