public inbox for prelink@sourceware.org
 help / color / mirror / Atom feed
* [patch] Add support for new mips relocs
@ 2008-12-03 18:46 Catherine Moore
  2008-12-03 19:37 ` Richard Sandiford
  0 siblings, 1 reply; 7+ messages in thread
From: Catherine Moore @ 2008-12-03 18:46 UTC (permalink / raw)
  To: prelink; +Cc: Catherine Moore

[-- Attachment #1: Type: text/plain, Size: 932 bytes --]


Nonpic support was recently added to gcc and binutils.  This patch adds the support to the prelinker 
for the new relocations that are generated by the nonpic implementation.  Does this look okay to 
install?

Thanks,
Catherine


	* src/arch-mips.c (mips_prelink_reloc): Handle R_MIPS_JUMP_SLOT and
	R_MIPS_COPY.
	(mips_apply_reloc): Likewise.
	(mips_reloc_class): Likewise.
	(mips_prelink_conflict_reloc): Report error for R_MIPS_COPY.
	(mips_apply_conflict_rela): Handle R_MIPS_JUMP_SLOT.
	(mips_need_rel_to_rela): Likewise.
	(mips_rel_to_rela): Handle R_MIPS_COPY.
	(mips_rela_to_rel): Likewise.
	(mips_arch_prelink): Handle DT_MIPS_PLTGOT.
	(mips_arch_undo_prelink): Likewise.
	(PL_ARCH): Add R_MIPS_JUMP_SLOT and R_MIPS_COPY.
	* src/dso.c (read_dynamic): Handle DT_MIPS_PLTGOT.
	* src/prelink.h (R_MIPS_COPY): Define.
	(R_MIPS_JUMP_SLOT): Define.
	(STO_MIPS_PLT): Define.
	(DT_MIPS_PLTGOT): Define.
	(DT_MIPS_RWPLT): Define.


[-- Attachment #2: pl.patch --]
[-- Type: text/x-patch, Size: 9334 bytes --]

*** src/arch-mips.c	(revision 230136)
--- src/arch-mips.c	(local)
*************** mips_prelink_reloc (struct prelink_info 
*** 451,456 ****
--- 451,457 ----
        break;
  
      case R_MIPS_GLOB_DAT:
+     case R_MIPS_JUMP_SLOT:
        write_ne32 (dso, r_offset, info->resolve (info, r_sym, r_type));
        break;
  
*************** mips_prelink_reloc (struct prelink_info 
*** 481,486 ****
--- 482,494 ----
  	}
        break;
  
+     case R_MIPS_COPY:
+       if (dso->ehdr.e_type == ET_EXEC)
+ 	/* COPY relocs are handled specially in generic code.  */
+ 	return 0;
+       error (0, 0, "%s: R_MIPS_COPY reloc in shared library?", dso->filename);
+       return 1;
+ 
      default:
        error (0, 0, "%s: Unknown MIPS relocation type %d",
  	     dso->filename, (int) GELF_R_TYPE (r_info));
*************** mips_prelink_conflict_reloc (DSO *dso, s
*** 596,601 ****
--- 604,613 ----
      case R_MIPS_GLOB_DAT:
        break;
  
+     case R_MIPS_COPY:
+       error (0, 0, "R_MIPS_COPY should not be present in shared libraries");
+       return 1;
+ 
      case R_MIPS_TLS_DTPMOD32:
        if (conflict != NULL && mips_get_tls (dso, conflict, &tls) == 1)
  	return 1;
*************** mips_apply_conflict_rela (struct prelink
*** 690,695 ****
--- 702,708 ----
    switch (GELF_R_TYPE (rela->r_info))
      {
      case R_MIPS_REL32:
+     case R_MIPS_JUMP_SLOT:
        buf_write_ne32 (info->dso, buf, rela->r_addend);
        break;
  
*************** mips_apply_reloc (struct prelink_info *i
*** 720,736 ****
  		  GElf_Rela *rela, char *buf)
  {
    DSO *dso;
  
    dso = info->dso;
    switch (GELF_R_TYPE (r_info))
      {
      case R_MIPS_NONE:
        break;
  
      case R_MIPS_REL32:
!       mips_apply_adjustment (dso, rela, buf,
! 			     info->resolve (info, GELF_R_SYM (r_info),
! 					    GELF_R_TYPE (r_info)));
        break;
  
      default:
--- 733,756 ----
  		  GElf_Rela *rela, char *buf)
  {
    DSO *dso;
+   GElf_Addr value;
  
+   value = info->resolve (info, GELF_R_SYM (r_info), GELF_R_TYPE (r_info));
    dso = info->dso;
    switch (GELF_R_TYPE (r_info))
      {
      case R_MIPS_NONE:
        break;
  
+     case R_MIPS_JUMP_SLOT:
+       buf_write_ne32 (info->dso, buf, value);
+       break;
+ 
+     case R_MIPS_COPY:
+       abort ();
+ 
      case R_MIPS_REL32:
!       mips_apply_adjustment (dso, rela, buf, value);
        break;
  
      default:
*************** mips_rel_to_rela (DSO *dso, GElf_Rel *re
*** 766,771 ****
--- 786,792 ----
        break;
  
      case R_MIPS_NONE:
+     case R_MIPS_COPY:
      case R_MIPS_GLOB_DAT:
      case R_MIPS_TLS_DTPMOD32:
        /* These relocations have no addend.  */
*************** mips_rela_to_rel (DSO *dso, GElf_Rela *r
*** 788,793 ****
--- 809,815 ----
    switch (GELF_R_TYPE (rela->r_info))
      {
      case R_MIPS_NONE:
+     case R_MIPS_COPY:
        break;
  
      case R_MIPS_REL32:
*************** mips_need_rel_to_rela (DSO *dso, int fir
*** 831,836 ****
--- 853,860 ----
  	    switch (ELF32_R_TYPE (rel->r_info))
  	      {
  	      case R_MIPS_NONE:
+ 	      case R_MIPS_COPY:
+ 	      case R_MIPS_JUMP_SLOT:
  		break;
  
  	      case R_MIPS_REL32:
*************** mips_need_rel_to_rela (DSO *dso, int fir
*** 871,877 ****
  
  	      default:
  		error (0, 0, "%s: Unknown MIPS relocation type %d",
! 		       dso->filename, (int) GELF_R_TYPE (rel->r_info));
  		return 1;
  	      }
  	}
--- 895,901 ----
  
  	      default:
  		error (0, 0, "%s: Unknown MIPS relocation type %d",
! 		       dso->filename, (int) ELF32_R_TYPE (rel->r_info));
  		return 1;
  	      }
  	}
*************** mips_reloc_class (int reloc_type)
*** 890,903 ****
  {
    switch (reloc_type)
      {
      case R_MIPS_TLS_DTPMOD32:
      case R_MIPS_TLS_DTPREL32:
      case R_MIPS_TLS_TPREL32:
        return RTYPE_CLASS_TLS;
      default:
!       /* MIPS lazy resolution stubs are local to the containing object,
! 	 so SHN_UNDEF symbols never participate in symbol lookup.  */
!       return RTYPE_CLASS_PLT;
      }
  }
  
--- 914,929 ----
  {
    switch (reloc_type)
      {
+     case R_MIPS_COPY:
+       return RTYPE_CLASS_COPY;
+     case R_MIPS_JUMP_SLOT:
+       return RTYPE_CLASS_PLT;
      case R_MIPS_TLS_DTPMOD32:
      case R_MIPS_TLS_DTPREL32:
      case R_MIPS_TLS_TPREL32:
        return RTYPE_CLASS_TLS;
      default:
!       return RTYPE_CLASS_VALID;
      }
  }
  
*************** mips_arch_prelink (struct prelink_info *
*** 907,914 ****
--- 933,965 ----
    struct mips_global_got_iterator ggi;
    DSO *dso;
    GElf_Addr value;
+   int i;
  
    dso = info->dso;
+ 
+   if (dso->info_DT_MIPS_PLTGOT)
+     {
+       /* Write address of .plt into gotplt[1].  This is in each
+ 	 normal gotplt entry unless prelinking.  */
+       int sec = addr_to_sec (dso, dso->info_DT_MIPS_PLTGOT);
+       Elf32_Addr data;
+ 
+       if (sec == -1)
+ 	return 1;
+ 
+       for (i = 1; i < dso->ehdr.e_shnum; i++)
+ 	if (dso->shdr[i].sh_type == SHT_PROGBITS
+ 	    && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx,
+ 				 dso->shdr[i].sh_name),
+ 			 ".plt"))
+ 	break;
+ 
+       if (i == dso->ehdr.e_shnum)
+ 	return 0;
+       data = dso->shdr[i].sh_addr;
+       write_ne32 (dso, dso->info_DT_MIPS_PLTGOT + 4, data);
+     }
+ 
    if (dso->info[DT_PLTGOT] == 0)
      return 0;
  
*************** static int
*** 953,958 ****
--- 1004,1033 ----
  mips_arch_undo_prelink (DSO *dso)
  {
    struct mips_global_got_iterator ggi;
+   int i;
+ 
+   if (dso->info_DT_MIPS_PLTGOT)
+     {
+       /* Clear gotplt[1] if it contains the address of .plt.  */
+       int sec = addr_to_sec (dso, dso->info_DT_MIPS_PLTGOT);
+       Elf32_Addr data;
+ 
+       if (sec == -1)
+ 	return 1;
+ 
+       for (i = 1; i < dso->ehdr.e_shnum; i++)
+ 	if (dso->shdr[i].sh_type == SHT_PROGBITS
+ 	    && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx,
+ 				 dso->shdr[i].sh_name),
+ 			 ".plt"))
+ 	break;
+ 
+       if (i == dso->ehdr.e_shnum)
+ 	return 0;
+       data = read_une32 (dso, dso->info_DT_MIPS_PLTGOT + 4);
+       if (data == dso->shdr[i].sh_addr)
+ 	write_ne32 (dso, dso->info_DT_MIPS_PLTGOT + 4, 0);
+     }
  
    if (dso->info[DT_PLTGOT] == 0)
      return 0;
*************** mips_arch_undo_prelink (DSO *dso)
*** 971,976 ****
--- 1046,1054 ----
  static int
  mips_undo_prelink_rel (DSO *dso, GElf_Rel *rel, GElf_Addr reladdr)
  {
+   int sec;
+   const char *name;
+ 
    /* Convert R_MIPS_GLOB_DAT relocations back into R_MIPS_REL32
       relocations.  Ideally we'd have some mechanism for recording
       these changes in the undo section, but in the absence of that,
*************** mips_undo_prelink_rel (DSO *dso, GElf_Re
*** 983,988 ****
--- 1061,1086 ----
        rel->r_info = GELF_R_INFO (GELF_R_SYM (rel->r_info), R_MIPS_REL32);
        return 2;
      }
+   else if (GELF_R_TYPE (rel->r_info) == R_MIPS_JUMP_SLOT)
+     {
+       sec = addr_to_sec (dso, rel->r_offset);
+       name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[sec].sh_name);
+       if (sec == -1 || strcmp (name, ".got.plt"))
+ 	{
+ 	  error (0, 0, "%s: R_MIPS_JUMP_SLOT not pointing into .got.plt section",
+ 		 dso->filename);
+ 	  return 1;
+ 	}
+       else
+ 	{
+ 	  Elf32_Addr data = read_une32 (dso, dso->shdr[sec].sh_addr + 4);
+ 
+ 	  assert (rel->r_offset >= dso->shdr[sec].sh_addr + 8);
+ 	  assert (((rel->r_offset - dso->shdr[sec].sh_addr) & 3) == 0);
+ 	  write_ne32 (dso, rel->r_offset, data);
+ 	}
+     }
+ 
    return 0;
  }
  
*************** PL_ARCH = {
*** 992,1001 ****
    .machine = EM_MIPS,
    .max_reloc_size = 4,
    .dynamic_linker = "/lib/ld.so.1",
!   /* MIPS does not use COPY relocs or jump slots.  Pick a value outside
!      the ELF32_R_TYPE range.  */
!   .R_COPY = ~0U,
!   .R_JMP_SLOT = ~0U,
    /* R_MIPS_REL32 relocations against symbol 0 do act as relative relocs,
       but those against other symbols don't.  */
    .R_RELATIVE = ~0U,
--- 1090,1097 ----
    .machine = EM_MIPS,
    .max_reloc_size = 4,
    .dynamic_linker = "/lib/ld.so.1",
!   .R_COPY = R_MIPS_COPY,
!   .R_JMP_SLOT = R_MIPS_JUMP_SLOT,
    /* R_MIPS_REL32 relocations against symbol 0 do act as relative relocs,
       but those against other symbols don't.  */
    .R_RELATIVE = ~0U,
*** src/dso.c	(revision 230136)
--- src/dso.c	(local)
*************** read_dynamic (DSO *dso)
*** 115,120 ****
--- 115,122 ----
  		      dso->info_DT_MIPS_GOTSYM = dyn.d_un.d_val;
  		    else if (dyn.d_tag == DT_MIPS_SYMTABNO)
  		      dso->info_DT_MIPS_SYMTABNO = dyn.d_un.d_val;
+ 		    else if (dyn.d_tag == DT_MIPS_PLTGOT)
+ 		      dso->info_DT_MIPS_PLTGOT = dyn.d_un.d_val;
  		  }
  	      }
  	    if (ndx < maxndx)
*** src/prelink.h	(revision 230136)
--- src/prelink.h	(local)
***************
*** 78,83 ****
--- 78,91 ----
  #define R_MIPS_GLOB_DAT		51
  #endif
  
+ #ifndef R_MIPS_COPY
+ #define R_MIPS_COPY		126
+ #define R_MIPS_JUMP_SLOT	127
+ #define STO_MIPS_PLT		0x8
+ #define DT_MIPS_PLTGOT		0x70000032
+ #define DT_MIPS_RWPLT		0x70000034
+ #endif
+ 
  struct prelink_entry;
  struct prelink_info;
  struct PLArch;
*************** typedef struct
*** 113,118 ****
--- 121,127 ----
    GElf_Addr info_DT_MIPS_LOCAL_GOTNO;
    GElf_Addr info_DT_MIPS_GOTSYM;
    GElf_Addr info_DT_MIPS_SYMTABNO;
+   GElf_Addr info_DT_MIPS_PLTGOT;
  #define DT_GNU_PRELINKED_BIT 50
  #define DT_CHECKSUM_BIT 51
  #define DT_VERNEED_BIT 52

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-01-12 17:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-12-03 18:46 [patch] Add support for new mips relocs Catherine Moore
2008-12-03 19:37 ` Richard Sandiford
2008-12-03 20:03   ` Daniel Jacobowitz
2008-12-03 20:12     ` Richard Sandiford
2008-12-03 20:29       ` Daniel Jacobowitz
2008-12-16 16:27         ` Daniel Jacobowitz
2009-01-12 17:28           ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).