public inbox for prelink@sourceware.org
 help / color / mirror / Atom feed
From: Catherine Moore <clm@codesourcery.com>
To: prelink@sourceware.org
Cc: Catherine Moore <clm@codesourcery.com>
Subject: [patch] Add support for new mips relocs
Date: Wed, 03 Dec 2008 18:46:00 -0000	[thread overview]
Message-ID: <4936D3D3.6030306@codesourcery.com> (raw)

[-- 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

             reply	other threads:[~2008-12-03 18:46 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-03 18:46 Catherine Moore [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4936D3D3.6030306@codesourcery.com \
    --to=clm@codesourcery.com \
    --cc=prelink@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).