From bffebb6ba5b4ddbca7353626d682f9f974584dbf Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 8 Jul 2014 15:24:06 +0930 Subject: [PATCH] Copy st_other for linker script symbol assignments This fixes a problem seen on powerpc64le ELFv2 when creating a function symbol alias with ld --defsym. st_other needs to be copied from the source symbol to the alias in order to set up the local entry offset for the alias. I decided to make this change in the generic ELF code rather than in elf64-ppc.c since it looks like other targets that use st_other bits might benefit too. bfd/ * elflink.c (_bfd_elf_copy_link_hash_symbol_type): Copy st_other bits from source to dest. * linker.c (_bfd_generic_copy_link_hash_symbol_type): Update comment. * targets.c (struct bfd_target <_bfd_copy_link_hash_symbol_type>): Likewise. * bfd-in2.h: Regenerate. ld/testsuite/ * ld-powerpc/defsym.s, * ld-powerpc/defsym.d: New test. * ld-powerpc/powerpc.exp: Run it. --- bfd/ChangeLog | 9 +++++++++ bfd/bfd-in2.h | 3 ++- bfd/elflink.c | 19 +++++++++++++------ bfd/linker.c | 9 ++++----- bfd/targets.c | 3 ++- ld/testsuite/ChangeLog | 5 +++++ ld/testsuite/ld-powerpc/defsym.d | 26 ++++++++++++++++++++++++++ ld/testsuite/ld-powerpc/defsym.s | 19 +++++++++++++++++++ ld/testsuite/ld-powerpc/powerpc.exp | 1 + 9 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 ld/testsuite/ld-powerpc/defsym.d create mode 100644 ld/testsuite/ld-powerpc/defsym.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index deed8cede5c..48280c49195 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2014-07-08 Alan Modra + + * elflink.c (_bfd_elf_copy_link_hash_symbol_type): Copy st_other + bits from source to dest. + * linker.c (_bfd_generic_copy_link_hash_symbol_type): Update comment. + * targets.c (struct bfd_target <_bfd_copy_link_hash_symbol_type>): + Likewise. + * bfd-in2.h: Regenerate. + 2014-07-08 Jiong Wang * elfnn-aarch64.c (elf_backend_rela_normal): Set to 1. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index ec19492d906..3886adc7e83 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -7084,7 +7084,8 @@ typedef struct bfd_target /* Indicate that we are only retrieving symbol values from this section. */ void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); - /* Copy the symbol type of a linker hash table entry. */ + /* Copy the symbol type and other attributes for a linker script + assignment of one symbol to another. */ #define bfd_copy_link_hash_symbol_type(b, t, f) \ BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f)) void (*_bfd_copy_link_hash_symbol_type) diff --git a/bfd/elflink.c b/bfd/elflink.c index ee80bcc7e2e..46d65f471a4 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -13044,17 +13044,24 @@ _bfd_elf_make_dynamic_reloc_section (asection * sec, return reloc_sec; } -/* Copy the ELF symbol type associated with a linker hash entry. */ +/* Copy the ELF symbol type and other attributes for a linker script + assignment from HSRC to HDEST. Generally this should be treated as + if we found a strong non-dynamic definition for HDEST (except that + ld ignores multiple definition errors). */ void -_bfd_elf_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_hash_entry * hdest, - struct bfd_link_hash_entry * hsrc) +_bfd_elf_copy_link_hash_symbol_type (bfd *abfd, + struct bfd_link_hash_entry *hdest, + struct bfd_link_hash_entry *hsrc) { - struct elf_link_hash_entry *ehdest = (struct elf_link_hash_entry *)hdest; - struct elf_link_hash_entry *ehsrc = (struct elf_link_hash_entry *)hsrc; + struct elf_link_hash_entry *ehdest = (struct elf_link_hash_entry *) hdest; + struct elf_link_hash_entry *ehsrc = (struct elf_link_hash_entry *) hsrc; + Elf_Internal_Sym isym; ehdest->type = ehsrc->type; ehdest->target_internal = ehsrc->target_internal; + + isym.st_other = ehsrc->other; + elf_merge_st_other (abfd, ehdest, &isym, TRUE, FALSE); } /* Append a RELA relocation REL to section S in BFD. */ diff --git a/bfd/linker.c b/bfd/linker.c index 483a0d4ea92..f6ae4e2c626 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -861,14 +861,13 @@ _bfd_generic_link_just_syms (asection *sec, sec->output_offset = sec->vma; } -/* Copy the type of a symbol assiciated with a linker hast table entry. - Override this so that symbols created in linker scripts get their - type from the RHS of the assignment. +/* Copy the symbol type and other attributes for a linker script + assignment from HSRC to HDEST. The default implementation does nothing. */ void _bfd_generic_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_hash_entry * hdest ATTRIBUTE_UNUSED, - struct bfd_link_hash_entry * hsrc ATTRIBUTE_UNUSED) + struct bfd_link_hash_entry *hdest ATTRIBUTE_UNUSED, + struct bfd_link_hash_entry *hsrc ATTRIBUTE_UNUSED) { } diff --git a/bfd/targets.c b/bfd/targets.c index 83131d1cfde..81a36959d42 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -478,7 +478,8 @@ BFD_JUMP_TABLE macros. . {* Indicate that we are only retrieving symbol values from this section. *} . void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); . -. {* Copy the symbol type of a linker hash table entry. *} +. {* Copy the symbol type and other attributes for a linker script +. assignment of one symbol to another. *} .#define bfd_copy_link_hash_symbol_type(b, t, f) \ . BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f)) . void (*_bfd_copy_link_hash_symbol_type) diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index bbef087cfdd..340c23f94e3 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -5,6 +5,11 @@ * ld-aarch64/emit-relocs-local-addend.d: New testcase. * ld-aarch64/local-addend-r.d: Likewise. +2014-07-08 Alan Modra + + * ld-powerpc/defsym.s, * ld-powerpc/defsym.d: New test. + * ld-powerpc/powerpc.exp: Run it. + 2014-07-08 Alan Modra PR 17112 diff --git a/ld/testsuite/ld-powerpc/defsym.d b/ld/testsuite/ld-powerpc/defsym.d new file mode 100644 index 00000000000..1e5b567a785 --- /dev/null +++ b/ld/testsuite/ld-powerpc/defsym.d @@ -0,0 +1,26 @@ +#source: defsym.s +#as: -a64 +#ld: -melf64ppc --defsym bar=foo +#objdump: -Dr + +.*: file format elf64-powerpc.* + +Disassembly of section \.text: + +0+100000b0 <_start>: + 100000b0: (15 00 00 48|48 00 00 15) bl 100000c4 <(foo|bar)\+0x8> + 100000b4: (11 00 00 48|48 00 00 11) bl 100000c4 <(foo|bar)\+0x8> + 100000b8: (00 00 00 60|60 00 00 00) nop + +0+100000bc <(foo|bar)>: + 100000bc: (02 10 40 3c|3c 40 10 02) lis r2,4098 + 100000c0: (c8 80 42 38|38 42 80 c8) addi r2,r2,-32568 + 100000c4: (20 00 80 4e|4e 80 00 20) blr + +Disassembly of section \.data: + +0+100100c8 .*: + 100100c8: (bc 00 00 10|00 00 00 00) .* + 100100cc: (00 00 00 00|10 00 00 bc) .* + 100100d0: (bc 00 00 10|00 00 00 00) .* + 100100d4: (00 00 00 00|10 00 00 bc) .* diff --git a/ld/testsuite/ld-powerpc/defsym.s b/ld/testsuite/ld-powerpc/defsym.s new file mode 100644 index 00000000000..efca072ca3c --- /dev/null +++ b/ld/testsuite/ld-powerpc/defsym.s @@ -0,0 +1,19 @@ + .text + .globl _start +_start: + bl foo + bl bar + nop + + .globl foo + .type foo,@function +foo: + addis 2,12,.TOC.-foo@ha + addi 2,2,.TOC.-foo@l + .localentry foo,.-foo + blr + .size foo,.-foo + + .data + .dc.a foo + .dc.a bar diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp index 08a7e2b53fb..23572c69a45 100644 --- a/ld/testsuite/ld-powerpc/powerpc.exp +++ b/ld/testsuite/ld-powerpc/powerpc.exp @@ -278,6 +278,7 @@ if [ supports_ppc64 ] then { run_dump_test "ambiguousv1b" run_dump_test "ambiguousv2" run_dump_test "ambiguousv2b" + run_dump_test "defsym" } if { [istarget "powerpc*-eabi*"] } { -- 2.30.2