* 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>
* ldgram.y (exp): Add two operand ALIGN.

View file

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

View file

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

View file

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

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