This is the mail archive of the binutils@sources.redhat.com 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]

ia64 psABI update


R_IA64_IPLTLSB type relocs, in addition to implementing .plt
entries, are also used to put function descriptors anywhere
the programmer would like.

GCC does not do this yet, but the C++ ABI for IA-64 sez that
we use descriptors in vtables instead of pointers to descriptors
as would be normal for a C-level function pointer.  The Intel
compiler already emits these relocations.

Also, several weird (and unhandled) relocations were removed.


r~

        * elfxx-ia64.c (elfNN_ia64_check_relocs): Handle IPLT relocs.
        (allocate_dynrel_entries): Likewise.
        (elfNN_ia64_relocate_section): Likewise.  Set REL addends correctly.
        (set_pltoff_entry): Likewise.
        (ia64_howto_table): Remove R_IA64_SEGBASE, and R_IA64_EPLT[ML]SB
        (elfNN_ia64_reloc_type_lookup): Likewise.
        (elfNN_ia64_install_value): Likewise.
        (elfNN_ia64_relocate_section): Likewise.
        * reloc.c (BFD_RELOC_IA64_SEGBASE): Remove.
        (BFD_RELOC_IA64_EPLTMSB, BFD_RELOC_IA64_EPLTLSB): Remove.

Index: elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 elfxx-ia64.c
*** elfxx-ia64.c	2000/11/08 07:54:31	1.2
--- elfxx-ia64.c	2000/11/16 22:43:33
*************** static reloc_howto_type ia64_howto_table
*** 353,359 ****
      IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
      IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
  
-     IA64_HOWTO (R_IA64_SEGBASE,	    "SEGBASE",	   4, false, true),
      IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
      IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
      IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
--- 353,358 ----
*************** static reloc_howto_type ia64_howto_table
*** 380,387 ****
  
      IA64_HOWTO (R_IA64_IPLTMSB,	    "IPLTMSB",	   4, false, true),
      IA64_HOWTO (R_IA64_IPLTLSB,	    "IPLTLSB",	   4, false, true),
-     IA64_HOWTO (R_IA64_EPLTMSB,	    "EPLTMSB",	   4, false, true),
-     IA64_HOWTO (R_IA64_EPLTLSB,	    "EPLTLSB",	   4, false, true),
      IA64_HOWTO (R_IA64_COPY,	    "COPY",	   4, false, true),
      IA64_HOWTO (R_IA64_LTOFF22X,    "LTOFF22X",	   0, false, true),
      IA64_HOWTO (R_IA64_LDXMOV,	    "LDXMOV",	   0, false, true),
--- 379,384 ----
*************** elfNN_ia64_reloc_type_lookup (abfd, bfd_
*** 476,482 ****
      case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
      case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
  
-     case BFD_RELOC_IA64_SEGBASE:	rtype = R_IA64_SEGBASE; break;
      case BFD_RELOC_IA64_SEGREL32MSB:	rtype = R_IA64_SEGREL32MSB; break;
      case BFD_RELOC_IA64_SEGREL32LSB:	rtype = R_IA64_SEGREL32LSB; break;
      case BFD_RELOC_IA64_SEGREL64MSB:	rtype = R_IA64_SEGREL64MSB; break;
--- 473,478 ----
*************** elfNN_ia64_reloc_type_lookup (abfd, bfd_
*** 499,506 ****
  
      case BFD_RELOC_IA64_IPLTMSB:	rtype = R_IA64_IPLTMSB; break;
      case BFD_RELOC_IA64_IPLTLSB:	rtype = R_IA64_IPLTLSB; break;
-     case BFD_RELOC_IA64_EPLTMSB:	rtype = R_IA64_EPLTMSB; break;
-     case BFD_RELOC_IA64_EPLTLSB:	rtype = R_IA64_EPLTLSB; break;
      case BFD_RELOC_IA64_COPY:		rtype = R_IA64_COPY; break;
      case BFD_RELOC_IA64_LTOFF22X:	rtype = R_IA64_LTOFF22X; break;
      case BFD_RELOC_IA64_LDXMOV:		rtype = R_IA64_LDXMOV; break;
--- 495,500 ----
*************** elfNN_ia64_check_relocs (abfd, info, sec
*** 1864,1869 ****
--- 1858,1871 ----
  	  dynrel_type = R_IA64_DIR64LSB;
  	  break;
  
+ 	case R_IA64_IPLTMSB:
+ 	case R_IA64_IPLTLSB:
+ 	  /* Shared objects will always need at least a REL relocation.  */
+ 	  if (info->shared || maybe_dynamic)
+ 	    need_entry = NEED_DYNREL;
+ 	  dynrel_type = R_IA64_IPLTLSB;
+ 	  break;
+ 
  	case R_IA64_PCREL22:
  	case R_IA64_PCREL64I:
  	case R_IA64_PCREL32MSB:
*************** allocate_dynrel_entries (dyn_i, data)
*** 2184,2189 ****
--- 2186,2193 ----
  
    for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
      {
+       int count = rent->count;
+ 
        switch (rent->type)
  	{
  	case R_IA64_FPTR64LSB:
*************** allocate_dynrel_entries (dyn_i, data)
*** 2201,2208 ****
  	  if (!dynamic_symbol && !shared)
  	    continue;
  	  break;
  	}
!       rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * rent->count;
      }
  
    /* Take care of the GOT and PLT relocations.  */
--- 2205,2222 ----
  	  if (!dynamic_symbol && !shared)
  	    continue;
  	  break;
+ 	case R_IA64_IPLTLSB:
+ 	  if (!dynamic_symbol && !shared)
+ 	    continue;
+ 	  /* Use two REL relocations for IPLT relocations
+ 	     against local symbols.  */
+ 	  if (!dynamic_symbol)
+ 	    count *= 2;
+ 	  break;
+ 	default:
+ 	  abort ();
  	}
!       rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
      }
  
    /* Take care of the GOT and PLT relocations.  */
*************** elfNN_ia64_install_value (abfd, hit_addr
*** 2639,2663 ****
        break;
  
        /* Unsupported / Dynamic relocations.  */
- 
-     case R_IA64_REL32MSB:
-     case R_IA64_REL32LSB:
-     case R_IA64_REL64MSB:
-     case R_IA64_REL64LSB:
- 
-     case R_IA64_IPLTMSB:
-     case R_IA64_IPLTLSB:
-     case R_IA64_EPLTMSB:
-     case R_IA64_EPLTLSB:
-     case R_IA64_COPY:
- 
-     case R_IA64_SEGBASE:
- 
-     case R_IA64_TPREL22:
-     case R_IA64_TPREL64MSB:
-     case R_IA64_TPREL64LSB:
-     case R_IA64_LTOFF_TP22:
- 
      default:
        return bfd_reloc_notsupported;
      }
--- 2653,2658 ----
*************** set_pltoff_entry (abfd, info, dyn_i, val
*** 2937,2946 ****
    if ((! dyn_i->want_plt || is_plt)
        && !dyn_i->pltoff_done)
      {
        /* Fill in the function descriptor.  */
        bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
!       bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
! 		  pltoff_sec->contents + dyn_i->pltoff_offset + 8);
  
        /* Install dynamic relocations if needed.  */
        if (!is_plt && info->shared)
--- 2932,2942 ----
    if ((! dyn_i->want_plt || is_plt)
        && !dyn_i->pltoff_done)
      {
+       bfd_vma gp = _bfd_get_gp_value (abfd);
+ 
        /* Fill in the function descriptor.  */
        bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
!       bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
  
        /* Install dynamic relocations if needed.  */
        if (!is_plt && info->shared)
*************** set_pltoff_entry (abfd, info, dyn_i, val
*** 2955,2965 ****
  	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
  					ia64_info->rel_pltoff_sec,
  					dyn_i->pltoff_offset,
! 					dyn_r_type, 0, 0);
  	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
  					ia64_info->rel_pltoff_sec,
  					dyn_i->pltoff_offset + 8,
! 					dyn_r_type, 0, 0);
  	}
  
        dyn_i->pltoff_done = 1;
--- 2951,2961 ----
  	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
  					ia64_info->rel_pltoff_sec,
  					dyn_i->pltoff_offset,
! 					dyn_r_type, 0, value);
  	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
  					ia64_info->rel_pltoff_sec,
  					dyn_i->pltoff_offset + 8,
! 					dyn_r_type, 0, gp);
  	}
  
        dyn_i->pltoff_done = 1;
*************** elfNN_ia64_relocate_section (output_bfd,
*** 3366,3371 ****
--- 3362,3368 ----
  	    {
  	      unsigned int dyn_r_type;
  	      long dynindx;
+ 	      bfd_vma addend;
  
  	      BFD_ASSERT (srel != NULL);
  
*************** elfNN_ia64_relocate_section (output_bfd,
*** 3373,3379 ****
  		 matching RELATIVE relocation.  */
  	      dyn_r_type = r_type;
  	      if (dynamic_symbol_p)
! 		dynindx = h->dynindx;
  	      else
  		{
  		  switch (r_type)
--- 3370,3380 ----
  		 matching RELATIVE relocation.  */
  	      dyn_r_type = r_type;
  	      if (dynamic_symbol_p)
! 		{
! 		  dynindx = h->dynindx;
! 		  addend = rel->r_addend;
! 		  value = 0;
! 		}
  	      else
  		{
  		  switch (r_type)
*************** elfNN_ia64_relocate_section (output_bfd,
*** 3405,3415 ****
  		      continue;
  		    }
  		  dynindx = 0;
  		}
  
  	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
  					    srel, rel->r_offset, dyn_r_type,
! 					    dynindx, rel->r_addend);
  	    }
  	  /* FALLTHRU */
  
--- 3406,3417 ----
  		      continue;
  		    }
  		  dynindx = 0;
+ 		  addend = value;
  		}
  
  	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
  					    srel, rel->r_offset, dyn_r_type,
! 					    dynindx, addend);
  	    }
  	  /* FALLTHRU */
  
*************** elfNN_ia64_relocate_section (output_bfd,
*** 3678,3700 ****
  	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
  	  break;
  
- 	case R_IA64_SEGBASE:
- 
- 	case R_IA64_REL32MSB:
- 	case R_IA64_REL32LSB:
- 	case R_IA64_REL64MSB:
- 	case R_IA64_REL64LSB:
- 
  	case R_IA64_IPLTMSB:
  	case R_IA64_IPLTLSB:
! 	case R_IA64_EPLTMSB:
! 	case R_IA64_EPLTLSB:
! 	case R_IA64_COPY:
  
! 	case R_IA64_TPREL22:
! 	case R_IA64_TPREL64MSB:
! 	case R_IA64_TPREL64LSB:
! 	case R_IA64_LTOFF_TP22:
  	default:
  	  r = bfd_reloc_notsupported;
  	  break;
--- 3680,3730 ----
  	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
  	  break;
  
  	case R_IA64_IPLTMSB:
  	case R_IA64_IPLTLSB:
! 	  /* Install a dynamic relocation for this reloc.  */
! 	  if ((dynamic_symbol_p || info->shared)
! 	      && (input_section->flags & SEC_ALLOC) != 0)
! 	    {
! 	      long dynindx;
  
! 	      BFD_ASSERT (srel != NULL);
! 
! 	      /* If we don't need dynamic symbol lookup, install two
! 		 RELATIVE relocations.  */
! 	      if (! dynamic_symbol_p)
! 		{
! 		  unsigned int dyn_r_type;
! 		
! 		  if (r_type == R_IA64_IPLTMSB)
! 		    dyn_r_type = R_IA64_REL64MSB;
! 		  else
! 		    dyn_r_type = R_IA64_REL64LSB;
! 
! 		  elfNN_ia64_install_dyn_reloc (output_bfd, info,
! 						input_section,
! 						srel, rel->r_offset,
! 						dyn_r_type, 0, value);
! 		  elfNN_ia64_install_dyn_reloc (output_bfd, info,
! 						input_section,
! 						srel, rel->r_offset + 8,
! 						dyn_r_type, 0, gp_val);
! 		}
! 	      else
! 		elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
! 					      srel, rel->r_offset, r_type,
! 					      h->dynindx, rel->r_addend);
! 	    }
! 
! 	  if (r_type == R_IA64_IPLTMSB)
! 	    r_type = R_IA64_DIR64MSB;
! 	  else
! 	    r_type = R_IA64_DIR64LSB;
! 	  elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
! 	  r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
! 					r_type);
! 	  break;
! 
  	default:
  	  r = bfd_reloc_notsupported;
  	  break;
Index: reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.30
diff -c -p -d -r1.30 reloc.c
*** reloc.c	2000/09/03 02:57:52	1.30
--- reloc.c	2000/11/16 22:43:34
*************** ENUMX
*** 2834,2841 ****
  ENUMX
    BFD_RELOC_IA64_LTOFF_FPTR64LSB
  ENUMX
-   BFD_RELOC_IA64_SEGBASE
- ENUMX
    BFD_RELOC_IA64_SEGREL32MSB
  ENUMX
    BFD_RELOC_IA64_SEGREL32LSB
--- 2834,2839 ----
*************** ENUMX
*** 2871,2880 ****
    BFD_RELOC_IA64_IPLTMSB
  ENUMX
    BFD_RELOC_IA64_IPLTLSB
- ENUMX
-   BFD_RELOC_IA64_EPLTMSB
- ENUMX
-   BFD_RELOC_IA64_EPLTLSB
  ENUMX
    BFD_RELOC_IA64_COPY
  ENUMX
--- 2869,2874 ----

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