2002-08-23 Stephen Clarke * elf32-sh.c (sh_elf_relocate_section): Handle SHmedia PC-relative relocations as dynamic relocations. (sh_elf_check_relocs): Likewise. * elf64-sh64.c (sh_elf64_relocate_section): Likewise. (sh_elf64_check_relocs): Likewise. 2002-08-23 Stephen Clarke * ld-sh/sh64/shpcrel.d, ld-sh/sh64/shpcrel.s, ld-sh/sh64/shpcrel64.d, ld-sh/sh64/shpcrel64.s: New test. Index: bfd/elf32-sh.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-sh.c,v retrieving revision 1.58 diff -u -c -3 -p -r1.58 elf32-sh.c *** bfd/elf32-sh.c 24 Aug 2002 01:44:56 -0000 1.58 --- bfd/elf32-sh.c 24 Aug 2002 05:04:19 -0000 *************** sh_elf_relocate_section (output_bfd, inf *** 4504,4510 **** && ((r_type == R_SH_DIR32 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) ! || r_type == R_SH_REL32) && ((input_section->flags & SEC_ALLOC) != 0 /* DWARF will emit R_SH_DIR32 relocations in its sections against symbols defined externally --- 4504,4514 ---- && ((r_type == R_SH_DIR32 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) ! || (r_type == R_SH_REL32 ! || r_type == R_SH_IMM_LOW16_PCREL ! || r_type == R_SH_IMM_MEDLOW16_PCREL ! || r_type == R_SH_IMM_MEDHI16_PCREL ! || r_type == R_SH_IMM_HI16_PCREL)) && ((input_section->flags & SEC_ALLOC) != 0 /* DWARF will emit R_SH_DIR32 relocations in its sections against symbols defined externally *************** sh_elf_relocate_section (output_bfd, inf *** 4614,4623 **** case R_SH_DIR32: case R_SH_REL32: if (info->shared && r_symndx != 0 && (input_section->flags & SEC_ALLOC) != 0 ! && (r_type != R_SH_REL32 || (h != NULL && h->dynindx != -1 && (! info->symbolic --- 4618,4633 ---- case R_SH_DIR32: case R_SH_REL32: + #ifdef INCLUDE_SHMEDIA + case R_SH_IMM_LOW16_PCREL: + case R_SH_IMM_MEDLOW16_PCREL: + case R_SH_IMM_MEDHI16_PCREL: + case R_SH_IMM_HI16_PCREL: + #endif if (info->shared && r_symndx != 0 && (input_section->flags & SEC_ALLOC) != 0 ! && (! howto->pc_relative || (h != NULL && h->dynindx != -1 && (! info->symbolic *************** sh_elf_relocate_section (output_bfd, inf *** 4666,4675 **** if (skip) memset (&outrel, 0, sizeof outrel); ! else if (r_type == R_SH_REL32) { BFD_ASSERT (h != NULL && h->dynindx != -1); ! outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_REL32); outrel.r_addend = bfd_get_32 (input_bfd, contents + rel->r_offset); } --- 4676,4685 ---- if (skip) memset (&outrel, 0, sizeof outrel); ! else if (howto->pc_relative) { BFD_ASSERT (h != NULL && h->dynindx != -1); ! outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); outrel.r_addend = bfd_get_32 (input_bfd, contents + rel->r_offset); } *************** sh_elf_check_relocs (abfd, info, sec, re *** 5413,5418 **** --- 5423,5429 ---- { struct elf_link_hash_entry *h; unsigned long r_symndx; + reloc_howto_type *howto; r_symndx = ELF32_R_SYM (rel->r_info); if (r_symndx < symtab_hdr->sh_info) *************** sh_elf_check_relocs (abfd, info, sec, re *** 5420,5425 **** --- 5431,5438 ---- else h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + howto = sh_elf_howto_table + ELF32_R_TYPE (rel->r_info); + /* Some relocs require a global offset table. */ if (htab->sgot == NULL) { *************** sh_elf_check_relocs (abfd, info, sec, re *** 5570,5575 **** --- 5583,5595 ---- case R_SH_DIR32: case R_SH_REL32: + #ifdef INCLUDE_SHMEDIA + case R_SH_IMM_LOW16_PCREL: + case R_SH_IMM_MEDLOW16_PCREL: + case R_SH_IMM_MEDHI16_PCREL: + case R_SH_IMM_HI16_PCREL: + #endif + if (h != NULL && ! info->shared) { h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF; *************** sh_elf_check_relocs (abfd, info, sec, re *** 5597,5603 **** symbol. */ if ((info->shared && (sec->flags & SEC_ALLOC) != 0 ! && (ELF32_R_TYPE (rel->r_info) != R_SH_REL32 || (h != NULL && (! info->symbolic || h->root.type == bfd_link_hash_defweak --- 5617,5623 ---- symbol. */ if ((info->shared && (sec->flags & SEC_ALLOC) != 0 ! && (! howto->pc_relative || (h != NULL && (! info->symbolic || h->root.type == bfd_link_hash_defweak *************** sh_elf_check_relocs (abfd, info, sec, re *** 5687,5693 **** } p->count += 1; ! if (ELF32_R_TYPE (rel->r_info) == R_SH_REL32) p->pc_count += 1; } --- 5707,5713 ---- } p->count += 1; ! if (howto->pc_relative) p->pc_count += 1; } Index: bfd/elf64-sh64.c =================================================================== RCS file: /cvs/src/src/bfd/elf64-sh64.c,v retrieving revision 1.19 diff -u -c -3 -p -r1.19 elf64-sh64.c *** bfd/elf64-sh64.c 23 Aug 2002 08:26:13 -0000 1.19 --- bfd/elf64-sh64.c 24 Aug 2002 05:04:20 -0000 *************** sh_elf64_relocate_section (output_bfd, i *** 1645,1651 **** && ((r_type == R_SH_64 && !(ELF_ST_VISIBILITY (h->other) == STV_INTERNAL || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)) ! || r_type == R_SH_64_PCREL) && ((input_section->flags & SEC_ALLOC) != 0 /* DWARF will emit R_SH_DIR32 relocations in its sections against symbols defined externally --- 1645,1655 ---- && ((r_type == R_SH_64 && !(ELF_ST_VISIBILITY (h->other) == STV_INTERNAL || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)) ! || (r_type == R_SH_64_PCREL ! || r_type == R_SH_IMM_LOW16_PCREL ! || r_type == R_SH_IMM_MEDLOW16_PCREL ! || r_type == R_SH_IMM_MEDHI16_PCREL ! || r_type == R_SH_IMM_HI16_PCREL)) && ((input_section->flags & SEC_ALLOC) != 0 /* DWARF will emit R_SH_DIR32 relocations in its sections against symbols defined externally *************** sh_elf64_relocate_section (output_bfd, i *** 1709,1717 **** { case R_SH_64: case R_SH_64_PCREL: if (info->shared && (input_section->flags & SEC_ALLOC) != 0 ! && (r_type != R_SH_64_PCREL || (h != NULL && h->dynindx != -1 && (! info->symbolic --- 1713,1725 ---- { case R_SH_64: case R_SH_64_PCREL: + case R_SH_IMM_LOW16_PCREL: + case R_SH_IMM_MEDLOW16_PCREL: + case R_SH_IMM_MEDHI16_PCREL: + case R_SH_IMM_HI16_PCREL: if (info->shared && (input_section->flags & SEC_ALLOC) != 0 ! && (! howto->pc_relative || (h != NULL && h->dynindx != -1 && (! info->symbolic *************** sh_elf64_relocate_section (output_bfd, i *** 1762,1771 **** if (skip) memset (&outrel, 0, sizeof outrel); ! else if (r_type == R_SH_64_PCREL) { BFD_ASSERT (h != NULL && h->dynindx != -1); ! outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64_PCREL); outrel.r_addend = rel->r_addend; } else --- 1770,1779 ---- if (skip) memset (&outrel, 0, sizeof outrel); ! else if (howto->pc_relative) { BFD_ASSERT (h != NULL && h->dynindx != -1); ! outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); outrel.r_addend = rel->r_addend; } else *************** sh_elf64_relocate_section (output_bfd, i *** 1802,1808 **** if (! relocate) continue; } ! else if (r_type == R_SH_64) addend = rel->r_addend; goto final_link_relocate; --- 1810,1820 ---- if (! relocate) continue; } ! else if (r_type == R_SH_64 ! || r_type == R_SH_IMM_LOW16_PCREL ! || r_type == R_SH_IMM_MEDLOW16_PCREL ! || r_type == R_SH_IMM_MEDHI16_PCREL ! || r_type == R_SH_IMM_HI16_PCREL) addend = rel->r_addend; goto final_link_relocate; *************** sh_elf64_relocate_section (output_bfd, i *** 2071,2083 **** case R_SH_IMMS16: case R_SH_IMMU16: case R_SH_IMM_LOW16: - case R_SH_IMM_LOW16_PCREL: case R_SH_IMM_MEDLOW16: - case R_SH_IMM_MEDLOW16_PCREL: case R_SH_IMM_MEDHI16: - case R_SH_IMM_MEDHI16_PCREL: case R_SH_IMM_HI16: - case R_SH_IMM_HI16_PCREL: addend = rel->r_addend; /* Fall through. */ case R_SH_REL32: --- 2083,2091 ---- *************** sh_elf64_check_relocs (abfd, info, sec, *** 2501,2506 **** --- 2509,2515 ---- { struct elf_link_hash_entry *h; unsigned long r_symndx; + reloc_howto_type *howto; r_symndx = ELF64_R_SYM (rel->r_info); if (r_symndx < symtab_hdr->sh_info) *************** sh_elf64_check_relocs (abfd, info, sec, *** 2508,2513 **** --- 2517,2524 ---- else h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + howto = sh_elf64_howto_table + ELF64_R_TYPE (rel->r_info); + /* Some relocs require a global offset table. */ if (dynobj == NULL) { *************** sh_elf64_check_relocs (abfd, info, sec, *** 2737,2742 **** --- 2748,2757 ---- case R_SH_64: case R_SH_64_PCREL: + case R_SH_IMM_LOW16_PCREL: + case R_SH_IMM_MEDLOW16_PCREL: + case R_SH_IMM_MEDHI16_PCREL: + case R_SH_IMM_HI16_PCREL: if (h != NULL) h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF; *************** sh_elf64_check_relocs (abfd, info, sec, *** 2754,2760 **** pcrel_relocs_copied field of the hash table entry. */ if (info->shared && (sec->flags & SEC_ALLOC) != 0 ! && (ELF32_R_TYPE (rel->r_info) != R_SH_64_PCREL || (h != NULL && (! info->symbolic || (h->elf_link_hash_flags --- 2769,2775 ---- pcrel_relocs_copied field of the hash table entry. */ if (info->shared && (sec->flags & SEC_ALLOC) != 0 ! && (! howto->pc_relative || (h != NULL && (! info->symbolic || (h->elf_link_hash_flags *************** sh_elf64_check_relocs (abfd, info, sec, *** 2806,2812 **** hash table, which means that h is really a pointer to an elf_sh_link_hash_entry. */ if (h != NULL && info->symbolic ! && ELF64_R_TYPE (rel->r_info) == R_SH_64_PCREL) { struct elf_sh64_link_hash_entry *eh; struct elf_sh64_pcrel_relocs_copied *p; --- 2821,2827 ---- hash table, which means that h is really a pointer to an elf_sh_link_hash_entry. */ if (h != NULL && info->symbolic ! && howto->pc_relative) { struct elf_sh64_link_hash_entry *eh; struct elf_sh64_pcrel_relocs_copied *p; Index: ld/testsuite/ld-sh/sh64/shpcrel.d =================================================================== RCS file: ld/testsuite/ld-sh/sh64/shpcrel.d diff -N ld/testsuite/ld-sh/sh64/shpcrel.d *** /dev/null 1 Jan 1970 00:00:00 -0000 --- ld/testsuite/ld-sh/sh64/shpcrel.d 24 Aug 2002 05:04:22 -0000 *************** *** 0 **** --- 1,13 ---- + #source: shpcrel.s + #as: --abi=32 --isa=SHmedia + #ld: -shared -mshelf32 + #readelf: -r + #target: sh64-*-elf + + # Make sure that we get PC-relative dynamic relocations + # in a shared library. + + Relocation section '.rela.dyn' at offset 0x358 contains 2 entries: + Offset Info Type Sym\.Value Sym\. Name \+ Addend + 00000370 00000ef9 R_SH_IMM_MEDLOW16 00000000 yyy \+ cc000000 + 00000374 00000ef7 R_SH_IMM_LOW16_PC 00000000 yyy \+ c8000000 Index: ld/testsuite/ld-sh/sh64/shpcrel.s =================================================================== RCS file: ld/testsuite/ld-sh/sh64/shpcrel.s diff -N ld/testsuite/ld-sh/sh64/shpcrel.s *** /dev/null 1 Jan 1970 00:00:00 -0000 --- ld/testsuite/ld-sh/sh64/shpcrel.s 24 Aug 2002 05:04:22 -0000 *************** *** 0 **** --- 1,5 ---- + .text + .global xxx + xxx: movi ((yyy-l)>>16)&0xffff,r0 + shori (yyy-l)&0xffff,r0 + l: ptrel r0,tr0 Index: ld/testsuite/ld-sh/sh64/shpcrel64.d =================================================================== RCS file: ld/testsuite/ld-sh/sh64/shpcrel64.d diff -N ld/testsuite/ld-sh/sh64/shpcrel64.d *** /dev/null 1 Jan 1970 00:00:00 -0000 --- ld/testsuite/ld-sh/sh64/shpcrel64.d 24 Aug 2002 05:04:22 -0000 *************** *** 0 **** --- 1,15 ---- + #source: shpcrel64.s + #as: --abi=64 --isa=SHmedia + #ld: -shared -mshelf64 + #readelf: -r + #target: sh64-*-elf + + # Make sure that we get PC-relative dynamic relocations + # in a shared library. + + Relocation section '.rela.dyn' at offset 0x480 contains 4 entries: + Offset Info Type Sym\. Value Sym\. Name \+ Addend + 0000000004e0 000e000000fd R_SH_IMM_HI16_PCR 0000000000000000 yyy \+ ffffffef + 0000000004e4 000e000000fb R_SH_IMM_MEDHI16_ 0000000000000000 yyy \+ fffffff3 + 0000000004e8 000e000000f9 R_SH_IMM_MEDLOW16 0000000000000000 yyy \+ fffffff7 + 0000000004ec 000e000000f7 R_SH_IMM_LOW16_PC 0000000000000000 yyy \+ fffffffb Index: ld/testsuite/ld-sh/sh64/shpcrel64.s =================================================================== RCS file: ld/testsuite/ld-sh/sh64/shpcrel64.s diff -N ld/testsuite/ld-sh/sh64/shpcrel64.s *** /dev/null 1 Jan 1970 00:00:00 -0000 --- ld/testsuite/ld-sh/sh64/shpcrel64.s 24 Aug 2002 05:04:22 -0000 *************** *** 0 **** --- 1,7 ---- + .text + .global xxx + xxx: movi ((yyy-l)>>48)&0xffff,r0 + shori ((yyy-l)>>32)&0xffff,r0 + shori ((yyy-l)>>16)&0xffff,r0 + shori (yyy-l)&0xffff,r0 + l: ptrel r0,tr0