This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Always descend into output section statements in lang_do_assignments


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f02cb058822459ea29a9fdaa928c2623df435908

commit f02cb058822459ea29a9fdaa928c2623df435908
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Oct 11 18:13:04 2016 +1030

    Always descend into output section statements in lang_do_assignments
    
    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.

Diff:
---
 bfd/ChangeLog                 |  8 ++++++++
 bfd/elf64-x86-64.c            |  5 ++++-
 bfd/elflink.c                 |  3 ++-
 bfd/elfxx-mips.c              |  1 +
 ld/ChangeLog                  | 11 +++++++++++
 ld/ldexp.c                    |  4 +++-
 ld/ldlang.c                   | 38 +++++++++++++++++++++++---------------
 ld/testsuite/ld-mmix/bpo-10.d |  3 +--
 ld/testsuite/ld-mmix/bpo-11.d |  3 +--
 9 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7e9476b..c3e7a7c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 2a372a6..79b8f1c 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -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)
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 1591682..2f40eb0 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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;
     }
 }
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index d618e54..cc29c0e 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -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)
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 4cfe874..1c71de1 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/ldexp.c b/ld/ldexp.c
index b2c7620..cb5e093 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -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"
diff --git a/ld/ldlang.c b/ld/ldlang.c
index fe0b844..af2ca99 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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;
 
diff --git a/ld/testsuite/ld-mmix/bpo-10.d b/ld/testsuite/ld-mmix/bpo-10.d
index 1cb7d61..6f49287 100644
--- a/ld/testsuite/ld-mmix/bpo-10.d
+++ b/ld/testsuite/ld-mmix/bpo-10.d
@@ -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                             .*
diff --git a/ld/testsuite/ld-mmix/bpo-11.d b/ld/testsuite/ld-mmix/bpo-11.d
index 9b38be8..1abf381 100644
--- a/ld/testsuite/ld-mmix/bpo-11.d
+++ b/ld/testsuite/ld-mmix/bpo-11.d
@@ -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  .*


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]