Always descend into output section statements in lang_do_assignments
authorAlan Modra <amodra@gmail.com>
Tue, 11 Oct 2016 07:43:04 +0000 (18:13 +1030)
committerAlan Modra <amodra@gmail.com>
Tue, 11 Oct 2016 07:43:04 +0000 (18:13 +1030)
See https://sourceware.org/ml/binutils/2016-07/msg00091.html
This patch stop --gc-sections elf_gc_sweep_symbol localizing symbols
that ought to remain global.

The difficulty with always descending into output section statements
is that symbols defined by the script in such statements don't have
a bfd section when lang_do_assignments runs early in the link process.
There are two approaches to curing this problem.  Either we can
create the bfd section early, or we can use a special section.  This
patch takes the latter approach and uses bfd_und_section.  (Creating
bfd sections early results in changed output section order, and thus
lots of testsuite failures.  You can't create all output sections
early to ensure proper ordering as KEEP then stops empty sections
from being stripped.)

The wrinkle with this approach is that some code that runs at
gc-sections time needs to be made aware of the odd defined symbols
using bfd_und_section.

bfd/
* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Handle symbols
defined temporarily with bfd_und_section.
* elflink.c (_bfd_elf_gc_keep): Don't set SEC_KEEP for bfd_und_section.
* elfxx-mips.c (mips_elf_local_pic_function_p): Exclude defined
symbols with bfd_und_section.
ld/
* ldlang.c (lang_do_assignments_1): Descend into output section
statements that do not yet have bfd sections.  Set symbol section
temporarily for symbols defined in such statements to the undefined
section.  Don't error on data or reloc statements until final phase.
* ldexp.c (exp_fold_tree_1 <etree_assign>): Handle bfd_und_section
in expld.section.
* testsuite/ld-mmix/bpo-10.d: Adjust.
* testsuite/ld-mmix/bpo-11.d: Adjust.

bfd/ChangeLog
bfd/elf64-x86-64.c
bfd/elflink.c
bfd/elfxx-mips.c
ld/ChangeLog
ld/ldexp.c
ld/ldlang.c
ld/testsuite/ld-mmix/bpo-10.d
ld/testsuite/ld-mmix/bpo-11.d

index 7e9476baa26f66fa3c11321ae577518712b4648c..c3e7a7c2b8feac4a91dc111ab592773fe121d694 100644 (file)
@@ -1,3 +1,11 @@
+2016-10-11  Alan Modra  <amodra@gmail.com>
+
+       * elf64-x86-64.c (elf_x86_64_convert_load_reloc): Handle symbols
+       defined temporarily with bfd_und_section.
+       * elflink.c (_bfd_elf_gc_keep): Don't set SEC_KEEP for bfd_und_section.
+       * elfxx-mips.c (mips_elf_local_pic_function_p): Exclude defined
+       symbols with bfd_und_section.
+
 2016-10-07  Alan Modra  <amodra@gmail.com>
 
        * targets.c (bfd_target <_bfd_merge_private_bfd_data>): Replace
index 2a372a6f3f5757bdd8844c9cbb8ce705cc8777ef..79b8f1c7e4c263255447830c2dbc569faebbde31 100644 (file)
@@ -1877,7 +1877,10 @@ elf_x86_64_convert_load_reloc (bfd *abfd, asection *sec,
             bfd_elf_record_link_assignment.   */
          if (h->def_regular
              && (h->root.type == bfd_link_hash_new
-                 || h->root.type == bfd_link_hash_undefined))
+                 || h->root.type == bfd_link_hash_undefined
+                 || ((h->root.type == bfd_link_hash_defined
+                      || h->root.type == bfd_link_hash_defweak)
+                     && h->root.u.def.section == bfd_und_section_ptr)))
            {
              /* Skip since R_X86_64_32/R_X86_64_32S may overflow.  */
              if (require_reloc_pc32)
index 1591682bce824fda63d2bd59dfff5b37d967455d..2f40eb09682e850880c00f8651208ffa0825dcd4 100644 (file)
@@ -13037,7 +13037,8 @@ _bfd_elf_gc_keep (struct bfd_link_info *info)
       if (h != NULL
          && (h->root.type == bfd_link_hash_defined
              || h->root.type == bfd_link_hash_defweak)
-         && !bfd_is_abs_section (h->root.u.def.section))
+         && !bfd_is_abs_section (h->root.u.def.section)
+         && !bfd_is_und_section (h->root.u.def.section))
        h->root.u.def.section->flags |= SEC_KEEP;
     }
 }
index d618e542e56edcbb1f2dc1cc46badd4e009ddaa1..cc29c0ef9b0029c1bb3c9f5185873ad052411990 100644 (file)
@@ -1808,6 +1808,7 @@ mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
           || h->root.root.type == bfd_link_hash_defweak)
          && h->root.def_regular
          && !bfd_is_abs_section (h->root.root.u.def.section)
+         && !bfd_is_und_section (h->root.root.u.def.section)
          && (!ELF_ST_IS_MIPS16 (h->root.other)
              || (h->fn_stub && h->need_fn_stub))
          && (PIC_OBJECT_P (h->root.root.u.def.section->owner)
index 4cfe8740a4e0dcaef7ae302d616b8197c8a2d9be..1c71de1966beb6852a4411d58d7086ec4a892129 100644 (file)
@@ -1,3 +1,14 @@
+2016-10-11  Alan Modra  <amodra@gmail.com>
+
+       * ldlang.c (lang_do_assignments_1): Descend into output section
+       statements that do not yet have bfd sections.  Set symbol section
+       temporarily for symbols defined in such statements to the undefined
+       section.  Don't error on data or reloc statements until final phase.
+       * ldexp.c (exp_fold_tree_1 <etree_assign>): Handle bfd_und_section
+       in expld.section.
+       * testsuite/ld-mmix/bpo-10.d: Adjust.
+       * testsuite/ld-mmix/bpo-11.d: Adjust.
+
 2016-10-10  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
        * emulparams/elf64_s390.sh: Move binary start to 16M.
index b2c762036da7cbad047b5cf2bbcbf7163fd34784..cb5e0935513ffe032e09b9d8badccf81ad410123 100644 (file)
@@ -1077,6 +1077,7 @@ exp_fold_tree_1 (etree_type *tree)
                 before relaxation and so be stripped incorrectly.  */
              if (expld.phase == lang_mark_phase_enum
                  && expld.section != bfd_abs_section_ptr
+                 && expld.section != bfd_und_section_ptr
                  && !(expld.result.valid_p
                       && expld.result.value == 0
                       && (is_value (tree->assign.src, 0)
@@ -1085,7 +1086,8 @@ exp_fold_tree_1 (etree_type *tree)
                           || is_align_conditional (tree->assign.src))))
                expld.section->flags |= SEC_KEEP;
 
-             if (!expld.result.valid_p)
+             if (!expld.result.valid_p
+                 || expld.section == bfd_und_section_ptr)
                {
                  if (expld.phase != lang_mark_phase_enum)
                    einfo (_("%F%S invalid assignment to"
index fe0b84476426093c933982bc61684b14f90a6f23..af2ca996380a23ede7beacf4dd79c3322b904164 100644 (file)
@@ -5618,6 +5618,7 @@ lang_do_assignments_1 (lang_statement_union_type *s,
        case lang_output_section_statement_enum:
          {
            lang_output_section_statement_type *os;
+           bfd_vma newdot;
 
            os = &(s->output_section_statement);
            os->after_end = *found_end;
@@ -5629,18 +5630,24 @@ lang_do_assignments_1 (lang_statement_union_type *s,
                    prefer_next_section = FALSE;
                  }
                dot = os->bfd_section->vma;
-
-               lang_do_assignments_1 (os->children.head,
-                                      os, os->fill, dot, found_end);
-
-               /* .tbss sections effectively have zero size.  */
-               if (!IS_TBSS (os->bfd_section)
-                   || bfd_link_relocatable (&link_info))
-                 dot += TO_ADDR (os->bfd_section->size);
-
-               if (os->update_dot_tree != NULL)
-                 exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr,
-                                &dot);
+             }
+           newdot = lang_do_assignments_1 (os->children.head,
+                                           os, os->fill, dot, found_end);
+           if (!os->ignored)
+             {
+               if (os->bfd_section != NULL)
+                 {
+                   /* .tbss sections effectively have zero size.  */
+                   if (!IS_TBSS (os->bfd_section)
+                       || bfd_link_relocatable (&link_info))
+                     dot += TO_ADDR (os->bfd_section->size);
+
+                   if (os->update_dot_tree != NULL)
+                     exp_fold_tree (os->update_dot_tree,
+                                    bfd_abs_section_ptr, &dot);
+                 }
+               else
+                 dot = newdot;
              }
          }
          break;
@@ -5664,7 +5671,7 @@ lang_do_assignments_1 (lang_statement_union_type *s,
              if (expld.result.section != NULL)
                s->data_statement.value += expld.result.section->vma;
            }
-         else
+         else if (expld.phase == lang_final_phase_enum)
            einfo (_("%F%P: invalid data statement\n"));
          {
            unsigned int size;
@@ -5697,7 +5704,7 @@ lang_do_assignments_1 (lang_statement_union_type *s,
                         bfd_abs_section_ptr, &dot);
          if (expld.result.valid_p)
            s->reloc_statement.addend_value = expld.result.value;
-         else
+         else if (expld.phase == lang_final_phase_enum)
            einfo (_("%F%P: invalid reloc statement\n"));
          dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto));
          break;
@@ -5733,7 +5740,8 @@ lang_do_assignments_1 (lang_statement_union_type *s,
                *found_end = TRUE;
            }
          exp_fold_tree (s->assignment_statement.exp,
-                        current_os->bfd_section,
+                        (current_os->bfd_section != NULL
+                         ? current_os->bfd_section : bfd_und_section_ptr),
                         &dot);
          break;
 
index 1cb7d611eea006d78df9f6eed00a5486d73387e1..6f49287e58818cec8ea502a1286fde5c8a1c874f 100644 (file)
@@ -14,11 +14,10 @@ SYMBOL TABLE:
 0+7f8 l +d  \.MMIX.reg_contents        0+ (|\.MMIX\.reg_contents)
 0+ l    df \*ABS\*     0+ .*
 0+ l       \.init      0+ _start
-0+ l    df \*ABS\*     0+ .*
-0+4 l       \.init     0+ _start\.
 2000000000000000 g       \.init        0+ __bss_start
 2000000000000000 g       \.init        0+ _edata
 2000000000000000 g       \.init        0+ _end
+0+4 g       \.init     0+ _start\.
 
 Contents of section \.init:
  0000 e37704a6                             .*
index 9b38be8913b228d8b58713e4786fe5c53751c89d..1abf38140d691dcc0208b8492d86c704c553da93 100644 (file)
@@ -16,13 +16,12 @@ SYMBOL TABLE:
 0+7e8 l    d  \.MMIX\.reg_contents     0+ (|\.MMIX\.reg_contents)
 0+ l    df \*ABS\*     0+ .*
 0+ l       \.init      0+ _start
-0+ l    df \*ABS\*     0+ .*
-0+10 l       \.text    0+ _start\.
 0+14 g       \.text    0+ x
 0+10 g       \.text    0+ x2
 2000000000000000 g       \.text        0+ __bss_start
 2000000000000000 g       \.text        0+ _edata
 2000000000000000 g       \.text        0+ _end
+0+10 g       \.text    0+ _start\.
 
 Contents of section \.init:
  0000 00000000 0000003d 00000000 0000003a  .*