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]

Re: [PATCH] (version 2) Change MIPS linker stubs to allow for more than 2^15 symbols.


Richard Sandiford wrote:
> David Daney <ddaney@avtrex.com> writes:
> > ! #define MIPS_FUNCTION_STUB_SIZE(INFO) \
> > !   (elf_hash_table (INFO)->dynsymcount > 65536 ? 20 : 16)
> 
> Sorry to be a pain, but as I said earlier, I really do think we should
> cache the chosen stub size in mips_elf_link_hash_table (and get rid of
> this macro entirely).  That will emphasise that always_size_dynamic_sections
> is the place that makes the decision, and that it's only safe to use this
> value once that function has been called.  I think that will be more robust
> and easier to understand in future.
> 
> Apart from that, and from Thiemo's and Daniel's comments, this looks
> really good to me.  Thanks a lot for doing this!

Does this followup patch look ok?


Thiemo


Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.171
diff -u -p -r1.171 elfxx-mips.c
--- bfd/elfxx-mips.c	9 Jun 2006 13:47:41 -0000	1.171
+++ bfd/elfxx-mips.c	9 Jun 2006 15:42:47 -0000
@@ -335,6 +335,8 @@ struct mips_elf_link_hash_table
   bfd_vma plt_header_size;
   /* The size of a PLT entry in bytes (VxWorks only).  */
   bfd_vma plt_entry_size;
+  /* The size of a function stub entry in bytes.  */
+  bfd_vma function_stub_size;
 };
 
 #define TLS_RELOC_P(r_type) \
@@ -633,16 +635,14 @@ static bfd *reldyn_sorting_bfd;
      : 0x03e07821))				/* addu t7,ra */
 #define STUB_LUI(VAL) (0x3c180000 + (VAL))	/* lui t8,VAL */
 #define STUB_JALR 0x0320f809			/* jalr t9,ra */
-#define STUB_LI16U(VAL) (0x34180000 + (VAL))	/* ori t8,zero,VAL unsigned*/
+#define STUB_LI16U(VAL) (0x34180000 + (VAL))	/* ori t8,zero,VAL unsigned */
 #define STUB_LI16S(abfd, VAL)						\
    ((ABI_64_P (abfd)							\
     ? (0x64180000 + (VAL))	/* daddiu t8,zero,VAL sign extended */	\
     : (0x24180000 + (VAL))))	/* addiu t8,zero,VAL sign extended */
 
-#define MIPS_FUNCTION_STUB_SIZE(INFO) \
-  (elf_hash_table (INFO)->dynsymcount > 65536 ? 20 : 16)
-
-#define MIPS_FUNCTION_STUB_MAX_SIZE 20
+#define MIPS_FUNCTION_STUB_NORMAL_SIZE 16
+#define MIPS_FUNCTION_STUB_BIG_SIZE 20
 
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
@@ -5930,6 +5930,9 @@ _bfd_mips_elf_create_dynamic_sections (b
 	  || ! bfd_set_section_alignment (abfd, s,
 					  MIPS_ELF_LOG_FILE_ALIGN (abfd)))
 	return FALSE;
+      htab->function_stub_size = (elf_hash_table (info)->dynsymcount > 0xffff
+				  ? MIPS_FUNCTION_STUB_BIG_SIZE
+				  : MIPS_FUNCTION_STUB_NORMAL_SIZE);
     }
 
   if ((IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none)
@@ -6832,7 +6835,9 @@ _bfd_mips_elf_adjust_dynamic_symbol (str
   bfd *dynobj;
   struct mips_elf_link_hash_entry *hmips;
   asection *s;
+  struct mips_elf_link_hash_table *htab;
 
+  htab = mips_elf_hash_table (info);
   dynobj = elf_hash_table (info)->dynobj;
 
   /* Make sure we know what is going on here.  */
@@ -6885,7 +6890,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (str
 	  h->plt.offset = s->size;
 
 	  /* Make room for this stub code.  */
-	  s->size += MIPS_FUNCTION_STUB_SIZE (info);
+	  s->size += htab->function_stub_size;
 
 	  /* The last half word of the stub will be filled with the index
 	     of this symbol in .dynsym section.  */
@@ -7150,7 +7155,7 @@ _bfd_mips_elf_always_size_sections (bfd 
   /* In the worst case, we'll get one stub per dynamic symbol, plus
      one to account for the dummy entry at the end required by IRIX
      rld.  */
-  loadable_size += MIPS_FUNCTION_STUB_SIZE (info) * (i + 1);
+  loadable_size += htab->function_stub_size * (i + 1);
 
   if (htab->is_vxworks)
     /* There's no need to allocate page entries for VxWorks; R_MIPS_GOT16
@@ -7367,14 +7372,14 @@ _bfd_mips_elf_size_dynamic_sections (bfd
       else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0)
 	{
 	  /* IRIX rld assumes that the function stub isn't at the end
-	     of .text section. So put a dummy. XXX  */
-	  s->size += MIPS_FUNCTION_STUB_SIZE (info);
+	     of .text section.  So put a dummy.  XXX  */
+		s->size += htab->function_stub_size;
 	}
       else if (! info->shared
 	       && ! mips_elf_hash_table (info)->use_rld_obj_head
 	       && strncmp (name, ".rld_map", 8) == 0)
 	{
-	  /* We add a room for __rld_map. It will be filled in by the
+	  /* We add a room for __rld_map.  It will be filled in by the
 	     rtld to contain a pointer to the _r_debug structure.  */
 	  s->size += 4;
 	}
@@ -8006,13 +8011,15 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
   struct mips_got_info *g, *gg;
   const char *name;
   int idx;
+  struct mips_elf_link_hash_table *htab;
 
+  htab = mips_elf_hash_table (info);
   dynobj = elf_hash_table (info)->dynobj;
 
   if (h->plt.offset != MINUS_ONE)
     {
       asection *s;
-      bfd_byte stub[MIPS_FUNCTION_STUB_MAX_SIZE];
+      bfd_byte stub[MIPS_FUNCTION_STUB_BIG_SIZE];
 
       /* This symbol has a stub.  Set it up.  */
 
@@ -8022,13 +8029,13 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
 				   MIPS_ELF_STUB_SECTION_NAME (dynobj));
       BFD_ASSERT (s != NULL);
 
-      BFD_ASSERT ((MIPS_FUNCTION_STUB_SIZE (info) == 20)
-                  || (h->dynindx <= 65536));
+      BFD_ASSERT ((htab->function_stub_size == MIPS_FUNCTION_STUB_BIG_SIZE)
+                  || (h->dynindx <= 0xffff));
 
       /* Values up to 2^31 - 1 are allowed.  Larger values would cause
-         sign extension at runtime in the stub, resulting in a
-         negative index value.  */
-      if (h->dynindx & 0x80000000)
+	 sign extension at runtime in the stub, resulting in a negative
+	 index value.  */
+      if (h->dynindx & ~0x7fffffff)
 	return FALSE;
 
       /* Fill the stub.  */
@@ -8037,9 +8044,9 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
       idx += 4;
       bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), stub + idx);
       idx += 4;
-      if (MIPS_FUNCTION_STUB_SIZE (info) == 20)
+      if (htab->function_stub_size == MIPS_FUNCTION_STUB_BIG_SIZE)
         {
-          bfd_put_32 (output_bfd, STUB_LUI ((h->dynindx >> 16 ) & 0xffff),
+          bfd_put_32 (output_bfd, STUB_LUI ((h->dynindx >> 16) & 0x7fff),
                       stub + idx);
           idx += 4;
         }
@@ -8048,15 +8055,15 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
 
       /* If a large stub is not required and sign extension is not a
          problem, then use legacy code in the stub.  */
-      if ((MIPS_FUNCTION_STUB_SIZE (info) == 20) || (h->dynindx & 0xffff8000))
+      if ((htab->function_stub_size == MIPS_FUNCTION_STUB_BIG_SIZE)
+	  || (h->dynindx & ~0x7fff))
         bfd_put_32 (output_bfd, STUB_LI16U (h->dynindx & 0xffff), stub + idx);
       else
-        bfd_put_32 (output_bfd,
-                    STUB_LI16S (output_bfd, h->dynindx & 0xffff), stub + idx);
-        
+        bfd_put_32 (output_bfd, STUB_LI16S (output_bfd, h->dynindx),
+		    stub + idx);
+
       BFD_ASSERT (h->plt.offset <= s->size);
-      memcpy (s->contents + h->plt.offset,
-              stub, MIPS_FUNCTION_STUB_SIZE (info));
+      memcpy (s->contents + h->plt.offset, stub, htab->function_stub_size);
 
       /* Mark the symbol as undefined.  plt.offset != -1 occurs
 	 only for the referenced symbol.  */
@@ -8859,10 +8866,10 @@ _bfd_mips_elf_finish_dynamic_sections (b
 	      {
 		file_ptr dummy_offset;
 
-		BFD_ASSERT (s->size >= MIPS_FUNCTION_STUB_SIZE (info));
-		dummy_offset = s->size - MIPS_FUNCTION_STUB_SIZE (info);
+		BFD_ASSERT (s->size >= htab->function_stub_size);
+		dummy_offset = s->size - htab->function_stub_size;
 		memset (s->contents + dummy_offset, 0,
-			MIPS_FUNCTION_STUB_SIZE (info));
+			htab->function_stub_size);
 	      }
 	  }
       }
@@ -9974,6 +9981,7 @@ _bfd_mips_elf_link_hash_table_create (bf
   ret->splt = NULL;
   ret->plt_header_size = 0;
   ret->plt_entry_size = 0;
+  ret->function_stub_size = 0;
 
   return &ret->root.root;
 }


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