[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

mips specific patches



Package: binutils
Version: 2.10.1.0.2-1
Severity: normal
tags: patch

for debian-mips support please add the mips patches
binutils-2.10-mips-call_reloc.patch.gz
binutils-2.10-mips-extsym_debug.gz
binutils-2.10.1-mips-merge.patch.gz
binutils-2.10.1-mips-sym_is_global.patch.gz
from ftp.ds2.pg.gda.pl/pub/macro/SRPMS/binutils-2.10.1.src.rpm. I
applied them to the current version and they are working.

I hope I succeed in building glibc-2.2 with that now.

Christoph

*** binutils-2.10.1.0.2/bfd/elf32-mips.c~	Fri Jan  5 00:05:20 2001
--- binutils-2.10.1.0.2/bfd/elf32-mips.c	Thu Jan  4 23:48:07 2001
***************
*** 79,84 ****
--- 79,90 ----
       section) against this symbol.  */
    unsigned int min_dyn_reloc_index;
  
+   /* We must not create a stub for a symbol that has relocations
+      related to taking the function's address, i.e. any but
+      R_MIPS_CALL*16 ones -- see "MIPS ABI Supplement, 3rd Edition",
+      p. 4-20.  */
+   boolean no_fn_stub;
+ 
    /* If there is a stub that 32 bit functions should use to call this
       16 bit function, this points to the section containing the stub.  */
    asection *fn_stub;
***************
*** 2275,2281 ****
       bfd *abfd ATTRIBUTE_UNUSED;
       asymbol *sym;
  {
!   return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false;
  }
  
  /* Set the right machine number for a MIPS ELF file.  This is used for
--- 2281,2292 ----
       bfd *abfd ATTRIBUTE_UNUSED;
       asymbol *sym;
  {
!   if (SGI_COMPAT (abfd))
!     return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false;
!   else
!     return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
! 	    || bfd_is_und_section (bfd_get_section (sym))
! 	    || bfd_is_com_section (bfd_get_section (sym))) ? true : false;
  }
  
  /* Set the right machine number for a MIPS ELF file.  This is used for
***************
*** 2475,2480 ****
--- 2486,2493 ----
    flagword old_flags;
    flagword new_flags;
    boolean ok;
+   boolean null_input_bfd = true;
+   asection *sec;
  
    /* Check if we have the same endianess */
    if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
***************
*** 2514,2519 ****
--- 2527,2553 ----
    if (new_flags == old_flags)
      return true;
  
+   /* Check to see if the input BFD actually contains any sections.
+      If not, its flags may not have been initialised either, but it cannot
+      actually cause any incompatibility.  */
+   for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+     {
+       /* Ignore synthetic sections and empty .text, .data and .bss sections
+ 	  which are automatically generated by gas.  */
+       if (strcmp (sec->name, ".reginfo")
+ 	  && strcmp (sec->name, ".mdebug")
+ 	  && ((!strcmp (sec->name, ".text")
+ 	       || !strcmp (sec->name, ".data")
+ 	       || !strcmp (sec->name, ".bss"))
+ 	      && sec->_raw_size != 0))
+ 	{
+ 	  null_input_bfd = false;
+ 	  break;
+ 	}
+     }
+   if (null_input_bfd)
+     return true;
+ 
    ok = true;
  
    if ((new_flags & EF_MIPS_PIC) != (old_flags & EF_MIPS_PIC))
***************
*** 3891,3896 ****
--- 3925,3931 ----
        ret->esym.ifd = -2;
        ret->possibly_dynamic_relocs = 0;
        ret->min_dyn_reloc_index = 0;
+       ret->no_fn_stub = false;
        ret->fn_stub = NULL;
        ret->need_fn_stub = false;
        ret->call_stub = NULL;
***************
*** 4267,4290 ****
      }
    else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
      {
!       /* Set type and value for a symbol with a function stub.  */
!       h->esym.asym.st = stProc;
!       sec = h->root.root.u.def.section;
!       if (sec == NULL)
! 	h->esym.asym.value = 0;
!       else
  	{
! 	  output_section = sec->output_section;
! 	  if (output_section != NULL)
! 	    h->esym.asym.value = (h->root.plt.offset
! 				  + sec->output_offset
! 				  + output_section->vma);
! 	  else
! 	    h->esym.asym.value = 0;
  	}
  #if 0 /* FIXME?  */
        h->esym.ifd = 0;
  #endif
      }
  
    if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
--- 4302,4337 ----
      }
    else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
      {
!       struct mips_elf_link_hash_entry *hd = h;
!       boolean no_fn_stub = h->no_fn_stub;
! 
!       while (hd->root.root.type == bfd_link_hash_indirect)
  	{
! 	  hd = (struct mips_elf_link_hash_entry *)h->root.root.u.i.link;
! 	  no_fn_stub = no_fn_stub || hd->no_fn_stub;
  	}
+ 
+       if (!no_fn_stub)
+ 	{
+ 	  /* Set type and value for a symbol with a function stub.  */
+ 	  h->esym.asym.st = stProc;
+ 	  sec = hd->root.root.u.def.section;
+ 	  if (sec == NULL)
+ 	    h->esym.asym.value = 0;
+ 	  else
+ 	    {
+ 	      output_section = sec->output_section;
+ 	      if (output_section != NULL)
+ 		h->esym.asym.value = (hd->root.plt.offset
+ 				      + sec->output_offset
+ 				      + output_section->vma);
+ 	      else
+ 		h->esym.asym.value = 0;
+ 	    }
  #if 0 /* FIXME?  */
        h->esym.ifd = 0;
  #endif
+ 	}
      }
  
    if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
***************
*** 5774,5788 ****
  	  /* The relocation we're building is section-relative.
  	     Therefore, the original addend must be adjusted by the
  	     section offset.  */
! 	  *addendp += symbol - sec->output_section->vma;
  	  /* Now, the relocation is just against the section.  */
  	  symbol = sec->output_section->vma;
  	}
        
!       /* If the relocation is against a local symbol was previously an absolute
! 	 relocation, we must adjust it by the value we give it in the dynamic
! 	 symbol table.  */
!       if (local_p && r_type != R_MIPS_REL32)
  	*addendp += symbol;
  
        /* The relocation is always an REL32 relocation because we don't
--- 5821,5836 ----
  	  /* The relocation we're building is section-relative.
  	     Therefore, the original addend must be adjusted by the
  	     section offset.  */
! 	  *addendp += section_offset;
  	  /* Now, the relocation is just against the section.  */
  	  symbol = sec->output_section->vma;
  	}
        
!       /* If the relocation was previously an absolute relocation and
! 	 this symbol will not be referred to by the relocation, we must
! 	 adjust it by the value we give it in the dynamic symbol table.
! 	 Otherwise leave the job up to the dynamic linker.  */
!       if (!indx && r_type != R_MIPS_REL32)
  	*addendp += symbol;
  
        /* The relocation is always an REL32 relocation because we don't
***************
*** 6157,6163 ****
  				 symbol + addend, sgot->contents + g);
  	    }
  	}
!       else if (r_type == R_MIPS_GOT16)
  	/* There's no need to create a local GOT entry here; the
  	   calculation for a local GOT16 entry does not involve G.  */
  	break;
--- 6205,6211 ----
  				 symbol + addend, sgot->contents + g);
  	    }
  	}
!       else if (r_type == R_MIPS_GOT16 || r_type == R_MIPS_CALL16)
  	/* There's no need to create a local GOT entry here; the
  	   calculation for a local GOT16 entry does not involve G.  */
  	break;
***************
*** 6325,6330 ****
--- 6373,6379 ----
        break;
        
      case R_MIPS_GOT16:
+     case R_MIPS_CALL16:
        if (local_p)
  	{
  	  boolean forced;
***************
*** 6347,6353 ****
  
        /* Fall through.  */
  
-     case R_MIPS_CALL16:
      case R_MIPS_GOT_DISP:
        value = g;
        overflowed_p = mips_elf_overflow_p (value, 16);
--- 6396,6401 ----
***************
*** 7662,7671 ****
  	  /* We may need a local GOT entry for this relocation.  We
  	     don't count R_MIPS_GOT_PAGE because we can estimate the
  	     maximum number of pages needed by looking at the size of
! 	     the segment.  Similar comments apply to R_MIPS_GOT16.  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.
  
  	     This estimation is very conservative since we can merge
  	     duplicate entries in the GOT.  In order to be less
--- 7710,7719 ----
  	  /* We may need a local GOT entry for this relocation.  We
  	     don't count R_MIPS_GOT_PAGE because we can estimate the
  	     maximum number of pages needed by looking at the size of
! 	     the segment.  Similar comments apply to R_MIPS_GOT16 and
! 	     R_MIPS_CALL16.  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.
  
  	     This estimation is very conservative since we can merge
  	     duplicate entries in the GOT.  In order to be less
***************
*** 7797,7802 ****
--- 7845,7869 ----
  	  break;
  	}
  
+       /* We must not create a stub for a symbol that has relocations
+          related to taking the function's address.  */
+       switch (r_type)
+ 	{
+ 	default:
+ 	  if (h != NULL)
+ 	    {
+ 	      struct mips_elf_link_hash_entry *mh;
+ 
+ 	      mh = (struct mips_elf_link_hash_entry *) h;
+ 	      mh->no_fn_stub = true;
+ 	    }
+ 	  break;
+ 	case R_MIPS_CALL16:
+ 	case R_MIPS_CALL_HI16:
+ 	case R_MIPS_CALL_LO16:
+ 	  break;
+ 	}
+ 
        /* If this reloc is not a 16 bit call, and it has a global
           symbol, then we will need the fn_stub if there is one.
           References from a stub section do not count. */
***************
*** 7932,7937 ****
--- 7999,8006 ----
        || (indmips->min_dyn_reloc_index != 0
            && indmips->min_dyn_reloc_index < dirmips->min_dyn_reloc_index))
      dirmips->min_dyn_reloc_index = indmips->min_dyn_reloc_index;
+   if (indmips->no_fn_stub)
+     dirmips->no_fn_stub = true;
  }
  
  /* Adjust a symbol defined by a dynamic object and referenced by a
***************
*** 7972,7979 ****
      mips_elf_allocate_dynamic_relocations (dynobj, 
  					   hmips->possibly_dynamic_relocs);
  
!   /* For a function, create a stub, if needed. */
!   if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
      {
        if (! elf_hash_table (info)->dynamic_sections_created)
  	return true;
--- 8041,8049 ----
      mips_elf_allocate_dynamic_relocations (dynobj, 
  					   hmips->possibly_dynamic_relocs);
  
!   /* For a function create a stub, if allowed.  */
!   if (! hmips->no_fn_stub
!       && (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
      {
        if (! elf_hash_table (info)->dynamic_sections_created)
  	return true;
*** binutils-2.10.1.0.2/gas/config/tc-mips.c~	Fri Jan  5 00:12:16 2001
--- binutils-2.10.1.0.2/gas/config/tc-mips.c	Thu Jan  4 23:55:15 2001
***************
*** 4278,4288 ****
--- 4278,4292 ----
  	}
        else if (mips_pic == SVR4_PIC && ! mips_big_got)
  	{
+ 	  int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT16;
+ 
  	  /* If this is a reference to an external symbol, and there
  	     is no constant, we want
  	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)
  	     For a local symbol, we want
  	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)
+ 	     or if tempreg is PIC_CALL_REG
+ 	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_CALL16)
  	       nop
  	       addiu	$tempreg,$tempreg,<sym>	(BFD_RELOC_LO16)
  
***************
*** 4307,4315 ****
  	  expr1.X_add_number = offset_expr.X_add_number;
  	  offset_expr.X_add_number = 0;
  	  frag_grow (32);
  	  macro_build ((char *) NULL, &icnt, &offset_expr,
  		       dbl ? "ld" : "lw",
! 		       "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
  	  if (expr1.X_add_number == 0)
  	    {
  	      int off;
--- 4311,4321 ----
  	  expr1.X_add_number = offset_expr.X_add_number;
  	  offset_expr.X_add_number = 0;
  	  frag_grow (32);
+ 	  if (expr1.X_add_number == 0 && tempreg == PIC_CALL_REG)
+ 	    lw_reloc_type = (int) BFD_RELOC_MIPS_CALL16;
  	  macro_build ((char *) NULL, &icnt, &offset_expr,
  		       dbl ? "ld" : "lw",
! 		       "t,o(b)", tempreg, lw_reloc_type, GP);
  	  if (expr1.X_add_number == 0)
  	    {
  	      int off;
***************
*** 4415,4426 ****
--- 4421,4438 ----
        else if (mips_pic == SVR4_PIC)
  	{
  	  int gpdel;
+ 	  int lui_reloc_type = (int) BFD_RELOC_MIPS_GOT_HI16;
+ 	  int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT_LO16;
  
  	  /* This is the large GOT case.  If this is a reference to an
  	     external symbol, and there is no constant, we want
  	       lui	$tempreg,<sym>		(BFD_RELOC_MIPS_GOT_HI16)
  	       addu	$tempreg,$tempreg,$gp
  	       lw	$tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ 	     or if tempreg is PIC_CALL_REG
+ 	       lui	$tempreg,<sym>		(BFD_RELOC_MIPS_CALL_HI16)
+ 	       addu	$tempreg,$tempreg,$gp
+ 	       lw	$tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_CALL_LO16)
  	     For a local symbol, we want
  	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)
  	       nop
***************
*** 4459,4466 ****
  	    gpdel = 4;
  	  else
  	    gpdel = 0;
  	  macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
! 		       tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
  	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
  		       ((bfd_arch_bits_per_address (stdoutput) == 32
  			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
--- 4471,4483 ----
  	    gpdel = 4;
  	  else
  	    gpdel = 0;
+ 	  if (expr1.X_add_number == 0 && tempreg == PIC_CALL_REG)
+ 	    {
+ 	      lui_reloc_type = (int) BFD_RELOC_MIPS_CALL_HI16;
+ 	      lw_reloc_type = (int) BFD_RELOC_MIPS_CALL_LO16;
+ 	    }
  	  macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
! 		       tempreg, lui_reloc_type);
  	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
  		       ((bfd_arch_bits_per_address (stdoutput) == 32
  			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
***************
*** 4468,4475 ****
  		       "d,v,t", tempreg, tempreg, GP);
  	  macro_build ((char *) NULL, &icnt, &offset_expr,
  		       dbl ? "ld" : "lw",
! 		       "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,
! 		       tempreg);
  	  if (expr1.X_add_number == 0)
  	    {
  	      int off;
--- 4485,4491 ----
  		       "d,v,t", tempreg, tempreg, GP);
  	  macro_build ((char *) NULL, &icnt, &offset_expr,
  		       dbl ? "ld" : "lw",
! 		       "t,o(b)", tempreg, lw_reloc_type, tempreg);
  	  if (expr1.X_add_number == 0)
  	    {
  	      int off;



-- System Information
Debian Release: 2.2
Kernel Version: Linux pongo 2.4.0-test9 #1 Thu Oct 26 21:35:48 CEST 2000 mips un
known

Versions of the packages gdb depends on:
ii  libc6          2.1.95-1.1     GNU C Library: Shared libraries and Timezone



Reply to: