2005-05-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR 797
	* elf32-i386.c (elf_i386_size_dynamic_sections): Also remove
	empty sdynbss section.
	* elf64-x86-64.c (elf64_x86_64_size_dynamic_sections): Likewise.

ld/

2005-05-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR 797
	* ldexp.c (exp_fold_tree_1): Renamed from exp_fold_tree and
	take take a bfd_boolean, mark_used. Ignore assert failure if
	mark_used is TRUE.
	(exp_fold_tree) Call exp_fold_tree_1 with mark_used == FALSE.
	(exp_fold_tree_no_dot): Updated to take a bfd_boolean,
	mark_used and pass down.
	(fold_unary): Likewise.
	(fold_binary): Likewise.
	(fold_trinary): Likewise.
	(exp_binop): Add FALSE to call to exp_fold_tree_no_dot.
	(exp_trinop): Likewise.
	(exp_unop): Likewise.
	(exp_nameop): Likewise.
	(exp_get_vma): Likewise.
	(exp_get_fill): Likewise.
	(exp_get_abs_int): Likewise.
	(fold_name): Likewise. Set SEC_KEEP in output section flags.
	(exp_mark_used_section): New.

	* ldexp.h (exp_mark_used_section): New.

	* ldlang.c (lang_output_section_statement_lookup_1): Set the
	ignored field to FALSE.
	(lang_mark_used_section_1): New.
	(lang_mark_used_section): Call lang_mark_used_section_1.
	(strip_excluded_output_sections): Call lang_mark_used_section
	and check for unused sections.
	(lang_size_sections_1): Skip an output section if it should
	be ignored.
	(lang_do_assignments_1): Likewise.
	(lang_process): Don't call lang_mark_used_section here.

	* ldlang.h (lang_output_section_statement_type): Change
	all_input_readonly to bitfield. Add ignored.

ld/testsuite/

2005-05-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR 797
	* empty-aligned.d: New file.
	* empty-aligned.exp: Likewise.
	* empty-aligned.s: Likewise.
	* empty-aligned.t: Likewise.
This commit is contained in:
H.J. Lu
2005-05-17 16:43:02 +00:00
parent 8e0ed13fa5
commit 75ff45898c
13 changed files with 444 additions and 93 deletions

View File

@ -41,8 +41,12 @@
#include "libiberty.h"
#include "safe-ctype.h"
static etree_value_type exp_fold_tree_1
(etree_type *, lang_output_section_statement_type *,
lang_phase_type, bfd_vma, bfd_vma *, bfd_boolean);
static etree_value_type exp_fold_tree_no_dot
(etree_type *, lang_output_section_statement_type *, lang_phase_type);
(etree_type *, lang_output_section_statement_type *, lang_phase_type,
bfd_boolean);
static bfd_vma align_n
(bfd_vma, bfd_vma);
@ -219,13 +223,14 @@ fold_unary (etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot,
bfd_vma *dotp)
bfd_vma *dotp,
bfd_boolean mark_used)
{
etree_value_type result;
result = exp_fold_tree (tree->unary.child,
current_section,
allocation_done, dot, dotp);
result = exp_fold_tree_1 (tree->unary.child,
current_section,
allocation_done, dot, dotp, mark_used);
if (result.valid_p)
{
switch (tree->type.node_code)
@ -308,12 +313,13 @@ fold_binary (etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot,
bfd_vma *dotp)
bfd_vma *dotp,
bfd_boolean mark_used)
{
etree_value_type result;
result = exp_fold_tree (tree->binary.lhs, current_section,
allocation_done, dot, dotp);
result = exp_fold_tree_1 (tree->binary.lhs, current_section,
allocation_done, dot, dotp, mark_used);
/* The SEGMENT_START operator is special because its first
operand is a string, not the name of a symbol. */
@ -338,9 +344,10 @@ fold_binary (etree_type *tree,
{
etree_value_type other;
other = exp_fold_tree (tree->binary.rhs,
current_section,
allocation_done, dot, dotp);
other = exp_fold_tree_1 (tree->binary.rhs,
current_section,
allocation_done,
dot, dotp, mark_used);
if (other.valid_p)
{
/* If the values are from different sections, or this is an
@ -498,18 +505,20 @@ fold_trinary (etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot,
bfd_vma *dotp)
bfd_vma *dotp,
bfd_boolean mark_used)
{
etree_value_type result;
result = exp_fold_tree (tree->trinary.cond, current_section,
allocation_done, dot, dotp);
result = exp_fold_tree_1 (tree->trinary.cond, current_section,
allocation_done, dot, dotp, mark_used);
if (result.valid_p)
result = exp_fold_tree ((result.value
? tree->trinary.lhs
: tree->trinary.rhs),
current_section,
allocation_done, dot, dotp);
result = exp_fold_tree_1 ((result.value
? tree->trinary.lhs
: tree->trinary.rhs),
current_section,
allocation_done,
dot, dotp, mark_used);
return result;
}
@ -518,7 +527,8 @@ static etree_value_type
fold_name (etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot)
bfd_vma dot,
bfd_boolean mark_used)
{
etree_value_type result;
@ -596,6 +606,7 @@ fold_name (etree_type *tree,
+ h->u.def.section->output_offset),
NULL,
os);
os->bfd_section->flags |= SEC_KEEP;
}
}
}
@ -619,8 +630,12 @@ fold_name (etree_type *tree,
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
if (os && os->processed > 0)
result = new_rel (0, NULL, os);
if (os)
{
os->bfd_section->flags |= SEC_KEEP;
if (os->processed > 0)
result = new_rel (0, NULL, os);
}
}
break;
@ -630,14 +645,19 @@ fold_name (etree_type *tree,
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
if (os && os->processed != 0)
if (os)
{
if (os->load_base == NULL)
result = new_rel (0, NULL, os);
else
result = exp_fold_tree_no_dot (os->load_base,
abs_output_section,
allocation_done);
os->bfd_section->flags |= SEC_KEEP;
if (os->processed != 0)
{
if (os->load_base == NULL)
result = new_rel (0, NULL, os);
else
result = exp_fold_tree_no_dot (os->load_base,
abs_output_section,
allocation_done,
mark_used);
}
}
}
break;
@ -649,8 +669,12 @@ fold_name (etree_type *tree,
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
if (os && os->processed > 0)
result = new_abs (os->bfd_section->size / opb);
if (os)
{
os->bfd_section->flags |= SEC_KEEP;
if (os->processed > 0)
result = new_abs (os->bfd_section->size / opb);
}
}
break;
@ -688,12 +712,13 @@ fold_name (etree_type *tree,
return result;
}
etree_value_type
exp_fold_tree (etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot,
bfd_vma *dotp)
static etree_value_type
exp_fold_tree_1 (etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot,
bfd_vma *dotp,
bfd_boolean mark_used)
{
etree_value_type result;
@ -721,26 +746,34 @@ exp_fold_tree (etree_type *tree,
break;
case etree_assert:
result = exp_fold_tree (tree->assert_s.child,
current_section,
allocation_done, dot, dotp);
if (result.valid_p && !result.value)
einfo ("%X%P: %s\n", tree->assert_s.message);
result = exp_fold_tree_1 (tree->assert_s.child,
current_section,
allocation_done, dot, dotp,
mark_used);
if (result.valid_p)
{
if (mark_used)
/* We don't care if assert fails or not when we are just
marking if a section is used or not. */
result.value = 1;
else if (!result.value)
einfo ("%X%P: %s\n", tree->assert_s.message);
}
break;
case etree_unary:
result = fold_unary (tree, current_section, allocation_done,
dot, dotp);
dot, dotp, mark_used);
break;
case etree_binary:
result = fold_binary (tree, current_section, allocation_done,
dot, dotp);
dot, dotp, mark_used);
break;
case etree_trinary:
result = fold_trinary (tree, current_section, allocation_done,
dot, dotp);
dot, dotp, mark_used);
break;
case etree_assign:
@ -757,9 +790,10 @@ exp_fold_tree (etree_type *tree,
{
/* Notify the folder that this is an assignment to dot. */
assigning_to_dot = TRUE;
result = exp_fold_tree (tree->assign.src,
current_section,
allocation_done, dot, dotp);
result = exp_fold_tree_1 (tree->assign.src,
current_section,
allocation_done,
dot, dotp, mark_used);
assigning_to_dot = FALSE;
if (! result.valid_p)
@ -788,9 +822,9 @@ exp_fold_tree (etree_type *tree,
}
else
{
result = exp_fold_tree (tree->assign.src,
current_section, allocation_done,
dot, dotp);
result = exp_fold_tree_1 (tree->assign.src,
current_section, allocation_done,
dot, dotp, mark_used);
if (result.valid_p)
{
bfd_boolean create;
@ -832,7 +866,8 @@ exp_fold_tree (etree_type *tree,
break;
case etree_name:
result = fold_name (tree, current_section, allocation_done, dot);
result = fold_name (tree, current_section, allocation_done, dot,
mark_used);
break;
default:
@ -844,12 +879,25 @@ exp_fold_tree (etree_type *tree,
return result;
}
etree_value_type
exp_fold_tree (etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done,
bfd_vma dot,
bfd_vma *dotp)
{
return exp_fold_tree_1 (tree, current_section, allocation_done,
dot, dotp, FALSE);
}
static etree_value_type
exp_fold_tree_no_dot (etree_type *tree,
lang_output_section_statement_type *current_section,
lang_phase_type allocation_done)
lang_phase_type allocation_done,
bfd_boolean mark_used)
{
return exp_fold_tree (tree, current_section, allocation_done, 0, NULL);
return exp_fold_tree_1 (tree, current_section, allocation_done, 0,
NULL, mark_used);
}
etree_type *
@ -864,7 +912,7 @@ exp_binop (int code, etree_type *lhs, etree_type *rhs)
value.type.node_class = etree_binary;
r = exp_fold_tree_no_dot (&value,
abs_output_section,
lang_first_phase_enum);
lang_first_phase_enum, FALSE);
if (r.valid_p)
{
return exp_intop (r.value);
@ -884,7 +932,7 @@ exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
value.trinary.cond = cond;
value.trinary.rhs = rhs;
value.type.node_class = etree_trinary;
r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum);
r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum, FALSE);
if (r.valid_p)
return exp_intop (r.value);
@ -903,7 +951,7 @@ exp_unop (int code, etree_type *child)
value.unary.child = child;
value.unary.type.node_class = etree_unary;
r = exp_fold_tree_no_dot (&value, abs_output_section,
lang_first_phase_enum);
lang_first_phase_enum, FALSE);
if (r.valid_p)
return exp_intop (r.value);
@ -921,7 +969,7 @@ exp_nameop (int code, const char *name)
value.name.name = name;
value.name.type.node_class = etree_name;
r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum);
r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum, FALSE);
if (r.valid_p)
return exp_intop (r.value);
@ -1071,7 +1119,8 @@ exp_get_vma (etree_type *tree,
if (tree != NULL)
{
r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
r = exp_fold_tree_no_dot (tree, abs_output_section,
allocation_done, FALSE);
if (! r.valid_p && name != NULL)
einfo (_("%F%S nonconstant expression for %s\n"), name);
return r.value;
@ -1103,7 +1152,8 @@ exp_get_fill (etree_type *tree,
if (tree == NULL)
return def;
r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done,
FALSE);
if (! r.valid_p && name != NULL)
einfo (_("%F%S nonconstant expression for %s\n"), name);
@ -1154,7 +1204,8 @@ exp_get_abs_int (etree_type *tree,
lang_phase_type allocation_done)
{
etree_value_type res;
res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done,
FALSE);
if (res.valid_p)
res.value += res.section->bfd_section->vma;
@ -1173,3 +1224,91 @@ align_n (bfd_vma value, bfd_vma align)
value = (value + align - 1) / align;
return value * align;
}
void
exp_mark_used_section
(etree_type *tree,
lang_output_section_statement_type *current_section)
{
switch (tree->type.node_class)
{
case etree_value:
break;
case etree_rel:
break;
case etree_assert:
break;
case etree_unary:
break;
case etree_binary:
break;
case etree_trinary:
break;
case etree_assign:
case etree_provide:
case etree_provided:
if (tree->assign.dst[0] != '.' || tree->assign.dst[1] != 0)
{
etree_value_type result;
bfd_vma dot = 0;
result = exp_fold_tree_1 (tree->assign.src,
current_section,
lang_allocating_phase_enum,
dot, &dot, TRUE);
if (result.valid_p)
{
bfd_boolean create;
struct bfd_link_hash_entry *h;
if (tree->type.node_class == etree_assign)
create = TRUE;
else
create = FALSE;
h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
create, FALSE, TRUE);
if (h == NULL)
{
if (create)
einfo (_("%P%F:%s: hash creation failed\n"),
tree->assign.dst);
}
else if (tree->type.node_class == etree_provide
&& h->type != bfd_link_hash_new
&& h->type != bfd_link_hash_undefined
&& h->type != bfd_link_hash_common)
{
/* Do nothing. The symbol was defined by some
object. */
}
else
{
/* FIXME: Should we worry if the symbol is already
defined? */
lang_update_definedness (tree->assign.dst, h);
h->type = bfd_link_hash_defined;
h->u.def.value = result.value;
h->u.def.section = result.section->bfd_section;
if (tree->type.node_class == etree_provide)
tree->type.node_class = etree_provided;
}
}
}
break;
case etree_name:
fold_name (tree, current_section, lang_allocating_phase_enum, 0,
TRUE);
break;
default:
abort ();
break;
}
}