From 1b493742004fd74ebe85a9f93bf28aebe8e858c8 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 23 Feb 2004 10:10:02 +0000 Subject: [PATCH] * 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/ChangeLog | 17 ++++++ ld/ldexp.c | 89 +++++++++++------------------ ld/ldlang.c | 15 ++++- ld/ldlang.h | 2 +- ld/testsuite/ChangeLog | 5 ++ ld/testsuite/ld-scripts/provide-1.d | 8 +++ ld/testsuite/ld-scripts/provide-1.s | 3 + ld/testsuite/ld-scripts/provide-1.t | 11 ++++ ld/testsuite/ld-scripts/provide-2.d | 6 ++ ld/testsuite/ld-scripts/provide-2.s | 6 ++ ld/testsuite/ld-scripts/provide-2.t | 10 ++++ ld/testsuite/ld-scripts/provide-3.d | 3 + ld/testsuite/ld-scripts/provide-3.s | 3 + ld/testsuite/ld-scripts/provide-3.t | 11 ++++ ld/testsuite/ld-scripts/provide.exp | 25 ++++++++ 15 files changed, 153 insertions(+), 61 deletions(-) create mode 100644 ld/testsuite/ld-scripts/provide-1.d create mode 100644 ld/testsuite/ld-scripts/provide-1.s create mode 100644 ld/testsuite/ld-scripts/provide-1.t create mode 100644 ld/testsuite/ld-scripts/provide-2.d create mode 100644 ld/testsuite/ld-scripts/provide-2.s create mode 100644 ld/testsuite/ld-scripts/provide-2.t create mode 100644 ld/testsuite/ld-scripts/provide-3.d create mode 100644 ld/testsuite/ld-scripts/provide-3.s create mode 100644 ld/testsuite/ld-scripts/provide-3.t create mode 100644 ld/testsuite/ld-scripts/provide.exp diff --git a/ld/ChangeLog b/ld/ChangeLog index 12716fba5f5..391292ee5d3 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,20 @@ +2004-02-23 Nathan Sidwell + + * 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. + +2004-02-23 Alan Modra + + * ldexp.c (fold_tree): Follow indirect symbols. + 2004-02-20 Nathan Sidwell * ldgram.y (exp): Add two operand ALIGN. diff --git a/ld/ldexp.c b/ld/ldexp.c index 23a23924fec..4d9a8575fb7 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) { diff --git a/ld/ldlang.c b/ld/ldlang.c index a25f5f300a4..0f5c6303233 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -622,7 +622,7 @@ lang_output_section_statement_lookup (const char *const name) lookup->next = NULL; lookup->bfd_section = NULL; - lookup->processed = FALSE; + lookup->processed = 0; lookup->sectype = normal_section; lookup->addr_tree = NULL; lang_list_init (&lookup->children); @@ -2984,12 +2984,15 @@ lang_size_sections_1 { etree_value_type r; + os->processed = -1; r = exp_fold_tree (os->addr_tree, abs_output_section, lang_allocating_phase_enum, dot, &dot); + os->processed = 0; + if (!r.valid_p) - einfo (_("%F%S: non constant address expression for section %s\n"), + einfo (_("%F%S: non constant or forward reference address expression for section %s\n"), os->name); dot = r.value + r.section->bfd_section->vma; @@ -3027,7 +3030,7 @@ lang_size_sections_1 = TO_SIZE (after - os->bfd_section->vma); dot = os->bfd_section->vma + TO_ADDR (os->bfd_section->_raw_size); - os->processed = TRUE; + os->processed = 1; if (os->update_dot_tree != 0) exp_fold_tree (os->update_dot_tree, abs_output_section, @@ -3089,6 +3092,11 @@ lang_size_sections_1 s->data_statement.output_section = output_section_statement->bfd_section; + /* We might refer to provided symbols in the expression, and + need to mark them as needed. */ + exp_fold_tree (s->data_statement.exp, abs_output_section, + lang_allocating_phase_enum, dot, &dot); + switch (s->data_statement.type) { default: @@ -3294,6 +3302,7 @@ lang_size_sections && first + last <= exp_data_seg.pagesize) { exp_data_seg.phase = exp_dataseg_adjust; + lang_statement_iteration++; result = lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax, check_regions); } diff --git a/ld/ldlang.h b/ld/ldlang.h index 867eb142367..d518398b27f 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -134,7 +134,7 @@ typedef struct lang_output_section_statement_struct union lang_statement_union *next; const char *name; - bfd_boolean processed; + int processed; asection *bfd_section; flagword flags; /* Or together of all input sections. */ diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 2bb75100c91..96220644979 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-02-23 Nathan Sidwell + + * ld-scripts/provide.exp: New. + * ld-scripts/provide-{1,2,3}.{s,t,d}.exp: New. + 2004-02-23 Alan Modra * ld-scripts/data.t: Set ".other" address so location doesn't diff --git a/ld/testsuite/ld-scripts/provide-1.d b/ld/testsuite/ld-scripts/provide-1.d new file mode 100644 index 00000000000..bec398237b5 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-1.d @@ -0,0 +1,8 @@ +#source: provide-1.s +#ld: -T provide-1.t +#objdump: -s -j .data + +.*: file format .* + +Contents of section .data: + 0000 (08)?000000(08)? (0c)?000000(0c)? 00000000 ............ diff --git a/ld/testsuite/ld-scripts/provide-1.s b/ld/testsuite/ld-scripts/provide-1.s new file mode 100644 index 00000000000..6395f3a39b8 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-1.s @@ -0,0 +1,3 @@ + .data + .globl foo +foo: .long 0 diff --git a/ld/testsuite/ld-scripts/provide-1.t b/ld/testsuite/ld-scripts/provide-1.t new file mode 100644 index 00000000000..dd309560d81 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-1.t @@ -0,0 +1,11 @@ +SECTIONS +{ + .data : + { + LONG (foo) + LONG (bar) + *(.data) + } + PROVIDE (foo = .); + PROVIDE (bar = .); +} diff --git a/ld/testsuite/ld-scripts/provide-2.d b/ld/testsuite/ld-scripts/provide-2.d new file mode 100644 index 00000000000..3b59e326291 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-2.d @@ -0,0 +1,6 @@ +#source: provide-2.s +#ld: -T provide-2.t +#nm: -B +0+3 A baz +0+0 D foo + diff --git a/ld/testsuite/ld-scripts/provide-2.s b/ld/testsuite/ld-scripts/provide-2.s new file mode 100644 index 00000000000..6fa93e44ed2 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-2.s @@ -0,0 +1,6 @@ + .data + .globl foo +foo: .long 0 + + .globl baz + .long baz diff --git a/ld/testsuite/ld-scripts/provide-2.t b/ld/testsuite/ld-scripts/provide-2.t new file mode 100644 index 00000000000..f128d5e12f8 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-2.t @@ -0,0 +1,10 @@ +SECTIONS +{ + PROVIDE (foo = 1); + PROVIDE (bar = 2); + PROVIDE (baz = 3); + .data : + { + *(.data) + } +} diff --git a/ld/testsuite/ld-scripts/provide-3.d b/ld/testsuite/ld-scripts/provide-3.d new file mode 100644 index 00000000000..1ee38e3ace0 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-3.d @@ -0,0 +1,3 @@ +#source: provide-2.s +#ld: -T provide-2.t +#error: symbol defined in linker script and object file diff --git a/ld/testsuite/ld-scripts/provide-3.s b/ld/testsuite/ld-scripts/provide-3.s new file mode 100644 index 00000000000..6395f3a39b8 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-3.s @@ -0,0 +1,3 @@ + .data + .globl foo +foo: .long 0 diff --git a/ld/testsuite/ld-scripts/provide-3.t b/ld/testsuite/ld-scripts/provide-3.t new file mode 100644 index 00000000000..f6229d4bc0c --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-3.t @@ -0,0 +1,11 @@ +SECTIONS +{ + .data : + { + LONG (foo) + LONG (bar) + *(.data) + } + foo = .; + bar = .; +} diff --git a/ld/testsuite/ld-scripts/provide.exp b/ld/testsuite/ld-scripts/provide.exp new file mode 100644 index 00000000000..00926742900 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide.exp @@ -0,0 +1,25 @@ +# Test PROVIDE in a linker script. +# By Nathan Sidwell, CodeSourcery LLC +# Copyright 2004 +# Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set testname "provide" + +run_dump_test provide-1 +run_dump_test provide-2 +setup_xfail *-*-* +run_dump_test provide-3 -- 2.30.2