From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22667 invoked by alias); 31 May 2005 23:04:25 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 22622 invoked by uid 22791); 31 May 2005 23:04:13 -0000 Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Tue, 31 May 2005 23:04:13 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11/8.12.11) with ESMTP id j4VN4CjP001985 for ; Tue, 31 May 2005 19:04:12 -0400 Received: from potter.sfbay.redhat.com (potter.sfbay.redhat.com [172.16.27.15]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id j4VN4BO02834 for ; Tue, 31 May 2005 19:04:11 -0400 Received: from presidente.sfbay.redhat.com (presidente.sfbay.redhat.com [192.168.28.6]) by potter.sfbay.redhat.com (8.12.8/8.12.8) with ESMTP id j4VN4AZF012782 for ; Tue, 31 May 2005 19:04:10 -0400 Received: from presidente.sfbay.redhat.com (localhost.localdomain [127.0.0.1]) by presidente.sfbay.redhat.com (8.13.1/8.13.1) with ESMTP id j4VN3b0r010463 for ; Tue, 31 May 2005 16:03:37 -0700 Received: (from rth@localhost) by presidente.sfbay.redhat.com (8.13.1/8.13.1/Submit) id j4VN3bHq010460 for binutils@gcc.gnu.org; Tue, 31 May 2005 16:03:37 -0700 Date: Tue, 31 May 2005 23:43:00 -0000 From: Richard Henderson To: binutils@gcc.gnu.org Subject: Add lituse_jsrdirect relocation for alpha Message-ID: <20050531230336.GA10254@presidente.sfbay.redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i X-SW-Source: 2005-05/txt/msg00774.txt.bz2 In the secureplt format, we clobber more registers than in the old format, which means that we can not allow the special integer division routines to be vectored through the plt. For the most part this can be solved in libc, by not marking the division routines STT_FUNC. That works except in the case that the user builds a shared library but does not link it against libc. In that case, the linker would have no information that __divq is special and would vector the call through the plt anyway, leading to corruption. While not linking against all of the required libraries is A Highly Questionable Practice, it did work before. This adds a LITUSE form that requests relaxation as for a call, but does not allow the linker to fall back to a plt entry. This is backward compatible with old linkers, in that LITUSE is, and has always been, a hint, and we ignore forms that we don't recognize. Indeed, we ignore them to the extent that we won't process them for plt entries either, which has the desired correctness effect as well. r~ bfd/ * elf64-alpha.c (ALPHA_ELF_LINK_HASH_LU_JSRDIRECT): New. (ALPHA_ELF_LINK_HASH_TLS_IE): Renumber to 0x80. (ALPHA_ELF_LINK_HASH_LU_PLT): Rename from ALPHA_ELF_LINK_HASH_LU_FUNC. (elf64_alpha_want_plt): Update to match. (elf64_alpha_check_relocs): Collect JSRDIRECT in gotent_flags. (elf64_alpha_relax_with_lituse): Likewise. Handle JSRDIRECT. binutils/ * readelf.c (dump_relocations): Special case R_ALPHA_LITUSE. gas/ * config/tc-alpha.c (O_lituse_jsrdirect): New. (alpha_reloc_op): Add it. (debug_exp): Handle it. (DUMMY_RELOC_LITUSE_JSRDIRECT): New. (emit_insn): Handle it. * doc/c-alpha.texi (Alpha-Relocs): Document lituse_jsrdirect. include/elf/ * alpha.h (LITUSE_ALPHA_JSRDIRECT): New. Index: bfd/elf64-alpha.c =================================================================== RCS file: /cvs/src/src/bfd/elf64-alpha.c,v retrieving revision 1.140 diff -u -p -d -r1.140 elf64-alpha.c --- bfd/elf64-alpha.c 30 May 2005 21:22:40 -0000 1.140 +++ bfd/elf64-alpha.c 31 May 2005 22:37:03 -0000 @@ -112,14 +112,15 @@ struct alpha_elf_link_hash_entry int flags; /* Contexts in which a literal was referenced. */ -#define ALPHA_ELF_LINK_HASH_LU_ADDR 0x01 -#define ALPHA_ELF_LINK_HASH_LU_MEM 0x02 -#define ALPHA_ELF_LINK_HASH_LU_BYTE 0x04 -#define ALPHA_ELF_LINK_HASH_LU_JSR 0x08 -#define ALPHA_ELF_LINK_HASH_LU_TLSGD 0x10 -#define ALPHA_ELF_LINK_HASH_LU_TLSLDM 0x20 -#define ALPHA_ELF_LINK_HASH_LU_FUNC 0x38 -#define ALPHA_ELF_LINK_HASH_TLS_IE 0x40 +#define ALPHA_ELF_LINK_HASH_LU_ADDR 0x01 +#define ALPHA_ELF_LINK_HASH_LU_MEM 0x02 +#define ALPHA_ELF_LINK_HASH_LU_BYTE 0x04 +#define ALPHA_ELF_LINK_HASH_LU_JSR 0x08 +#define ALPHA_ELF_LINK_HASH_LU_TLSGD 0x10 +#define ALPHA_ELF_LINK_HASH_LU_TLSLDM 0x20 +#define ALPHA_ELF_LINK_HASH_LU_JSRDIRECT 0x40 +#define ALPHA_ELF_LINK_HASH_LU_PLT 0x38 +#define ALPHA_ELF_LINK_HASH_TLS_IE 0x80 /* Used to implement multiple .got subsections. */ struct alpha_elf_got_entry @@ -1729,8 +1730,8 @@ elf64_alpha_want_plt (struct alpha_elf_l return ((ah->root.type == STT_FUNC || ah->root.root.type == bfd_link_hash_undefweak || ah->root.root.type == bfd_link_hash_undefined) - && (ah->flags & ALPHA_ELF_LINK_HASH_LU_FUNC) != 0 - && (ah->flags & ~ALPHA_ELF_LINK_HASH_LU_FUNC) == 0); + && (ah->flags & ALPHA_ELF_LINK_HASH_LU_PLT) != 0 + && (ah->flags & ~ALPHA_ELF_LINK_HASH_LU_PLT) == 0); } /* Handle dynamic relocations when doing an Alpha ELF link. */ @@ -1826,7 +1827,7 @@ elf64_alpha_check_relocs (bfd *abfd, str This will be important when it comes to decide if we can create a .plt entry for a function symbol. */ while (++rel < relend && ELF64_R_TYPE (rel->r_info) == R_ALPHA_LITUSE) - if (rel->r_addend >= 1 && rel->r_addend <= 5) + if (rel->r_addend >= 1 && rel->r_addend <= 6) gotent_flags |= 1 << rel->r_addend; --rel; @@ -3137,7 +3138,7 @@ elf64_alpha_relax_with_lituse (struct al { if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE) break; - if (urel->r_addend <= 3) + if (urel->r_addend <= 6) flags |= 1 << urel->r_addend; } @@ -3232,6 +3233,7 @@ elf64_alpha_relax_with_lituse (struct al case LITUSE_ALPHA_JSR: case LITUSE_ALPHA_TLSGD: case LITUSE_ALPHA_TLSLDM: + case LITUSE_ALPHA_JSRDIRECT: { bfd_vma optdest, org; bfd_signed_vma odisp; Index: binutils/readelf.c =================================================================== RCS file: /cvs/src/src/binutils/readelf.c,v retrieving revision 1.298 diff -u -p -d -r1.298 readelf.c --- binutils/readelf.c 29 May 2005 23:18:51 -0000 1.298 +++ binutils/readelf.c 31 May 2005 22:37:07 -0000 @@ -1243,7 +1243,31 @@ dump_relocations (FILE *file, else printf (do_wide ? "%-22.22s" : "%-17.17s", rtype); - if (symtab_index) + if (elf_header.e_machine == EM_ALPHA + && streq (rtype, "R_ALPHA_LITUSE") + && is_rela) + { + switch (rels[i].r_addend) + { + case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break; + case LITUSE_ALPHA_BASE: rtype = "BASE"; break; + case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break; + case LITUSE_ALPHA_JSR: rtype = "JSR"; break; + case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break; + case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break; + case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break; + default: rtype = NULL; + } + if (rtype) + printf (" (%s)", rtype); + else + { + putchar (' '); + printf (_(""), + (unsigned long) rels[i].r_addend); + } + } + else if (symtab_index) { if (symtab == NULL || symtab_index >= nsyms) printf (" bad symbol index: %08lx", (unsigned long) symtab_index); @@ -1309,8 +1333,7 @@ dump_relocations (FILE *file, print_vma (rels[i].r_addend, LONG_HEX); } - if (elf_header.e_machine == EM_SPARCV9 - && streq (rtype, "R_SPARC_OLO10")) + if (elf_header.e_machine == EM_SPARCV9 && streq (rtype, "R_SPARC_OLO10")) printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info)); putchar ('\n'); Index: gas/config/tc-alpha.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-alpha.c,v retrieving revision 1.67 diff -u -p -d -r1.67 tc-alpha.c --- gas/config/tc-alpha.c 5 May 2005 09:12:53 -0000 1.67 +++ gas/config/tc-alpha.c 31 May 2005 22:37:08 -0000 @@ -109,28 +109,29 @@ struct alpha_macro #define O_cpregister O_md2 /* + a leading comma. */ /* The alpha_reloc_op table below depends on the ordering of these. */ -#define O_literal O_md3 /* !literal relocation. */ -#define O_lituse_addr O_md4 /* !lituse_addr relocation. */ -#define O_lituse_base O_md5 /* !lituse_base relocation. */ -#define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */ -#define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */ -#define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */ -#define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */ -#define O_gpdisp O_md10 /* !gpdisp relocation. */ -#define O_gprelhigh O_md11 /* !gprelhigh relocation. */ -#define O_gprellow O_md12 /* !gprellow relocation. */ -#define O_gprel O_md13 /* !gprel relocation. */ -#define O_samegp O_md14 /* !samegp relocation. */ -#define O_tlsgd O_md15 /* !tlsgd relocation. */ -#define O_tlsldm O_md16 /* !tlsldm relocation. */ -#define O_gotdtprel O_md17 /* !gotdtprel relocation. */ -#define O_dtprelhi O_md18 /* !dtprelhi relocation. */ -#define O_dtprello O_md19 /* !dtprello relocation. */ -#define O_dtprel O_md20 /* !dtprel relocation. */ -#define O_gottprel O_md21 /* !gottprel relocation. */ -#define O_tprelhi O_md22 /* !tprelhi relocation. */ -#define O_tprello O_md23 /* !tprello relocation. */ -#define O_tprel O_md24 /* !tprel relocation. */ +#define O_literal O_md3 /* !literal relocation. */ +#define O_lituse_addr O_md4 /* !lituse_addr relocation. */ +#define O_lituse_base O_md5 /* !lituse_base relocation. */ +#define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */ +#define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */ +#define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */ +#define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */ +#define O_lituse_jsrdirect O_md10 /* !lituse_jsrdirect relocation. */ +#define O_gpdisp O_md11 /* !gpdisp relocation. */ +#define O_gprelhigh O_md12 /* !gprelhigh relocation. */ +#define O_gprellow O_md13 /* !gprellow relocation. */ +#define O_gprel O_md14 /* !gprel relocation. */ +#define O_samegp O_md15 /* !samegp relocation. */ +#define O_tlsgd O_md16 /* !tlsgd relocation. */ +#define O_tlsldm O_md17 /* !tlsldm relocation. */ +#define O_gotdtprel O_md18 /* !gotdtprel relocation. */ +#define O_dtprelhi O_md19 /* !dtprelhi relocation. */ +#define O_dtprello O_md20 /* !dtprello relocation. */ +#define O_dtprel O_md21 /* !dtprel relocation. */ +#define O_gottprel O_md22 /* !gottprel relocation. */ +#define O_tprelhi O_md23 /* !tprelhi relocation. */ +#define O_tprello O_md24 /* !tprello relocation. */ +#define O_tprel O_md25 /* !tprel relocation. */ #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1) #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2) @@ -138,6 +139,7 @@ struct alpha_macro #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4) #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5) #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6) +#define DUMMY_RELOC_LITUSE_JSRDIRECT (BFD_RELOC_UNUSED + 7) #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel) @@ -418,6 +420,7 @@ alpha_reloc_op[] = DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1), DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1), DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1), + DEF (lituse_jsrdirect, DUMMY_RELOC_LITUSE_JSRDIRECT, 1, 1), DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1), DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0), DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0), @@ -770,6 +773,7 @@ debug_exp (expressionS tok[], int ntok) case O_lituse_jsr: name = "O_lituse_jsr"; break; case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break; case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break; + case O_lituse_jsrdirect: name = "O_lituse_jsrdirect"; break; case O_gpdisp: name = "O_gpdisp"; break; case O_gprelhigh: name = "O_gprelhigh"; break; case O_gprellow: name = "O_gprellow"; break; @@ -1720,6 +1724,9 @@ emit_insn (struct alpha_insn *insn) case DUMMY_RELOC_LITUSE_TLSLDM: fixP->fx_offset = LITUSE_ALPHA_TLSLDM; goto do_lituse; + case DUMMY_RELOC_LITUSE_JSRDIRECT: + fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT; + goto do_lituse; do_lituse: fixP->fx_addsy = section_symbol (now_seg); fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE; Index: include/elf/alpha.h =================================================================== RCS file: /cvs/src/src/include/elf/alpha.h,v retrieving revision 1.11 diff -u -p -d -r1.11 alpha.h --- include/elf/alpha.h 29 May 2005 23:18:26 -0000 1.11 +++ include/elf/alpha.h 31 May 2005 22:37:09 -0000 @@ -125,5 +125,6 @@ END_RELOC_NUMBERS (R_ALPHA_max) #define LITUSE_ALPHA_JSR 3 #define LITUSE_ALPHA_TLSGD 4 #define LITUSE_ALPHA_TLSLDM 5 +#define LITUSE_ALPHA_JSRDIRECT 6 #endif /* _ELF_ALPHA_H */ ? gas/doc/as.info Index: gas/doc/c-alpha.texi =================================================================== RCS file: /cvs/src/src/gas/doc/c-alpha.texi,v retrieving revision 1.7 diff -u -p -d -r1.7 c-alpha.texi --- gas/doc/c-alpha.texi 3 Mar 2005 01:29:53 -0000 1.7 +++ gas/doc/c-alpha.texi 31 May 2005 22:50:57 -0000 @@ -203,6 +203,12 @@ Used with a register branch format instr indicate that the literal is used for a call. During relaxation, the code may be altered to use a direct branch (e.g.@: @code{bsr}). +@item !lituse_jsrdirect!@var{N} +Similar to @code{lituse_jsr}, but also that this call cannot be vectored +through a PLT entry. This is useful for functions with special calling +conventions which do not allow the normal call-clobbered registers to be +clobbered. + @item !lituse_bytoff!@var{N} Used with a byte mask instruction (e.g.@: @code{extbl}) to indicate that only the low 3 bits of the address are relevant. During relaxation,