MIPS: Fix GOT page counter in multi-got links
authorJames Cowgill <james.cowgill@mips.com>
Thu, 5 Apr 2018 15:47:53 +0000 (08:47 -0700)
committerCary Coutant <ccoutant@gmail.com>
Thu, 5 Apr 2018 15:47:53 +0000 (08:47 -0700)
The record_got_page_entry function records and updates the maximum
number of GOT page entries which may be required by an object. In the
case where an existing GOT page entry was expanded, only the entry
belonging to output GOT would have its page count updated. This leaves
the entry belonging to the object GOT with the num_pages count of 1 it
was originally initialized with. Later on when GOTs are being merged in a
multi-got link, this causes the value of entry->num_pages in
add_got_page_entries to always be 1 and underestimates the number of pages
required for the new entry. This in turn leads to an assertion failure in
get_got_page_offset where we run out of pages.

Fix by obtaining the object's GOT entry unconditionally and not just
the first time it gets created. Now that entry2 is always valid, remove
the useless NULL checks.

gold/
PR gold/22770
* mips.cc (Mips_got_info::record_got_page_entry): Fetch existing
page entries for the object's GOT.

gold/ChangeLog
gold/mips.cc

index 0e6ec0ce14926e5f356214e80f8293c6ace899c5..c1776b50e80397a8039d678aac6336fb851527ec 100644 (file)
@@ -1,3 +1,9 @@
+2018-04-05  James Cowgill  <james.cowgill@mips.com>
+
+       PR gold/22770
+       * mips.cc (Mips_got_info::record_got_page_entry): Fetch existing
+       page entries for the object's GOT.
+
 2018-04-05  Alan Modra  <amodra@gmail.com>
 
        * powerpc.cc (Target_powerpc::make_brlt_section): Make .branch_lt relro.
index ee2c037ad538f07f137c1ff0de2bd20df1dcd9ef..5d0ae739f6fa6faa666dca1ca6b361ecbacb7627 100644 (file)
@@ -5795,13 +5795,14 @@ Mips_got_info<size, big_endian>::record_got_page_entry(
     this->got_page_entries_.insert(entry);
 
   // Add the same entry to the OBJECT's GOT.
-  Got_page_entry* entry2 = NULL;
+  Got_page_entry* entry2 = new Got_page_entry(*entry);
   Mips_got_info<size, big_endian>* g2 = object->get_or_create_got_info();
-  if (g2->got_page_entries_.find(entry) == g2->got_page_entries_.end())
-    {
-      entry2 = new Got_page_entry(*entry);
-      g2->got_page_entries_.insert(entry2);
-    }
+  typename Got_page_entry_set::iterator it2 =
+    g2->got_page_entries_.find(entry);
+  if (it2 != g2->got_page_entries_.end())
+    entry2 = *it2;
+  else
+    g2->got_page_entries_.insert(entry2);
 
   // Skip over ranges whose maximum extent cannot share a page entry
   // with ADDEND.
@@ -5822,8 +5823,7 @@ Mips_got_info<size, big_endian>::record_got_page_entry(
 
       *range_ptr = range;
       ++entry->num_pages;
-      if (entry2 != NULL)
-        ++entry2->num_pages;
+      ++entry2->num_pages;
       ++this->page_gotno_;
       ++g2->page_gotno_;
       return;
@@ -5852,8 +5852,7 @@ Mips_got_info<size, big_endian>::record_got_page_entry(
   if (old_pages != new_pages)
     {
       entry->num_pages += new_pages - old_pages;
-      if (entry2 != NULL)
-        entry2->num_pages += new_pages - old_pages;
+      entry2->num_pages += new_pages - old_pages;
       this->page_gotno_ += new_pages - old_pages;
       g2->page_gotno_ += new_pages - old_pages;
     }