* 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:
parent
33ed461333
commit
1b49374200
15 changed files with 153 additions and 61 deletions
17
ld/ChangeLog
17
ld/ChangeLog
|
@ -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.
|
||||
|
|
89
ld/ldexp.c
89
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)
|
||||
{
|
||||
|
|
15
ld/ldlang.c
15
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);
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
8
ld/testsuite/ld-scripts/provide-1.d
Normal file
8
ld/testsuite/ld-scripts/provide-1.d
Normal 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 ............
|
3
ld/testsuite/ld-scripts/provide-1.s
Normal file
3
ld/testsuite/ld-scripts/provide-1.s
Normal file
|
@ -0,0 +1,3 @@
|
|||
.data
|
||||
.globl foo
|
||||
foo: .long 0
|
11
ld/testsuite/ld-scripts/provide-1.t
Normal file
11
ld/testsuite/ld-scripts/provide-1.t
Normal file
|
@ -0,0 +1,11 @@
|
|||
SECTIONS
|
||||
{
|
||||
.data :
|
||||
{
|
||||
LONG (foo)
|
||||
LONG (bar)
|
||||
*(.data)
|
||||
}
|
||||
PROVIDE (foo = .);
|
||||
PROVIDE (bar = .);
|
||||
}
|
6
ld/testsuite/ld-scripts/provide-2.d
Normal file
6
ld/testsuite/ld-scripts/provide-2.d
Normal file
|
@ -0,0 +1,6 @@
|
|||
#source: provide-2.s
|
||||
#ld: -T provide-2.t
|
||||
#nm: -B
|
||||
0+3 A baz
|
||||
0+0 D foo
|
||||
|
6
ld/testsuite/ld-scripts/provide-2.s
Normal file
6
ld/testsuite/ld-scripts/provide-2.s
Normal file
|
@ -0,0 +1,6 @@
|
|||
.data
|
||||
.globl foo
|
||||
foo: .long 0
|
||||
|
||||
.globl baz
|
||||
.long baz
|
10
ld/testsuite/ld-scripts/provide-2.t
Normal file
10
ld/testsuite/ld-scripts/provide-2.t
Normal file
|
@ -0,0 +1,10 @@
|
|||
SECTIONS
|
||||
{
|
||||
PROVIDE (foo = 1);
|
||||
PROVIDE (bar = 2);
|
||||
PROVIDE (baz = 3);
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
}
|
3
ld/testsuite/ld-scripts/provide-3.d
Normal file
3
ld/testsuite/ld-scripts/provide-3.d
Normal file
|
@ -0,0 +1,3 @@
|
|||
#source: provide-2.s
|
||||
#ld: -T provide-2.t
|
||||
#error: symbol defined in linker script and object file
|
3
ld/testsuite/ld-scripts/provide-3.s
Normal file
3
ld/testsuite/ld-scripts/provide-3.s
Normal file
|
@ -0,0 +1,3 @@
|
|||
.data
|
||||
.globl foo
|
||||
foo: .long 0
|
11
ld/testsuite/ld-scripts/provide-3.t
Normal file
11
ld/testsuite/ld-scripts/provide-3.t
Normal file
|
@ -0,0 +1,11 @@
|
|||
SECTIONS
|
||||
{
|
||||
.data :
|
||||
{
|
||||
LONG (foo)
|
||||
LONG (bar)
|
||||
*(.data)
|
||||
}
|
||||
foo = .;
|
||||
bar = .;
|
||||
}
|
25
ld/testsuite/ld-scripts/provide.exp
Normal file
25
ld/testsuite/ld-scripts/provide.exp
Normal 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
|
Loading…
Reference in a new issue