* 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.
This commit is contained in:
Nathan Sidwell
2004-02-23 10:10:02 +00:00
parent 33ed461333
commit 1b49374200
15 changed files with 153 additions and 61 deletions

View File

@ -1,3 +1,20 @@
2004-02-23 Nathan Sidwell <nathan@codesourcery.com>
* 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 <amodra@bigpond.net.au>
* ldexp.c (fold_tree): Follow indirect symbols.
2004-02-20 Nathan Sidwell <nathan@codesourcery.com> 2004-02-20 Nathan Sidwell <nathan@codesourcery.com>
* ldgram.y (exp): Add two operand ALIGN. * ldgram.y (exp): Add two operand ALIGN.

View File

@ -141,17 +141,6 @@ new_abs (bfd_vma value)
return new; 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 * etree_type *
exp_intop (bfd_vma value) exp_intop (bfd_vma value)
{ {
@ -460,14 +449,6 @@ fold_trinary (etree_type *tree,
return result; return result;
} }
etree_value_type
invalid (void)
{
etree_value_type new;
new.valid_p = FALSE;
return new;
}
static etree_value_type static etree_value_type
fold_name (etree_type *tree, fold_name (etree_type *tree,
lang_output_section_statement_type *current_section, lang_output_section_statement_type *current_section,
@ -476,25 +457,18 @@ fold_name (etree_type *tree,
{ {
etree_value_type result; etree_value_type result;
result.valid_p = FALSE;
switch (tree->type.node_code) switch (tree->type.node_code)
{ {
case SIZEOF_HEADERS: case SIZEOF_HEADERS:
if (allocation_done != lang_first_phase_enum) if (allocation_done != lang_first_phase_enum)
{ result = new_abs (bfd_sizeof_headers (output_bfd,
result = new_abs (bfd_sizeof_headers (output_bfd, link_info.relocatable));
link_info.relocatable));
}
else
{
result.valid_p = FALSE;
}
break; break;
case DEFINED: case DEFINED:
if (allocation_done == lang_first_phase_enum) if (allocation_done == lang_first_phase_enum)
{ lang_track_definedness (tree->name.name);
lang_track_definedness (tree->name.name);
result.valid_p = FALSE;
}
else else
{ {
struct bfd_link_hash_entry *h; struct bfd_link_hash_entry *h;
@ -515,13 +489,10 @@ fold_name (etree_type *tree,
} }
break; break;
case NAME: case NAME:
result.valid_p = FALSE;
if (tree->name.name[0] == '.' && tree->name.name[1] == 0) if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
{ {
if (allocation_done != lang_first_phase_enum) if (allocation_done != lang_first_phase_enum)
result = new_rel_from_section (dot, current_section); result = new_rel_from_section (dot, current_section);
else
result = invalid ();
} }
else if (allocation_done != lang_first_phase_enum) 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, h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
tree->name.name, tree->name.name,
FALSE, FALSE, TRUE); TRUE, FALSE, TRUE);
if (h != NULL if (!h)
&& (h->type == bfd_link_hash_defined einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
|| h->type == bfd_link_hash_defweak)) else if (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak)
{ {
if (bfd_is_abs_section (h->u.def.section)) if (bfd_is_abs_section (h->u.def.section))
result = new_abs (h->u.def.value); result = new_abs (h->u.def.value);
@ -565,6 +537,12 @@ fold_name (etree_type *tree,
else if (allocation_done == lang_final_phase_enum) else if (allocation_done == lang_final_phase_enum)
einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"), einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
tree->name.name); 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; break;
@ -574,11 +552,9 @@ fold_name (etree_type *tree,
lang_output_section_statement_type *os; lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name); os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "ADDR"); if (os && os->processed > 0)
result = new_rel (0, NULL, os); result = new_rel (0, NULL, os);
} }
else
result = invalid ();
break; break;
case LOADADDR: case LOADADDR:
@ -587,16 +563,16 @@ fold_name (etree_type *tree,
lang_output_section_statement_type *os; lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name); os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "LOADADDR"); if (os && os->processed != 0)
if (os->load_base == NULL) {
result = new_rel (0, NULL, os); if (os->load_base == NULL)
else result = new_rel (0, NULL, os);
result = exp_fold_tree_no_dot (os->load_base, else
abs_output_section, result = exp_fold_tree_no_dot (os->load_base,
allocation_done); abs_output_section,
allocation_done);
}
} }
else
result = invalid ();
break; break;
case SIZEOF: case SIZEOF:
@ -606,11 +582,9 @@ fold_name (etree_type *tree,
lang_output_section_statement_type *os; lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name); os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "SIZEOF"); if (os && os->processed > 0)
result = new_abs (os->bfd_section->_raw_size / opb); result = new_abs (os->bfd_section->_raw_size / opb);
} }
else
result = invalid ();
break; break;
default: default:
@ -733,14 +707,15 @@ exp_fold_tree (etree_type *tree,
else else
create = FALSE; create = FALSE;
h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
create, FALSE, FALSE); create, FALSE, TRUE);
if (h == NULL) if (h == NULL)
{ {
if (tree->type.node_class == etree_assign) if (create)
einfo (_("%P%F:%s: hash creation failed\n"), einfo (_("%P%F:%s: hash creation failed\n"),
tree->assign.dst); tree->assign.dst);
} }
else if (tree->type.node_class == etree_provide 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_undefined
&& h->type != bfd_link_hash_common) && h->type != bfd_link_hash_common)
{ {

View File

@ -622,7 +622,7 @@ lang_output_section_statement_lookup (const char *const name)
lookup->next = NULL; lookup->next = NULL;
lookup->bfd_section = NULL; lookup->bfd_section = NULL;
lookup->processed = FALSE; lookup->processed = 0;
lookup->sectype = normal_section; lookup->sectype = normal_section;
lookup->addr_tree = NULL; lookup->addr_tree = NULL;
lang_list_init (&lookup->children); lang_list_init (&lookup->children);
@ -2984,12 +2984,15 @@ lang_size_sections_1
{ {
etree_value_type r; etree_value_type r;
os->processed = -1;
r = exp_fold_tree (os->addr_tree, r = exp_fold_tree (os->addr_tree,
abs_output_section, abs_output_section,
lang_allocating_phase_enum, lang_allocating_phase_enum,
dot, &dot); dot, &dot);
os->processed = 0;
if (!r.valid_p) 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); os->name);
dot = r.value + r.section->bfd_section->vma; dot = r.value + r.section->bfd_section->vma;
@ -3027,7 +3030,7 @@ lang_size_sections_1
= TO_SIZE (after - os->bfd_section->vma); = TO_SIZE (after - os->bfd_section->vma);
dot = os->bfd_section->vma + TO_ADDR (os->bfd_section->_raw_size); dot = os->bfd_section->vma + TO_ADDR (os->bfd_section->_raw_size);
os->processed = TRUE; os->processed = 1;
if (os->update_dot_tree != 0) if (os->update_dot_tree != 0)
exp_fold_tree (os->update_dot_tree, abs_output_section, exp_fold_tree (os->update_dot_tree, abs_output_section,
@ -3089,6 +3092,11 @@ lang_size_sections_1
s->data_statement.output_section = s->data_statement.output_section =
output_section_statement->bfd_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) switch (s->data_statement.type)
{ {
default: default:
@ -3294,6 +3302,7 @@ lang_size_sections
&& first + last <= exp_data_seg.pagesize) && first + last <= exp_data_seg.pagesize)
{ {
exp_data_seg.phase = exp_dataseg_adjust; exp_data_seg.phase = exp_dataseg_adjust;
lang_statement_iteration++;
result = lang_size_sections_1 (s, output_section_statement, prev, result = lang_size_sections_1 (s, output_section_statement, prev,
fill, dot, relax, check_regions); fill, dot, relax, check_regions);
} }

View File

@ -134,7 +134,7 @@ typedef struct lang_output_section_statement_struct
union lang_statement_union *next; union lang_statement_union *next;
const char *name; const char *name;
bfd_boolean processed; int processed;
asection *bfd_section; asection *bfd_section;
flagword flags; /* Or together of all input sections. */ flagword flags; /* Or together of all input sections. */

View File

@ -1,3 +1,8 @@
2004-02-23 Nathan Sidwell <nathan@codesourcery.com>
* ld-scripts/provide.exp: New.
* ld-scripts/provide-{1,2,3}.{s,t,d}.exp: New.
2004-02-23 Alan Modra <amodra@bigpond.net.au> 2004-02-23 Alan Modra <amodra@bigpond.net.au>
* ld-scripts/data.t: Set ".other" address so location doesn't * ld-scripts/data.t: Set ".other" address so location doesn't

View File

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

View File

@ -0,0 +1,3 @@
.data
.globl foo
foo: .long 0

View File

@ -0,0 +1,11 @@
SECTIONS
{
.data :
{
LONG (foo)
LONG (bar)
*(.data)
}
PROVIDE (foo = .);
PROVIDE (bar = .);
}

View File

@ -0,0 +1,6 @@
#source: provide-2.s
#ld: -T provide-2.t
#nm: -B
0+3 A baz
0+0 D foo

View File

@ -0,0 +1,6 @@
.data
.globl foo
foo: .long 0
.globl baz
.long baz

View File

@ -0,0 +1,10 @@
SECTIONS
{
PROVIDE (foo = 1);
PROVIDE (bar = 2);
PROVIDE (baz = 3);
.data :
{
*(.data)
}
}

View File

@ -0,0 +1,3 @@
#source: provide-2.s
#ld: -T provide-2.t
#error: symbol defined in linker script and object file

View File

@ -0,0 +1,3 @@
.data
.globl foo
foo: .long 0

View File

@ -0,0 +1,11 @@
SECTIONS
{
.data :
{
LONG (foo)
LONG (bar)
*(.data)
}
foo = .;
bar = .;
}

View File

@ -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