From 1b493742004fd74ebe85a9f93bf28aebe8e858c8 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 23 Feb 2004 10:10:02 +0000 Subject: * ldlang.h (struct lang_output_section_state): Change processed field's type. * ldexp.c (check, invalid): Remove. (fold_name): Move valid_p assignments. Create undefined symbol when needed. Directly exampine section's processd flag. * ldlang.c (lang_output_section_statement_lookup): Adjust processed field init. (lang_size_sections_1): Allow LOADADDR when determining section's VMA. Adjust error message. Fold data statement's expr. (lang_size_sections): Correctly increment lang_statement_iteration. * ld-scripts/provide.exp: New. * ld-scripts/provide-{1,2,3}.{s,t,d}.exp: New. * ldexp.c (fold_tree): Follow indirect symbols. --- ld/ldexp.c | 89 ++++++++++++++++++++++---------------------------------------- 1 file changed, 32 insertions(+), 57 deletions(-) (limited to 'ld/ldexp.c') diff --git a/ld/ldexp.c b/ld/ldexp.c index 23a2392..4d9a857 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -141,17 +141,6 @@ new_abs (bfd_vma value) return new; } -static void -check (lang_output_section_statement_type *os, - const char *name, - const char *op) -{ - if (os == NULL) - einfo (_("%F%P: %s uses undefined section %s\n"), op, name); - if (! os->processed) - einfo (_("%F%P: %s forward reference of section %s\n"), op, name); -} - etree_type * exp_intop (bfd_vma value) { @@ -460,14 +449,6 @@ fold_trinary (etree_type *tree, return result; } -etree_value_type -invalid (void) -{ - etree_value_type new; - new.valid_p = FALSE; - return new; -} - static etree_value_type fold_name (etree_type *tree, lang_output_section_statement_type *current_section, @@ -476,25 +457,18 @@ fold_name (etree_type *tree, { etree_value_type result; + result.valid_p = FALSE; + switch (tree->type.node_code) { case SIZEOF_HEADERS: if (allocation_done != lang_first_phase_enum) - { - result = new_abs (bfd_sizeof_headers (output_bfd, - link_info.relocatable)); - } - else - { - result.valid_p = FALSE; - } + result = new_abs (bfd_sizeof_headers (output_bfd, + link_info.relocatable)); break; case DEFINED: if (allocation_done == lang_first_phase_enum) - { - lang_track_definedness (tree->name.name); - result.valid_p = FALSE; - } + lang_track_definedness (tree->name.name); else { struct bfd_link_hash_entry *h; @@ -515,13 +489,10 @@ fold_name (etree_type *tree, } break; case NAME: - result.valid_p = FALSE; if (tree->name.name[0] == '.' && tree->name.name[1] == 0) { if (allocation_done != lang_first_phase_enum) result = new_rel_from_section (dot, current_section); - else - result = invalid (); } else if (allocation_done != lang_first_phase_enum) { @@ -529,10 +500,11 @@ fold_name (etree_type *tree, h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info, tree->name.name, - FALSE, FALSE, TRUE); - if (h != NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak)) + TRUE, FALSE, TRUE); + if (!h) + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + else if (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak) { if (bfd_is_abs_section (h->u.def.section)) result = new_abs (h->u.def.value); @@ -565,6 +537,12 @@ fold_name (etree_type *tree, else if (allocation_done == lang_final_phase_enum) einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"), tree->name.name); + else if (h->type == bfd_link_hash_new) + { + h->type = bfd_link_hash_undefined; + h->u.undef.abfd = NULL; + bfd_link_add_undef (link_info.hash, h); + } } break; @@ -574,11 +552,9 @@ fold_name (etree_type *tree, lang_output_section_statement_type *os; os = lang_output_section_find (tree->name.name); - check (os, tree->name.name, "ADDR"); - result = new_rel (0, NULL, os); + if (os && os->processed > 0) + result = new_rel (0, NULL, os); } - else - result = invalid (); break; case LOADADDR: @@ -587,16 +563,16 @@ fold_name (etree_type *tree, lang_output_section_statement_type *os; os = lang_output_section_find (tree->name.name); - check (os, tree->name.name, "LOADADDR"); - 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); + if (os && 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); + } } - else - result = invalid (); break; case SIZEOF: @@ -606,11 +582,9 @@ fold_name (etree_type *tree, lang_output_section_statement_type *os; os = lang_output_section_find (tree->name.name); - check (os, tree->name.name, "SIZEOF"); - result = new_abs (os->bfd_section->_raw_size / opb); + if (os && os->processed > 0) + result = new_abs (os->bfd_section->_raw_size / opb); } - else - result = invalid (); break; default: @@ -733,14 +707,15 @@ exp_fold_tree (etree_type *tree, else create = FALSE; h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, - create, FALSE, FALSE); + create, FALSE, TRUE); if (h == NULL) { - if (tree->type.node_class == etree_assign) + 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) { -- cgit v1.1