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]

[PATCH] Cache the MIPS GOT section


Following on from:

    http://sources.redhat.com/ml/binutils/2008-06/msg00267.html

we also find the .got section each time we need it, rather than caching
it in the hash table.  We then read the got info from the MIPS-specific
section data, rather than making that information available in the hash
table too.

Specifically, we use the function:

    mips_elf_got_section (dynobj, maybe_excluded)

to find the .got section for DYNOBJ.  It returns null if the section
doesn't exist.  If MAYBE_EXCLUDED is false, the function also returns
null if the .got section has been excluded.

We use:

    mips_elf_got_info (dynobj, sgot_ptr)

to read both the .got section (*SGOT_PTR) and the GOT info.

There are three uses of MAYBE_EXCLUDED:

  (1) within mips_elf_got_info itself, which returns the GOT info even
      when .got has been excluded.

  (2) within _bfd_mips_elf_hide_symbol, which likewise wants
      access to the GOT info even when .got has been excluded.

  (3) within mips_elf_create_got_section, which simply wants to
      know if .got has already been created.  This function may be called
      several times during the same link, and only the first call needs
      to do something.

If we put the got info in the hash table, uses like (1) and (2) can
get the info directly from there, without going through the .got
section data.  And if we put the .got _section_ in the hash table,
(3) can just read that field.

The only interesting uses of mips_got_section are then those for
which MAYBE_EXCLUDED == FALSE.  The patch therefore changes the
interface to:

    mips_elf_got_section (struct bfd_link_info *info)

and updates the callers accordingly.  (Note that later patches will
remove the function altogether.  This is just one step in a longer
process.)

The patch also replaces calls to mips_elf_got_info with direct accesses
to the hash-table field.  Functions like mips_elf_create_local_got_entry
already have access to the bfd_link_info, so there's no need for the
caller to provide the GOT info as a separate parameter.

Tested on mips64-linux-gnu and mips64el-linux-gnu.  OK to install?

Richard


bfd/
	* elfxx-mips.c (_mips_elf_section_data): Remove the "u.got_info" field.
	(mips_elf_link_hash_table): Add "sgot" and "got_info" fields.
	(_bfd_mips_elf_link_hash_table_create): Initialize them.
	(mips_elf_got_section): Always apply the !maybe_excluded behavior.
	(mips_elf_got_info): Delete.
	(mips_elf_initialize_tls_slots): Remove the DYNOBJ local variable.
	Adjust the call to mips_elf_got_section.
	(mips_elf_local_got_index): Don't call mips_elf_got_info.
	Update the call to mips_elf_create_local_got_entry.
	Use htab->got_info.
	(mips_elf_global_got_index): Don't call mips_elf_got_info;
	use htab->got_info and htab->sgot instead.
	(mips_elf_got_page): Don't call mips_elf_got_info.  Update the
	call to mips_elf_create_local_got_entry.
	(mips_elf_got16_entry): Likewise.
	(mips_elf_got_offset_from_index): Replace with DYNOBJ parameter
	with an INFO parameter.  Don't call mips_elf_got_info; use htab->sgot
	and htab->got_info instead.
	(mips_elf_create_local_got_entry): Remove the GG and SGOT parameters.
	Use htab->sgot and htab->got_info.
	(mips_elf_sort_hash_table): Remove the DYNOBJ local variable.
	Don't call mips_elf_got_info; use htab->got_info instead.
	(mips_elf_record_global_got_symbol): Turn G from a paramter to
	a local variable and read it from htab->got_info.
	(mips_elf_record_local_got_symbol): Replace the G parameter with
	an INFO parameter.  Make G a local variable and read it from
	htab->got_info instead.
	(mips_elf_record_got_page_entry): Likewise.
	(mips_elf_multi_got): Remove the G parameter and make it a local
	variable instead.  Read it from htab->got_info.
	(mips_elf_create_got_section): Cache the GOT section in htab->sgot.
	Store the GOT information in htab->got_info.
	(mips_elf_calculate_relocation): Don't call mips_elf_got_section
	and mips_elf_got_info; use htab->sgot and htab->got_info instead.
	Adjust the calls to mips_elf_got_offset_from_index and
	mips_elf_adjust_gp.
	(_bfd_mips_elf_check_relocs): Remove the G and SGOT local variables.
	Adjust the calls to mips_elf_record_local_got_symbol,
	mips_elf_record_global_got_symbol and mips_elf_record_got_page_entry.
	Use htab->sgot.
	(_bfd_mips_elf_always_size_sections): Remove the DYNOBJ local variable.
	Don't call mips_elf_got_info; use htab->sgot and htab->got_info instead.
	Update the call to mips_elf_multi_got.
	(_bfd_mips_elf_size_dynamic_sections): Don't call mips_elf_got_info;
	use htab->got_info instead.
	(_bfd_mips_elf_finish_dynamic_symbol): Update the call to
	mips_elf_got_section.  Get the got_info from the hash table
	rather than the GOT section.
	(_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
	(_bfd_mips_elf_finish_dynamic_sections): Likewise.
	(_bfd_mips_elf_hide_symbol): Don't call mips_elf_got_section;
	get the got_info from the hash table instead.  Remove the GOT
	local variable.
	(_bfd_mips_elf_final_link): Likewise.  Also remove the DYNOBJ
	local variable.

Index: bfd/elfxx-mips.c
===================================================================
--- bfd/elfxx-mips.c	2008-06-28 17:14:30.000000000 +0100
+++ bfd/elfxx-mips.c	2008-06-28 17:14:33.000000000 +0100
@@ -234,7 +234,6 @@ struct _mips_elf_section_data
   struct bfd_elf_section_data elf;
   union
   {
-    struct mips_got_info *got_info;
     bfd_byte *tdata;
   } u;
 };
@@ -364,6 +363,9 @@ struct mips_elf_link_hash_table
   asection *sgotplt;
   asection *splt;
   asection *sstubs;
+  asection *sgot;
+  /* The master GOT information.  */
+  struct mips_got_info *got_info;
   /* The size of the PLT header in bytes (VxWorks only).  */
   bfd_vma plt_header_size;
   /* The size of a PLT entry in bytes (VxWorks only).  */
@@ -520,8 +522,8 @@ #define cbRPDR sizeof (RPDR)
 #define rpdNil ((pRPDR) 0)
 
 static struct mips_got_entry *mips_elf_create_local_got_entry
-  (bfd *, struct bfd_link_info *, bfd *, struct mips_got_info *, asection *,
-   bfd_vma, unsigned long, struct mips_elf_link_hash_entry *, int);
+  (bfd *, struct bfd_link_info *, bfd *, bfd_vma, unsigned long,
+   struct mips_elf_link_hash_entry *, int);
 static bfd_boolean mips_elf_sort_hash_table_f
   (struct mips_elf_link_hash_entry *, void *);
 static bfd_vma mips_elf_high
@@ -2256,38 +2258,17 @@ mips_elf_rel_dyn_section (struct bfd_lin
   return sreloc;
 }
 
-/* Returns the GOT section for ABFD.  */
+/* Returns the GOT section, if it hasn't been excluded.  */
 
 static asection *
-mips_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
-{
-  asection *sgot = bfd_get_section_by_name (abfd, ".got");
-  if (sgot == NULL
-      || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
-    return NULL;
-  return sgot;
-}
-
-/* Returns the GOT information associated with the link indicated by
-   INFO.  If SGOTP is non-NULL, it is filled in with the GOT
-   section.  */
-
-static struct mips_got_info *
-mips_elf_got_info (bfd *abfd, asection **sgotp)
+mips_elf_got_section (struct bfd_link_info *info)
 {
-  asection *sgot;
-  struct mips_got_info *g;
-
-  sgot = mips_elf_got_section (abfd, TRUE);
-  BFD_ASSERT (sgot != NULL);
-  BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
-  g = mips_elf_section_data (sgot)->u.got_info;
-  BFD_ASSERT (g != NULL);
-
-  if (sgotp)
-    *sgotp = (sgot->flags & SEC_EXCLUDE) == 0 ? sgot : NULL;
+  struct mips_elf_link_hash_table *htab;
 
-  return g;
+  htab = mips_elf_hash_table (info);
+  if (htab->sgot == NULL || (htab->sgot->flags & SEC_EXCLUDE) != 0)
+    return NULL;
+  return htab->sgot;
 }
 
 /* Count the number of relocations needed for a TLS GOT entry, with
@@ -2423,11 +2404,9 @@ mips_elf_initialize_tls_slots (bfd *abfd
   int indx;
   asection *sreloc, *sgot;
   bfd_vma offset, offset2;
-  bfd *dynobj;
   bfd_boolean need_relocs = FALSE;
 
-  dynobj = elf_hash_table (info)->dynobj;
-  sgot = mips_elf_got_section (dynobj, FALSE);
+  sgot = mips_elf_got_section (info);
 
   indx = 0;
   if (h != NULL)
@@ -2614,20 +2593,18 @@ mips_elf_local_got_index (bfd *abfd, bfd
 			  bfd_vma value, unsigned long r_symndx,
 			  struct mips_elf_link_hash_entry *h, int r_type)
 {
-  asection *sgot;
-  struct mips_got_info *g;
+  struct mips_elf_link_hash_table *htab;
   struct mips_got_entry *entry;
 
-  g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
-
-  entry = mips_elf_create_local_got_entry (abfd, info, ibfd, g, sgot,
-					   value, r_symndx, h, r_type);
+  htab = mips_elf_hash_table (info);
+  entry = mips_elf_create_local_got_entry (abfd, info, ibfd, value,
+					   r_symndx, h, r_type);
   if (!entry)
     return MINUS_ONE;
 
   if (TLS_RELOC_P (r_type))
     {
-      if (entry->symndx == -1 && g->next == NULL)
+      if (entry->symndx == -1 && htab->got_info->next == NULL)
 	/* A type (3) entry in the single-GOT case.  We use the symbol's
 	   hash table entry to track the index.  */
 	return mips_tls_got_index (abfd, h->tls_got_offset, &h->tls_type,
@@ -2646,12 +2623,13 @@ mips_elf_local_got_index (bfd *abfd, bfd
 mips_elf_global_got_index (bfd *abfd, bfd *ibfd, struct elf_link_hash_entry *h,
 			   int r_type, struct bfd_link_info *info)
 {
+  struct mips_elf_link_hash_table *htab;
   bfd_vma index;
-  asection *sgot;
   struct mips_got_info *g, *gg;
   long global_got_dynindx = 0;
 
-  gg = g = mips_elf_got_info (abfd, &sgot);
+  htab = mips_elf_hash_table (info);
+  gg = g = htab->got_info;
   if (g->bfd2got && ibfd)
     {
       struct mips_got_entry e, *p;
@@ -2717,7 +2695,7 @@ mips_elf_global_got_index (bfd *abfd, bf
       index = ((h->dynindx - global_got_dynindx + g->local_gotno)
 	       * MIPS_ELF_GOT_SIZE (abfd));
     }
-  BFD_ASSERT (index < sgot->size);
+  BFD_ASSERT (index < htab->sgot->size);
 
   return index;
 }
@@ -2732,16 +2710,12 @@ mips_elf_global_got_index (bfd *abfd, bf
 mips_elf_got_page (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
 		   bfd_vma value, bfd_vma *offsetp)
 {
-  asection *sgot;
-  struct mips_got_info *g;
   bfd_vma page, index;
   struct mips_got_entry *entry;
 
-  g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
-
   page = (value + 0x8000) & ~(bfd_vma) 0xffff;
-  entry = mips_elf_create_local_got_entry (abfd, info, ibfd, g, sgot,
-					   page, 0, NULL, R_MIPS_GOT_PAGE);
+  entry = mips_elf_create_local_got_entry (abfd, info, ibfd, page, 0,
+					   NULL, R_MIPS_GOT_PAGE);
 
   if (!entry)
     return MINUS_ONE;
@@ -2762,8 +2736,6 @@ mips_elf_got_page (bfd *abfd, bfd *ibfd,
 mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
 		      bfd_vma value, bfd_boolean external)
 {
-  asection *sgot;
-  struct mips_got_info *g;
   struct mips_got_entry *entry;
 
   /* GOT16 relocations against local symbols are followed by a LO16
@@ -2773,13 +2745,11 @@ mips_elf_got16_entry (bfd *abfd, bfd *ib
   if (! external)
     value = mips_elf_high (value) << 16;
 
-  g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
-
   /* It doesn't matter whether the original relocation was R_MIPS_GOT16,
      R_MIPS16_GOT16, R_MIPS_CALL16, etc.  The format of the entry is the
      same in all cases.  */
-  entry = mips_elf_create_local_got_entry (abfd, info, ibfd, g, sgot,
-					   value, 0, NULL, R_MIPS_GOT16);
+  entry = mips_elf_create_local_got_entry (abfd, info, ibfd, value, 0,
+					   NULL, R_MIPS_GOT16);
   if (entry)
     return entry->gotidx;
   else
@@ -2790,16 +2760,17 @@ mips_elf_got16_entry (bfd *abfd, bfd *ib
    in the GOT.  */
 
 static bfd_vma
-mips_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd,
+mips_elf_got_offset_from_index (struct bfd_link_info *info, bfd *output_bfd,
 				bfd *input_bfd, bfd_vma index)
 {
+  struct mips_elf_link_hash_table *htab;
   asection *sgot;
   bfd_vma gp;
-  struct mips_got_info *g;
 
-  g = mips_elf_got_info (dynobj, &sgot);
+  htab = mips_elf_hash_table (info);
+  sgot = htab->sgot;
   gp = _bfd_get_gp_value (output_bfd)
-    + mips_elf_adjust_gp (output_bfd, g, input_bfd);
+    + mips_elf_adjust_gp (output_bfd, htab->got_info, input_bfd);
 
   return sgot->output_section->vma + sgot->output_offset + index - gp;
 }
@@ -2811,8 +2782,7 @@ mips_elf_got_offset_from_index (bfd *dyn
 
 static struct mips_got_entry *
 mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info,
-				 bfd *ibfd, struct mips_got_info *gg,
-				 asection *sgot, bfd_vma value,
+				 bfd *ibfd, bfd_vma value,
 				 unsigned long r_symndx,
 				 struct mips_elf_link_hash_entry *h,
 				 int r_type)
@@ -2828,10 +2798,10 @@ mips_elf_create_local_got_entry (bfd *ab
   entry.d.address = value;
   entry.tls_type = 0;
 
-  g = mips_elf_got_for_ibfd (gg, ibfd);
+  g = mips_elf_got_for_ibfd (htab->got_info, ibfd);
   if (g == NULL)
     {
-      g = mips_elf_got_for_ibfd (gg, abfd);
+      g = mips_elf_got_for_ibfd (htab->got_info, abfd);
       BFD_ASSERT (g != NULL);
     }
 
@@ -2892,7 +2862,7 @@ mips_elf_create_local_got_entry (bfd *ab
     }
 
   MIPS_ELF_PUT_WORD (abfd, value,
-		     (sgot->contents + entry.gotidx));
+		     (htab->sgot->contents + entry.gotidx));
 
   /* These GOT entries need a dynamic relocation on VxWorks.  */
   if (htab->is_vxworks)
@@ -2903,8 +2873,8 @@ mips_elf_create_local_got_entry (bfd *ab
       bfd_vma got_address;
 
       s = mips_elf_rel_dyn_section (info, FALSE);
-      got_address = (sgot->output_section->vma
-		     + sgot->output_offset
+      got_address = (htab->sgot->output_section->vma
+		     + htab->sgot->output_offset
 		     + entry.gotidx);
 
       loc = s->contents + (s->reloc_count++ * sizeof (Elf32_External_Rela));
@@ -2927,13 +2897,12 @@ mips_elf_create_local_got_entry (bfd *ab
 static bfd_boolean
 mips_elf_sort_hash_table (struct bfd_link_info *info, unsigned long max_local)
 {
+  struct mips_elf_link_hash_table *htab;
   struct mips_elf_hash_sort_data hsd;
   struct mips_got_info *g;
-  bfd *dynobj;
-
-  dynobj = elf_hash_table (info)->dynobj;
 
-  g = mips_elf_got_info (dynobj, NULL);
+  htab = mips_elf_hash_table (info);
+  g = htab->got_info;
 
   hsd.low = NULL;
   hsd.max_unref_got_dynindx =
@@ -3015,10 +2984,13 @@ mips_elf_sort_hash_table_f (struct mips_
 static bfd_boolean
 mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
 				   bfd *abfd, struct bfd_link_info *info,
-				   struct mips_got_info *g,
 				   unsigned char tls_flag)
 {
+  struct mips_elf_link_hash_table *htab;
   struct mips_got_entry entry, **loc;
+  struct mips_got_info *g;
+
+  htab = mips_elf_hash_table (info);
 
   /* A global symbol in the GOT must also be in the dynamic symbol
      table.  */
@@ -3036,6 +3008,7 @@ mips_elf_record_global_got_symbol (struc
     }
 
   /* Make sure we have a GOT to put this entry into.  */
+  g = htab->got_info;
   BFD_ASSERT (g != NULL);
 
   entry.abfd = abfd;
@@ -3085,11 +3058,17 @@ mips_elf_record_global_got_symbol (struc
 
 static bfd_boolean
 mips_elf_record_local_got_symbol (bfd *abfd, long symndx, bfd_vma addend,
-				  struct mips_got_info *g,
+				  struct bfd_link_info *info,
 				  unsigned char tls_flag)
 {
+  struct mips_elf_link_hash_table *htab;
+  struct mips_got_info *g;
   struct mips_got_entry entry, **loc;
 
+  htab = mips_elf_hash_table (info);
+  g = htab->got_info;
+  BFD_ASSERT (g != NULL);
+
   entry.abfd = abfd;
   entry.symndx = symndx;
   entry.d.addend = addend;
@@ -3151,20 +3130,27 @@ mips_elf_pages_for_range (const struct m
 }
 
 /* Record that ABFD has a page relocation against symbol SYMNDX and
-   that ADDEND is the addend for that relocation.  G is the GOT
-   information.  This function creates an upper bound on the number of
-   GOT slots required; no attempt is made to combine references to
-   non-overridable global symbols across multiple input files.  */
+   that ADDEND is the addend for that relocation.
+
+   This function creates an upper bound on the number of GOT slots
+   required; no attempt is made to combine references to non-overridable
+   global symbols across multiple input files.  */
 
 static bfd_boolean
-mips_elf_record_got_page_entry (bfd *abfd, long symndx, bfd_signed_vma addend,
-				struct mips_got_info *g)
+mips_elf_record_got_page_entry (struct bfd_link_info *info, bfd *abfd,
+				long symndx, bfd_signed_vma addend)
 {
+  struct mips_elf_link_hash_table *htab;
+  struct mips_got_info *g;
   struct mips_got_page_entry lookup, *entry;
   struct mips_got_page_range **range_ptr, *range;
   bfd_vma old_pages, new_pages;
   void **loc;
 
+  htab = mips_elf_hash_table (info);
+  g = htab->got_info;
+  BFD_ASSERT (g != NULL);
+
   /* Find the mips_got_page_entry hash table entry for this symbol.  */
   lookup.abfd = abfd;
   lookup.symndx = symndx;
@@ -3731,14 +3717,16 @@ mips_elf_adjust_gp (bfd *abfd, struct mi
 
 static bfd_boolean
 mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info,
-		    struct mips_got_info *g, asection *got,
-		    bfd_size_type pages)
+		    asection *got, bfd_size_type pages)
 {
+  struct mips_elf_link_hash_table *htab;
   struct mips_elf_got_per_bfd_arg got_per_bfd_arg;
   struct mips_elf_set_global_got_offset_arg set_got_offset_arg;
-  struct mips_got_info *gg;
+  struct mips_got_info *g, *gg;
   unsigned int assign;
 
+  htab = mips_elf_hash_table (info);
+  g = htab->got_info;
   g->bfd2got = htab_try_create (1, mips_elf_bfd2got_entry_hash,
 				mips_elf_bfd2got_entry_eq, NULL);
   if (g->bfd2got == NULL)
@@ -4113,7 +4101,7 @@ mips_elf_create_got_section (bfd *abfd, 
   htab = mips_elf_hash_table (info);
 
   /* This function may be called more than once.  */
-  s = mips_elf_got_section (abfd, TRUE);
+  s = htab->sgot;
   if (s)
     {
       if (! maybe_exclude)
@@ -4133,6 +4121,7 @@ mips_elf_create_got_section (bfd *abfd, 
   if (s == NULL
       || ! bfd_set_section_alignment (abfd, s, 4))
     return FALSE;
+  htab->sgot = s;
 
   /* Define the symbol _GLOBAL_OFFSET_TABLE_.  We don't do this in the
      linker script because we don't want to define the symbol if we
@@ -4174,7 +4163,7 @@ mips_elf_create_got_section (bfd *abfd, 
 					 mips_got_page_entry_eq, NULL);
   if (g->got_page_entries == NULL)
     return FALSE;
-  mips_elf_section_data (s)->u.got_info = g;
+  htab->got_info = g;
   mips_elf_section_data (s)->elf.this_hdr.sh_flags
     |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
 
@@ -4517,8 +4506,7 @@ mips_elf_calculate_relocation (bfd *abfd
   gp0 = _bfd_get_gp_value (input_bfd);
   gp = _bfd_get_gp_value (abfd);
   if (dynobj)
-    gp += mips_elf_adjust_gp (abfd, mips_elf_got_info (dynobj, NULL),
-			      input_bfd);
+    gp += mips_elf_adjust_gp (abfd, htab->got_info, input_bfd);
 
   if (gnu_local_gp_p)
     symbol = gp;
@@ -4583,13 +4571,10 @@ mips_elf_calculate_relocation (bfd *abfd
 		      || (info->shared
 			  && (info->symbolic || h->root.forced_local)
 			  && h->root.def_regular)))
-		{
-		  /* This is a static link or a -Bsymbolic link.  The
-		     symbol is defined locally, or was forced to be local.
-		     We must initialize this entry in the GOT.  */
-		  asection *sgot = mips_elf_got_section (dynobj, FALSE);
-		  MIPS_ELF_PUT_WORD (dynobj, symbol, sgot->contents + g);
-		}
+		/* This is a static link or a -Bsymbolic link.  The
+		   symbol is defined locally, or was forced to be local.
+		   We must initialize this entry in the GOT.  */
+		MIPS_ELF_PUT_WORD (dynobj, symbol, htab->sgot->contents + g);
 	    }
 	}
       else if (!htab->is_vxworks
@@ -4605,7 +4590,7 @@ mips_elf_calculate_relocation (bfd *abfd
 	}
 
       /* Convert GOT indices to actual offsets.  */
-      g = mips_elf_got_offset_from_index (dynobj, abfd, input_bfd, g);
+      g = mips_elf_got_offset_from_index (info, abfd, input_bfd, g);
       break;
     }
 
@@ -4837,7 +4822,7 @@ mips_elf_calculate_relocation (bfd *abfd
 	  if (value == MINUS_ONE)
 	    return bfd_reloc_outofrange;
 	  value
-	    = mips_elf_got_offset_from_index (dynobj, abfd, input_bfd, value);
+	    = mips_elf_got_offset_from_index (info, abfd, input_bfd, value);
 	  overflowed_p = mips_elf_overflow_p (value, 16);
 	  break;
 	}
@@ -4891,7 +4876,7 @@ mips_elf_calculate_relocation (bfd *abfd
       value = mips_elf_got_page (abfd, input_bfd, info, symbol + addend, NULL);
       if (value == MINUS_ONE)
 	return bfd_reloc_outofrange;
-      value = mips_elf_got_offset_from_index (dynobj, abfd, input_bfd, value);
+      value = mips_elf_got_offset_from_index (info, abfd, input_bfd, value);
       overflowed_p = mips_elf_overflow_p (value, 16);
       break;
 
@@ -6617,11 +6602,9 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
   bfd *dynobj;
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
-  struct mips_got_info *g;
   size_t extsymoff;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
-  asection *sgot;
   asection *sreloc;
   const struct elf_backend_data *bed;
   struct mips_elf_link_hash_table *htab;
@@ -6894,24 +6877,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 	}
     }
 
-  if (dynobj == NULL)
-    {
-      sgot = NULL;
-      g = NULL;
-    }
-  else
-    {
-      sgot = mips_elf_got_section (dynobj, FALSE);
-      if (sgot == NULL)
-	g = NULL;
-      else
-	{
-	  BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
-	  g = mips_elf_section_data (sgot)->u.got_info;
-	  BFD_ASSERT (g != NULL);
-	}
-    }
-
   sreloc = NULL;
   bed = get_elf_backend_data (abfd);
   rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
@@ -6948,7 +6913,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 	}
 
       /* Some relocs require a global offset table.  */
-      if (dynobj == NULL || sgot == NULL)
+      if (dynobj == NULL || htab->sgot == NULL)
 	{
 	  switch (r_type)
 	    {
@@ -6970,7 +6935,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 		elf_hash_table (info)->dynobj = dynobj = abfd;
 	      if (! mips_elf_create_got_section (dynobj, info, FALSE))
 		return FALSE;
-	      g = mips_elf_got_info (dynobj, &sgot);
 	      if (htab->is_vxworks && !info->shared)
 		{
 		  (*_bfd_error_handler)
@@ -7033,8 +6997,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 	     always evaluate to "G".  We don't count R_MIPS_GOT_HI16, or
 	     R_MIPS_CALL_HI16 because these are always followed by an
 	     R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16.  */
-	  if (! mips_elf_record_local_got_symbol (abfd, r_symndx,
-						  rel->r_addend, g, 0))
+	  if (!mips_elf_record_local_got_symbol (abfd, r_symndx,
+						 rel->r_addend, info, 0))
 	    return FALSE;
 	}
 
@@ -7060,7 +7024,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 		 entry, which will be allocated by adjust_dynamic_symbol.
 		 Otherwise, this symbol requires a global GOT entry.  */
 	      if ((!htab->is_vxworks || h->forced_local)
-		  && !mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
+		  && !mips_elf_record_global_got_symbol (h, abfd, info, 0))
 		return FALSE;
 
 	      /* We need a stub, not a plt entry for the undefined
@@ -7117,14 +7081,15 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 		}
 	      else
 		addend = rel->r_addend;
-	      if (!mips_elf_record_got_page_entry (abfd, r_symndx, addend, g))
+	      if (!mips_elf_record_got_page_entry (info, abfd, r_symndx,
+						   addend))
 		return FALSE;
 	      break;
 	    }
 	  /* Fall through.  */
 
 	case R_MIPS_GOT_DISP:
-	  if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
+	  if (h && !mips_elf_record_global_got_symbol (h, abfd, info, 0))
 	    return FALSE;
 	  break;
 
@@ -7156,15 +7121,17 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 		  (struct mips_elf_link_hash_entry *) h;
 		hmips->tls_type |= flag;
 
-		if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, flag))
+		if (h && !mips_elf_record_global_got_symbol (h, abfd,
+							     info, flag))
 		  return FALSE;
 	      }
 	    else
 	      {
 		BFD_ASSERT (flag == GOT_TLS_LDM || r_symndx != 0);
 
-		if (! mips_elf_record_local_got_symbol (abfd, r_symndx,
-							rel->r_addend, g, flag))
+		if (!mips_elf_record_local_got_symbol (abfd, r_symndx,
+						       rel->r_addend,
+						       info, flag))
 		  return FALSE;
 	      }
 	  }
@@ -7223,8 +7190,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
 		    elf_hash_table (info)->dynobj = dynobj = abfd;
 		  if (! mips_elf_create_got_section (dynobj, info, TRUE))
 		    return FALSE;
-		  g = mips_elf_got_info (dynobj, &sgot);
-		  if (! mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
+		  if (!mips_elf_record_global_got_symbol (h, abfd, info, 0))
 		    return FALSE;
 		}
 	    }
@@ -7735,7 +7701,6 @@ _bfd_mips_elf_always_size_sections (bfd 
 {
   asection *ri;
 
-  bfd *dynobj;
   asection *s;
   struct mips_got_info *g;
   int i;
@@ -7758,15 +7723,12 @@ _bfd_mips_elf_always_size_sections (bfd 
     mips_elf_link_hash_traverse (mips_elf_hash_table (info),
 				 mips_elf_check_mips16_stubs, info);
 
-  dynobj = elf_hash_table (info)->dynobj;
-  if (dynobj == NULL)
-    /* Relocatable links don't have it.  */
-    return TRUE;
-
-  g = mips_elf_got_info (dynobj, &s);
+  s = htab->sgot;
   if (s == NULL)
     return TRUE;
 
+  g = htab->got_info;
+
   /* Calculate the total loadable size of the output.  That
      will give us the maximum number of GOT_PAGE entries
      required.  */
@@ -7856,7 +7818,7 @@ _bfd_mips_elf_always_size_sections (bfd 
      dynamic loader.  */
   if (!htab->is_vxworks && s->size > MIPS_ELF_GOT_MAX_SIZE (info))
     {
-      if (! mips_elf_multi_got (output_bfd, info, g, s, page_gotno))
+      if (!mips_elf_multi_got (output_bfd, info, s, page_gotno))
 	return FALSE;
     }
   else
@@ -7962,12 +7924,10 @@ _bfd_mips_elf_size_dynamic_sections (bfd
 	  if (info->shared)
 	    {
 	      /* Allocate relocations for all but the reserved entries.  */
-	      struct mips_got_info *g;
 	      unsigned int count;
 
-	      g = mips_elf_got_info (dynobj, NULL);
-	      count = (g->global_gotno
-		       + g->local_gotno
+	      count = (htab->got_info->global_gotno
+		       + htab->got_info->local_gotno
 		       - MIPS_RESERVED_GOTNO (info));
 	      mips_elf_allocate_dynamic_relocations (dynobj, info, count);
 	    }
@@ -7978,7 +7938,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd
 	     most of the work, but some symbols may have been mapped
 	     to versions that we must now resolve in the got_entries
 	     hash tables.  */
-	  struct mips_got_info *gg = mips_elf_got_info (dynobj, NULL);
+	  struct mips_got_info *gg = htab->got_info;
 	  struct mips_got_info *g = gg;
 	  struct mips_elf_set_global_got_offset_arg set_got_offset_arg;
 	  unsigned int needed_relocs = 0;
@@ -8747,10 +8707,9 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
   BFD_ASSERT (h->dynindx != -1
 	      || h->forced_local);
 
-  sgot = mips_elf_got_section (dynobj, FALSE);
+  sgot = mips_elf_got_section (info);
   BFD_ASSERT (sgot != NULL);
-  BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
-  g = mips_elf_section_data (sgot)->u.got_info;
+  g = htab->got_info;
   BFD_ASSERT (g != NULL);
 
   /* Run through the global symbol table, creating GOT entries for all
@@ -9021,10 +8980,9 @@ _bfd_mips_vxworks_finish_dynamic_symbol 
 
   BFD_ASSERT (h->dynindx != -1 || h->forced_local);
 
-  sgot = mips_elf_got_section (dynobj, FALSE);
+  sgot = mips_elf_got_section (info);
   BFD_ASSERT (sgot != NULL);
-  BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
-  g = mips_elf_section_data (sgot)->u.got_info;
+  g = htab->got_info;
   BFD_ASSERT (g != NULL);
 
   /* See if this symbol has an entry in the GOT.  */
@@ -9185,14 +9143,12 @@ _bfd_mips_elf_finish_dynamic_sections (b
 
   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
 
-  sgot = mips_elf_got_section (dynobj, FALSE);
+  sgot = mips_elf_got_section (info);
   if (sgot == NULL)
     gg = g = NULL;
   else
     {
-      BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
-      gg = mips_elf_section_data (sgot)->u.got_info;
-      BFD_ASSERT (gg != NULL);
+      gg = htab->got_info;
       g = mips_elf_got_for_ibfd (gg, output_bfd);
       BFD_ASSERT (g != NULL);
     }
@@ -10186,7 +10142,6 @@ _bfd_mips_elf_hide_symbol (struct bfd_li
 			   bfd_boolean force_local)
 {
   bfd *dynobj;
-  asection *got;
   struct mips_got_info *g;
   struct mips_elf_link_hash_entry *h;
   struct mips_elf_link_hash_table *htab;
@@ -10198,10 +10153,12 @@ _bfd_mips_elf_hide_symbol (struct bfd_li
 
   dynobj = elf_hash_table (info)->dynobj;
   htab = mips_elf_hash_table (info);
-  if (dynobj != NULL && force_local && h->root.type != STT_TLS
-      && (got = mips_elf_got_section (dynobj, TRUE)) != NULL
-      && (g = mips_elf_section_data (got)->u.got_info) != NULL)
+  if (dynobj != NULL
+      && force_local
+      && h->root.type != STT_TLS
+      && htab->got_info != NULL)
     {
+      g = htab->got_info;
       if (g->next)
 	{
 	  struct mips_got_entry e;
@@ -10257,7 +10214,7 @@ _bfd_mips_elf_hide_symbol (struct bfd_li
 	    /* The symbol is only used in call relocations, so we'll
 	       have assumed it only needs a .got.plt entry.  Increase
 	       the size of .got accordingly.  */
-	    got->size += MIPS_ELF_GOT_SIZE (dynobj);
+	    htab->sgot->size += MIPS_ELF_GOT_SIZE (dynobj);
         }
     }
 
@@ -10729,6 +10686,8 @@ _bfd_mips_elf_link_hash_table_create (bf
   ret->sgotplt = NULL;
   ret->splt = NULL;
   ret->sstubs = NULL;
+  ret->sgot = NULL;
+  ret->got_info = NULL;
   ret->plt_header_size = 0;
   ret->plt_entry_size = 0;
   ret->function_stub_size = 0;
@@ -10795,8 +10754,6 @@ _bfd_mips_elf_final_link (bfd *abfd, str
   htab = mips_elf_hash_table (info);
   if (elf_hash_table (info)->dynamic_sections_created)
     {
-      bfd *dynobj;
-      asection *got;
       struct mips_got_info *g;
       bfd_size_type dynsecsymcount;
 
@@ -10812,10 +10769,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
 	return FALSE;
 
       /* Make sure we didn't grow the global .got region.  */
-      dynobj = elf_hash_table (info)->dynobj;
-      got = mips_elf_got_section (dynobj, FALSE);
-      g = mips_elf_section_data (got)->u.got_info;
-
+      g = htab->got_info;
       if (g->global_gotsym != NULL)
 	BFD_ASSERT ((elf_hash_table (info)->dynsymcount
 		     - g->global_gotsym->dynindx)


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