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.


Thiemo Seufer wrote:

Formatting. Otherwise ok for trunk.



Committed this version:


2006-06-08 David Daney <ddaney@avtrex.com>

	* elfxx-mips.c (STUB_LI16): Removed.
	(STUB_LUI): New macro.
	(STUB_LI16U): Ditto.
	(STUB_LI16S): Ditto.
	(MIPS_FUNCTION_STUB_SIZE): Rewrote to take info parameter.
	(_bfd_mips_elf_adjust_dynamic_symbol): Pass info parameter to
	MIPS_FUNCTION_STUB_SIZE.
	(_bfd_mips_elf_always_size_sections): Ditto.
	(_bfd_mips_elf_size_dynamic_sections): Ditto.
	(_bfd_mips_elf_finish_dynamic_sections): Ditto.
	(_bfd_mips_elf_finish_dynamic_symbol): Rewrote stub generation
	to allow larger symbol table indexes.
? doc/bfd.info
Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/bfd/ChangeLog,v
retrieving revision 1.3541
diff -c -p -r1.3541 ChangeLog
*** ChangeLog	7 Jun 2006 15:38:00 -0000	1.3541
--- ChangeLog	8 Jun 2006 23:50:16 -0000
***************
*** 1,3 ****
--- 1,18 ----
+ 2006-06-08  David Daney  <ddaney@avtrex.com>
+ 
+ 	* elfxx-mips.c (STUB_LI16): Removed.
+ 	(STUB_LUI): New macro.
+ 	(STUB_LI16U): Ditto.
+ 	(STUB_LI16S): Ditto.
+ 	(MIPS_FUNCTION_STUB_SIZE): Rewrote to take info parameter.
+ 	(_bfd_mips_elf_adjust_dynamic_symbol): Pass info parameter to
+ 	MIPS_FUNCTION_STUB_SIZE.
+ 	(_bfd_mips_elf_always_size_sections): Ditto.
+ 	(_bfd_mips_elf_size_dynamic_sections): Ditto.
+ 	(_bfd_mips_elf_finish_dynamic_sections): Ditto.
+ 	(_bfd_mips_elf_finish_dynamic_symbol): Rewrote stub generation
+ 	to allow larger symbol table indexes.
+ 
  2006-06-07  Joseph S. Myers  <joseph@codesourcery.com>
  
  	* po/Make-in (pdf, ps): New dummy targets.
Index: elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.169
diff -c -p -r1.169 elfxx-mips.c
*** elfxx-mips.c	22 May 2006 15:06:22 -0000	1.169
--- elfxx-mips.c	8 Jun 2006 23:50:20 -0000
*************** static bfd *reldyn_sorting_bfd;
*** 623,642 ****
  #define MIPS_ELF_GOT_MAX_SIZE(INFO) (ELF_MIPS_GP_OFFSET (INFO) + 0x7fff)
  
  /* Instructions which appear in a stub.  */
! #define STUB_LW(abfd)						\
!   ((ABI_64_P (abfd)  						\
!     ? 0xdf998010		/* ld t9,0x8010(gp) */		\
!     : 0x8f998010))              /* lw t9,0x8010(gp) */
! #define STUB_MOVE(abfd)                                         \
!    ((ABI_64_P (abfd)						\
!      ? 0x03e0782d		/* daddu t7,ra */		\
!      : 0x03e07821))		/* addu t7,ra */
! #define STUB_JALR 0x0320f809	/* jalr t9,ra */
! #define STUB_LI16(abfd)                                         \
!   ((ABI_64_P (abfd)						\
!    ? 0x64180000			/* daddiu t8,zero,0 */		\
!    : 0x24180000))		/* addiu t8,zero,0 */
! #define MIPS_FUNCTION_STUB_SIZE (16)
  
  /* The name of the dynamic interpreter.  This is put in the .interp
     section.  */
--- 623,648 ----
  #define MIPS_ELF_GOT_MAX_SIZE(INFO) (ELF_MIPS_GP_OFFSET (INFO) + 0x7fff)
  
  /* Instructions which appear in a stub.  */
! #define STUB_LW(abfd)							\
!   ((ABI_64_P (abfd)							\
!     ? 0xdf998010				/* ld t9,0x8010(gp) */	\
!     : 0x8f998010))              		/* lw t9,0x8010(gp) */
! #define STUB_MOVE(abfd)							\
!    ((ABI_64_P (abfd)							\
!      ? 0x03e0782d				/* daddu t7,ra */	\
!      : 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_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
  
  /* The name of the dynamic interpreter.  This is put in the .interp
     section.  */
*************** _bfd_mips_elf_adjust_dynamic_symbol (str
*** 6877,6883 ****
  	  h->plt.offset = s->size;
  
  	  /* Make room for this stub code.  */
! 	  s->size += MIPS_FUNCTION_STUB_SIZE;
  
  	  /* The last half word of the stub will be filled with the index
  	     of this symbol in .dynsym section.  */
--- 6883,6889 ----
  	  h->plt.offset = s->size;
  
  	  /* Make room for this stub code.  */
! 	  s->size += MIPS_FUNCTION_STUB_SIZE (info);
  
  	  /* The last half word of the stub will be filled with the index
  	     of this symbol in .dynsym section.  */
*************** _bfd_mips_elf_always_size_sections (bfd 
*** 7142,7148 ****
    /* 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 * (i + 1);
  
    if (htab->is_vxworks)
      /* There's no need to allocate page entries for VxWorks; R_MIPS_GOT16
--- 7148,7154 ----
    /* 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);
  
    if (htab->is_vxworks)
      /* There's no need to allocate page entries for VxWorks; R_MIPS_GOT16
*************** _bfd_mips_elf_size_dynamic_sections (bfd
*** 7360,7366 ****
  	{
  	  /* 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;
  	}
        else if (! info->shared
  	       && ! mips_elf_hash_table (info)->use_rld_obj_head
--- 7366,7372 ----
  	{
  	  /* 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);
  	}
        else if (! info->shared
  	       && ! mips_elf_hash_table (info)->use_rld_obj_head
*************** _bfd_mips_elf_finish_dynamic_symbol (bfd
*** 7997,8009 ****
    asection *sgot;
    struct mips_got_info *g, *gg;
    const char *name;
  
    dynobj = elf_hash_table (info)->dynobj;
  
    if (h->plt.offset != MINUS_ONE)
      {
        asection *s;
!       bfd_byte stub[MIPS_FUNCTION_STUB_SIZE];
  
        /* This symbol has a stub.  Set it up.  */
  
--- 8003,8016 ----
    asection *sgot;
    struct mips_got_info *g, *gg;
    const char *name;
+   int idx;
  
    dynobj = elf_hash_table (info)->dynobj;
  
    if (h->plt.offset != MINUS_ONE)
      {
        asection *s;
!       bfd_byte stub[MIPS_FUNCTION_STUB_MAX_SIZE];
  
        /* This symbol has a stub.  Set it up.  */
  
*************** _bfd_mips_elf_finish_dynamic_symbol (bfd
*** 8013,8030 ****
  				   MIPS_ELF_STUB_SECTION_NAME (dynobj));
        BFD_ASSERT (s != NULL);
  
!       /* FIXME: Can h->dynindx be more than 64K?  */
!       if (h->dynindx & 0xffff0000)
  	return FALSE;
  
        /* Fill the stub.  */
!       bfd_put_32 (output_bfd, STUB_LW (output_bfd), stub);
!       bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), stub + 4);
!       bfd_put_32 (output_bfd, STUB_JALR, stub + 8);
!       bfd_put_32 (output_bfd, STUB_LI16 (output_bfd) + h->dynindx, stub + 12);
  
        BFD_ASSERT (h->plt.offset <= s->size);
!       memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE);
  
        /* Mark the symbol as undefined.  plt.offset != -1 occurs
  	 only for the referenced symbol.  */
--- 8020,8060 ----
  				   MIPS_ELF_STUB_SECTION_NAME (dynobj));
        BFD_ASSERT (s != NULL);
  
!       BFD_ASSERT ((MIPS_FUNCTION_STUB_SIZE (info) == 20)
!                   || (h->dynindx <= 65536));
! 
!       /* 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)
  	return FALSE;
  
        /* Fill the stub.  */
!       idx = 0;
!       bfd_put_32 (output_bfd, STUB_LW (output_bfd), stub + idx);
!       idx += 4;
!       bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), stub + idx);
!       idx += 4;
!       if (MIPS_FUNCTION_STUB_SIZE (info) == 20)
!         {
!           bfd_put_32 (output_bfd, STUB_LUI ((h->dynindx >> 16 ) & 0xffff),
!                       stub + idx);
!           idx += 4;
!         }
!       bfd_put_32 (output_bfd, STUB_JALR, stub + idx);
!       idx += 4;
  
+       /* 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))
+         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_ASSERT (h->plt.offset <= s->size);
!       memcpy (s->contents + h->plt.offset,
!               stub, MIPS_FUNCTION_STUB_SIZE (info));
  
        /* Mark the symbol as undefined.  plt.offset != -1 occurs
  	 only for the referenced symbol.  */
*************** _bfd_mips_elf_finish_dynamic_sections (b
*** 8827,8836 ****
  	      {
  		file_ptr dummy_offset;
  
! 		BFD_ASSERT (s->size >= MIPS_FUNCTION_STUB_SIZE);
! 		dummy_offset = s->size - MIPS_FUNCTION_STUB_SIZE;
  		memset (s->contents + dummy_offset, 0,
! 			MIPS_FUNCTION_STUB_SIZE);
  	      }
  	  }
        }
--- 8857,8866 ----
  	      {
  		file_ptr dummy_offset;
  
! 		BFD_ASSERT (s->size >= MIPS_FUNCTION_STUB_SIZE (info));
! 		dummy_offset = s->size - MIPS_FUNCTION_STUB_SIZE (info);
  		memset (s->contents + dummy_offset, 0,
! 			MIPS_FUNCTION_STUB_SIZE (info));
  	      }
  	  }
        }

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