This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[20/20] MIPS GOT: Count GOT entries in mips_elf_recreate_got


This patch merges the GOT counting into mips_elf_resolve_final_got_entries.
I think that makes logical sense and also avoids a separate htab_traverse.

Richard


bfd/
	* elfxx-mips.c (mips_elf_count_got_entries): Delete.
	(mips_elf_check_recreate_got, mips_elf_recreate_got): Take a
	mips_elf_traverse_got_arg.  Count GOT entries.
	(mips_elf_resolve_final_got_entries): Take the bfd_link_info
	as argument.  Update after above changes.
	(mips_elf_merge_got, mips_elf_lay_out_got): Don't call
	mips_elf_count_got_entries.  Update the calls to
	mips_elf_resolve_final_got_entries.

Index: bfd/elfxx-mips.c
===================================================================
--- bfd/elfxx-mips.c	2013-02-11 16:52:45.000000000 +0000
+++ bfd/elfxx-mips.c	2013-02-11 16:55:07.360652770 +0000
@@ -2979,23 +2979,6 @@ mips_elf_count_got_entry (struct bfd_lin
     g->global_gotno += 1;
 }
 
-/* A htab_traverse callback.  Count the number of GOT entries and
-   TLS relocations required for the GOT entry in *ENTRYP.  DATA points
-   to a mips_elf_traverse_got_arg structure.  */
-
-static int
-mips_elf_count_got_entries (void **entryp, void *data)
-{
-  struct mips_got_entry *entry;
-  struct mips_elf_traverse_got_arg *arg;
-
-  entry = (struct mips_got_entry *) *entryp;
-  arg = (struct mips_elf_traverse_got_arg *) data;
-  mips_elf_count_got_entry (arg->info, arg->g, entry);
-
-  return 1;
-}
-
 /* Output a simple dynamic relocation into SRELOC.  */
 
 static void
@@ -3861,17 +3844,19 @@ mips_elf_allocate_dynamic_relocations (b
     }
 }
 
-/* A htab_traverse callback for GOT entries.  Set boolean *DATA to true
-   if the GOT entry is for an indirect or warning symbol.  */
+/* A htab_traverse callback for GOT entries, with DATA pointing to a
+   mips_elf_traverse_got_arg structure.  Count the number of GOT
+   entries and TLS relocs.  Set DATA->value to true if we need
+   to resolve indirect or warning symbols and then recreate the GOT.  */
 
 static int
 mips_elf_check_recreate_got (void **entryp, void *data)
 {
   struct mips_got_entry *entry;
-  bfd_boolean *must_recreate;
+  struct mips_elf_traverse_got_arg *arg;
 
   entry = (struct mips_got_entry *) *entryp;
-  must_recreate = (bfd_boolean *) data;
+  arg = (struct mips_elf_traverse_got_arg *) data;
   if (entry->abfd != NULL && entry->symndx == -1)
     {
       struct mips_elf_link_hash_entry *h;
@@ -3880,27 +3865,28 @@ mips_elf_check_recreate_got (void **entr
       if (h->root.root.type == bfd_link_hash_indirect
 	  || h->root.root.type == bfd_link_hash_warning)
 	{
-	  *must_recreate = TRUE;
+	  arg->value = TRUE;
 	  return 0;
 	}
     }
+  mips_elf_count_got_entry (arg->info, arg->g, entry);
   return 1;
 }
 
-/* A htab_traverse callback for GOT entries.  Add all entries to
-   hash table *DATA, converting entries for indirect and warning
-   symbols into entries for the target symbol.  Set *DATA to null
-   on error.  */
+/* A htab_traverse callback for GOT entries, with DATA pointing to a
+   mips_elf_traverse_got_arg structure.  Add all entries to DATA->g,
+   converting entries for indirect and warning symbols into entries
+   for the target symbol.  Set DATA->g to null on error.  */
 
 static int
 mips_elf_recreate_got (void **entryp, void *data)
 {
-  htab_t *new_got;
   struct mips_got_entry new_entry, *entry;
+  struct mips_elf_traverse_got_arg *arg;
   void **slot;
 
-  new_got = (htab_t *) data;
   entry = (struct mips_got_entry *) *entryp;
+  arg = (struct mips_elf_traverse_got_arg *) data;
   if (entry->abfd != NULL
       && entry->symndx == -1
       && (entry->d.h->root.root.type == bfd_link_hash_indirect
@@ -3920,10 +3906,10 @@ mips_elf_recreate_got (void **entryp, vo
 	     || h->root.root.type == bfd_link_hash_warning);
       entry->d.h = h;
     }
-  slot = htab_find_slot (*new_got, entry, INSERT);
+  slot = htab_find_slot (arg->g->got_entries, entry, INSERT);
   if (slot == NULL)
     {
-      *new_got = NULL;
+      arg->g = NULL;
       return 0;
     }
   if (*slot == NULL)
@@ -3933,12 +3919,13 @@ mips_elf_recreate_got (void **entryp, vo
 	  entry = bfd_alloc (entry->abfd, sizeof (*entry));
 	  if (!entry)
 	    {
-	      *new_got = NULL;
+	      arg->g = NULL;
 	      return 0;
 	    }
 	  *entry = new_entry;
 	}
       *slot = entry;
+      mips_elf_count_got_entry (arg->info, arg->g, entry);
     }
   return 1;
 }
@@ -3947,24 +3934,32 @@ mips_elf_recreate_got (void **entryp, vo
    replace them with entries for the target symbol.  */
 
 static bfd_boolean
-mips_elf_resolve_final_got_entries (struct mips_got_info *g)
+mips_elf_resolve_final_got_entries (struct bfd_link_info *info,
+				    struct mips_got_info *g)
 {
-  bfd_boolean must_recreate;
-  htab_t new_got;
+  struct mips_elf_traverse_got_arg tga;
+  struct mips_got_info oldg;
+
+  oldg = *g;
+
+  tga.info = info;
+  tga.g = g;
+  tga.value = FALSE;
+  htab_traverse (g->got_entries, mips_elf_check_recreate_got, &tga);
+  if (tga.value)
+    {
+      *g = oldg;
+      g->got_entries = htab_create (htab_size (oldg.got_entries),
+				    mips_elf_got_entry_hash,
+				    mips_elf_got_entry_eq, NULL);
+      if (!g->got_entries)
+	return FALSE;
 
-  must_recreate = FALSE;
-  htab_traverse (g->got_entries, mips_elf_check_recreate_got, &must_recreate);
-  if (must_recreate)
-    {
-      new_got = htab_create (htab_size (g->got_entries),
-			     mips_elf_got_entry_hash,
-			     mips_elf_got_entry_eq, NULL);
-      htab_traverse (g->got_entries, mips_elf_recreate_got, &new_got);
-      if (new_got == NULL)
+      htab_traverse (oldg.got_entries, mips_elf_recreate_got, &tga);
+      if (!tga.g)
 	return FALSE;
 
-      htab_delete (g->got_entries);
-      g->got_entries = new_got;
+      htab_delete (oldg.got_entries);
     }
   return TRUE;
 }
@@ -4134,17 +4129,12 @@ mips_elf_merge_got_with (bfd *abfd, stru
 mips_elf_merge_got (bfd *abfd, struct mips_got_info *g,
 		    struct mips_elf_got_per_bfd_arg *arg)
 {
-  struct mips_elf_traverse_got_arg tga;
   unsigned int estimate;
   int result;
 
-  if (!mips_elf_resolve_final_got_entries (g))
+  if (!mips_elf_resolve_final_got_entries (arg->info, g))
     return FALSE;
 
-  tga.info = arg->info;
-  tga.g = g;
-  htab_traverse (g->got_entries, mips_elf_count_got_entries, &tga);
-
   /* Work out the number of page, local and TLS entries.  */
   estimate = arg->max_pages;
   if (estimate > g->page_gotno)
@@ -8608,11 +8598,6 @@ mips_elf_lay_out_got (bfd *output_bfd, s
   g->local_gotno += htab->reserved_gotno;
   g->assigned_gotno = htab->reserved_gotno;
 
-  /* Replace entries for indirect and warning symbols with entries for
-     the target symbol.  */
-  if (!mips_elf_resolve_final_got_entries (g))
-    return FALSE;
-
   /* Decide which symbols need to go in the global part of the GOT and
      count the number of reloc-only GOT symbols.  */
   mips_elf_link_hash_traverse (htab, mips_elf_count_got_symbols, info);
@@ -8652,10 +8637,10 @@ mips_elf_lay_out_got (bfd *output_bfd, s
 
   g->local_gotno += page_gotno;
 
-  /* Count the number of GOT entries and TLS relocs.  */
-  tga.info = info;
-  tga.g = g;
-  htab_traverse (g->got_entries, mips_elf_count_got_entries, &tga);
+  /* Replace entries for indirect and warning symbols with entries for
+     the target symbol.  Count the number of GOT entries and TLS relocs.  */
+  if (!mips_elf_resolve_final_got_entries (info, g))
+    return FALSE;
 
   s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
   s->size += g->global_gotno * MIPS_ELF_GOT_SIZE (output_bfd);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]