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.
This commit is contained in:
Alan Modra 2016-10-11 18:13:04 +10:30
parent 3b202c1080
commit f02cb05882
9 changed files with 53 additions and 21 deletions

View 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

View 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)

View 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;
}
}

View 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)

View 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.

View 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"

View 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;
}
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);
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);
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;

View 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 .*

View 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 .*