diff options
author | Kaz Kojima <kkojima@rr.iij4u.or.jp> | 2003-10-15 06:23:55 +0000 |
---|---|---|
committer | Kaz Kojima <kkojima@rr.iij4u.or.jp> | 2003-10-15 06:23:55 +0000 |
commit | 46e993b970891cc96da82849a3b22fd769fe609a (patch) | |
tree | 7fe6d347d890b6ba47e0049f5d23dcc9d90d9cd3 | |
parent | 3d390fc11a544515512973496879f277ef64fc42 (diff) | |
download | binutils-46e993b970891cc96da82849a3b22fd769fe609a.zip binutils-46e993b970891cc96da82849a3b22fd769fe609a.tar.gz binutils-46e993b970891cc96da82849a3b22fd769fe609a.tar.bz2 |
[bfd]
* elf32-sh.c (sh_elf_relocate_section): Handle R_SH_IMM_*_PCREL
relocations.
(sh_elf_check_relocs): Likewise.
* elf32-sh64.c (elf_backend_merge_symbol_attribute): Define.
(sh64_elf_merge_symbol_attribute): New.
* elf64-sh64.c (elf_backend_merge_symbol_attribute): Define.
(sh64_elf64_merge_symbol_attribute): New.
[ld/testsuite]
* ld-sh/sh64/rd-sh64.exp: If the test matches *-dso.d, copy
the output of linker to the file tmpdir/*-dso.so.
* ld-sh/sh64/stobin-0-dso.d: New.
* ld-sh/sh64/stobin-1.d: New.
* ld-sh/sh64/stobin.s: New.
* ld-sh/sh64/stolib.s: New.
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elf32-sh.c | 34 | ||||
-rw-r--r-- | bfd/elf32-sh64.c | 22 | ||||
-rw-r--r-- | bfd/elf64-sh64.c | 24 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-sh/sh64/rd-sh64.exp | 11 | ||||
-rw-r--r-- | ld/testsuite/ld-sh/sh64/stobin-0-dso.d | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-sh/sh64/stobin-1.d | 15 | ||||
-rw-r--r-- | ld/testsuite/ld-sh/sh64/stobin.s | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-sh/sh64/stolib.s | 7 |
10 files changed, 145 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d41c0a6..635c6ae 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2003-10-15 Kaz Kojima <kkojima@rr.iij4u.or.jp> + + * elf32-sh.c (sh_elf_relocate_section): Handle R_SH_IMM_*_PCREL + relocations. + (sh_elf_check_relocs): Likewise. + + * elf32-sh64.c (elf_backend_merge_symbol_attribute): Define. + (sh64_elf_merge_symbol_attribute): New. + * elf64-sh64.c (elf_backend_merge_symbol_attribute): Define. + (sh64_elf64_merge_symbol_attribute): New. + 2003-10-14 Kaz Kojima <kkojima@rr.iij4u.or.jp> * elf-bfd.h (struct elf_backend_data): New function pointer member diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index a3b2133..836b34b 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -5081,13 +5081,19 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 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 && (h == NULL || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || h->root.type != bfd_link_hash_undefweak) && r_symndx != 0 && (input_section->flags & SEC_ALLOC) != 0 - && (r_type != R_SH_REL32 + && (r_type == R_SH_DIR32 || !SYMBOL_CALLS_LOCAL (info, h))) { Elf_Internal_Rela outrel; @@ -5140,6 +5146,17 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, outrel.r_addend = bfd_get_32 (input_bfd, contents + rel->r_offset); } +#ifdef INCLUDE_SHMEDIA + else if (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) + { + BFD_ASSERT (h != NULL && h->dynindx != -1); + outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); + outrel.r_addend = addend; + } +#endif else { /* h->dynindx may be -1 if this symbol was marked to @@ -6655,6 +6672,12 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, 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; @@ -6772,7 +6795,14 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, } p->count += 1; - if (r_type == R_SH_REL32) + if (r_type == R_SH_REL32 +#ifdef INCLUDE_SHMEDIA + || 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 +#endif + ) p->pc_count += 1; } diff --git a/bfd/elf32-sh64.c b/bfd/elf32-sh64.c index 288003e..c3be09f 100644 --- a/bfd/elf32-sh64.c +++ b/bfd/elf32-sh64.c @@ -85,6 +85,7 @@ static void sh64_find_section_for_address #define elf_backend_add_symbol_hook sh64_elf_add_symbol_hook #define elf_backend_link_output_symbol_hook \ sh64_elf_link_output_symbol_hook +#define elf_backend_merge_symbol_attribute sh64_elf_merge_symbol_attribute #define elf_backend_final_write_processing sh64_elf_final_write_processing #define elf_backend_section_from_shdr sh64_backend_section_from_shdr #define elf_backend_special_sections sh64_elf_special_sections @@ -735,6 +736,27 @@ sh64_elf_final_write_processing (bfd *abfd, } } +/* Merge non visibility st_other attribute when the symbol comes from + a dynamic object. */ +static void +sh64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, + const Elf_Internal_Sym *isym, + bfd_boolean definition, + bfd_boolean dynamic) +{ + if (isym->st_other != 0 && dynamic) + { + unsigned char other; + + /* Take the balance of OTHER from the definition. */ + other = (definition ? isym->st_other : h->other); + other &= ~ ELF_ST_VISIBILITY (-1); + h->other = other | ELF_ST_VISIBILITY (h->other); + } + + return; +} + static struct bfd_elf_special_section const sh64_elf_special_sections[]= { { ".cranges", 8, 0, SHT_PROGBITS, 0 }, diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index e05145e..1a679d3 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -4118,6 +4118,27 @@ sh64_elf64_finish_dynamic_sections (bfd *output_bfd, return TRUE; } +/* Merge non visibility st_other attribute when the symbol comes from + a dynamic object. */ +static void +sh64_elf64_merge_symbol_attribute (struct elf_link_hash_entry *h, + const Elf_Internal_Sym *isym, + bfd_boolean definition, + bfd_boolean dynamic) +{ + if (isym->st_other != 0 && dynamic) + { + unsigned char other; + + /* Take the balance of OTHER from the definition. */ + other = (definition ? isym->st_other : h->other); + other &= ~ ELF_ST_VISIBILITY (-1); + h->other = other | ELF_ST_VISIBILITY (h->other); + } + + return; +} + static struct bfd_elf_special_section const sh64_elf64_special_sections[]= { { ".cranges", 8, 0, SHT_PROGBITS, 0 }, @@ -4164,6 +4185,9 @@ static struct bfd_elf_special_section const sh64_elf64_special_sections[]= #define elf_backend_link_output_symbol_hook \ sh64_elf64_link_output_symbol_hook +#define elf_backend_merge_symbol_attribute \ + sh64_elf64_merge_symbol_attribute + #define elf_backend_final_write_processing \ sh64_elf64_final_write_processing diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index fd38f47..28c1605 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2003-10-15 Kaz Kojima <kkojima@rr.iij4u.or.jp> + + * ld-sh/sh64/rd-sh64.exp: If the test matches *-dso.d, copy + the output of linker to the file tmpdir/*-dso.so. + * ld-sh/sh64/stobin-0-dso.d: New. + * ld-sh/sh64/stobin-1.d: New. + * ld-sh/sh64/stobin.s: New. + * ld-sh/sh64/stolib.s: New. + 2003-10-13 Richard Sandiford <rsandifo@redht.com> * ld-mips-elf/multi-got-1.d (RELSZ): Don't include the size of the diff --git a/ld/testsuite/ld-sh/sh64/rd-sh64.exp b/ld/testsuite/ld-sh/sh64/rd-sh64.exp index cc5c3f7..6efb347 100644 --- a/ld/testsuite/ld-sh/sh64/rd-sh64.exp +++ b/ld/testsuite/ld-sh/sh64/rd-sh64.exp @@ -27,4 +27,15 @@ foreach sh64test $rd_test_list { # We need to strip the ".d", but can leave the dirname. verbose [file rootname $sh64test] run_dump_test [file rootname $sh64test] + if [string match $srcdir/$subdir/*-dso.d $sh64test] { + # Copy the output of the DSO-createing test to .so file. + # Notice that a DSO-creating test must preceed the tests + # which need that DSO in sort-order by name. + set cmd "cp tmpdir/dump \ + tmpdir/[file rootname [file tail $sh64test]].so" + send_log "$cmd\n" + set cmdret [catch "exec $cmd" comp_output] + send_log "$comp_output\n" + # FIXME: What if it fails? Need we do something? + } } diff --git a/ld/testsuite/ld-sh/sh64/stobin-0-dso.d b/ld/testsuite/ld-sh/sh64/stobin-0-dso.d new file mode 100644 index 0000000..405c05a --- /dev/null +++ b/ld/testsuite/ld-sh/sh64/stobin-0-dso.d @@ -0,0 +1,9 @@ +#source: stolib.s +#as: --abi=32 --isa=SHmedia +#ld: -shared -mshelf32 +#objdump: -drj.text +#target: sh64-*-elf + +.*: +file format elf32-sh64.* + +#pass diff --git a/ld/testsuite/ld-sh/sh64/stobin-1.d b/ld/testsuite/ld-sh/sh64/stobin-1.d new file mode 100644 index 0000000..e0f8b27 --- /dev/null +++ b/ld/testsuite/ld-sh/sh64/stobin-1.d @@ -0,0 +1,15 @@ +#source: stobin.s +#as: --abi=32 --isa=SHmedia +#ld: -mshelf32 tmpdir/stobin-0-dso.so +#objdump: -drj.text +#target: sh64-*-elf + +.*: +file format elf32-sh64.* + +Disassembly of section \.text: + +0+[0-9a-f]+ <start>: + [0-9a-f]+: cffffd90 movi -1,r25 + [0-9a-f]+: cbfee590 shori 65465,r25 ! 0xffffffb9 .* + [0-9a-f]+: 6bf56600 ptrel/l r25,tr0 + [0-9a-f]+: 4401fff0 blink tr0,r63 diff --git a/ld/testsuite/ld-sh/sh64/stobin.s b/ld/testsuite/ld-sh/sh64/stobin.s new file mode 100644 index 0000000..30d3597 --- /dev/null +++ b/ld/testsuite/ld-sh/sh64/stobin.s @@ -0,0 +1,5 @@ + .text + .globl start +start: + pt bar, tr0 + blink tr0, r63 diff --git a/ld/testsuite/ld-sh/sh64/stolib.s b/ld/testsuite/ld-sh/sh64/stolib.s new file mode 100644 index 0000000..587faa6 --- /dev/null +++ b/ld/testsuite/ld-sh/sh64/stolib.s @@ -0,0 +1,7 @@ + .text + .globl bar + .type bar,@function +bar: + ptabs r18, tr0 + blink tr0, r63 + .Lfe_bar: .size bar,.Lfe_bar-X |