Copy st_other for linker script symbol assignments
authorAlan Modra <amodra@gmail.com>
Tue, 8 Jul 2014 05:54:06 +0000 (15:24 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 8 Jul 2014 10:12:03 +0000 (19:42 +0930)
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
bfd/bfd-in2.h
bfd/elflink.c
bfd/linker.c
bfd/targets.c
ld/testsuite/ChangeLog
ld/testsuite/ld-powerpc/defsym.d [new file with mode: 0644]
ld/testsuite/ld-powerpc/defsym.s [new file with mode: 0644]
ld/testsuite/ld-powerpc/powerpc.exp

index deed8cede5c537494aba88368c4ef89dc93924a7..48280c49195bf2ae791a7fe16c90787e181f25fa 100644 (file)
@@ -1,3 +1,12 @@
+2014-07-08  Alan Modra  <amodra@gmail.com>
+
+       * 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  <jiong.wang@arm.com>
 
        * elfnn-aarch64.c (elf_backend_rela_normal): Set to 1.
index ec19492d906038358e7587fad5497f939d743be2..3886adc7e838e07c4081a3afd977c0cb2b2ca82d 100644 (file)
@@ -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)
index ee80bcc7e2ee76f1b0263869a3ed57e96267bbee..46d65f471a4ca0b5dda29b4e6e195f30d63b1700 100644 (file)
@@ -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.  */
index 483a0d4ea921a38a213e83919909bb3b3c00356b..f6ae4e2c6264b07e7042507f0641c37644a96dcf 100644 (file)
@@ -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)
 {
 }
 
index 83131d1cfde768d2508a482046d0e5a9e055ff97..81a36959d42c60e1266e3980a72c1248e2beb86d 100644 (file)
@@ -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)
index bbef087cfdd8793b0fa549fad42bfd792613999e..340c23f94e3cae498c17eca68482fe87113b7523 100644 (file)
@@ -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  <amodra@gmail.com>
+
+       * ld-powerpc/defsym.s, * ld-powerpc/defsym.d: New test.
+       * ld-powerpc/powerpc.exp: Run it.
+
 2014-07-08  Alan Modra  <amodra@gmail.com>
 
        PR 17112
diff --git a/ld/testsuite/ld-powerpc/defsym.d b/ld/testsuite/ld-powerpc/defsym.d
new file mode 100644 (file)
index 0000000..1e5b567
--- /dev/null
@@ -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 (file)
index 0000000..efca072
--- /dev/null
@@ -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
index 08a7e2b53fb38bca32aa4e8b98291e46b17c0edc..23572c69a451f4105113f28cc24ffd308494f8e4 100644 (file)
@@ -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*"] } {