From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3458 invoked by alias); 3 Dec 2008 18:46:34 -0000 Received: (qmail 3450 invoked by uid 22791); 3 Dec 2008 18:46:33 -0000 X-Spam-Level: * X-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 03 Dec 2008 18:45:57 +0000 Received: (qmail 5040 invoked from network); 3 Dec 2008 18:45:55 -0000 Received: from unknown (HELO ?192.168.89.128?) (clm@127.0.0.2) by mail.codesourcery.com with ESMTPA; 3 Dec 2008 18:45:55 -0000 Message-ID: <4936D3D3.6030306@codesourcery.com> Date: Wed, 03 Dec 2008 18:46:00 -0000 From: Catherine Moore User-Agent: Thunderbird 2.0.0.14 (X11/20080502) MIME-Version: 1.0 To: prelink@sourceware.org CC: Catherine Moore Subject: [patch] Add support for new mips relocs Content-Type: multipart/mixed; boundary="------------080508070000040802000609" X-Virus-Checked: Checked by ClamAV on sourceware.org Mailing-List: contact prelink-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: prelink-owner@sourceware.org X-SW-Source: 2008-q4/txt/msg00001.txt.bz2 This is a multi-part message in MIME format. --------------080508070000040802000609 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 932 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. --------------080508070000040802000609 Content-Type: text/x-patch; name="pl.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="pl.patch" Content-length: 9334 *** 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 --------------080508070000040802000609--