aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2004-02-23 10:11:47 +0000
committerNathan Sidwell <nathan@codesourcery.com>2004-02-23 10:11:47 +0000
commitc1823dd9e47d7dec2a4be7a46a3237bba81380a1 (patch)
treea3fd823c0f1fd5024697a9a3cf2c8a5b4d400ad7
parent8e7b2cf4286e07d4a8a21e1fa33fc212ddf3f15e (diff)
downloadgdb-c1823dd9e47d7dec2a4be7a46a3237bba81380a1.zip
gdb-c1823dd9e47d7dec2a4be7a46a3237bba81380a1.tar.gz
gdb-c1823dd9e47d7dec2a4be7a46a3237bba81380a1.tar.bz2
* 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.
-rw-r--r--ld/ChangeLog17
-rw-r--r--ld/ldexp.c89
-rw-r--r--ld/ldlang.c15
-rw-r--r--ld/ldlang.h2
-rw-r--r--ld/testsuite/ChangeLog5
5 files changed, 67 insertions, 61 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 12716fb..391292e 100644
--- a/ld/ChangeLog
+++ b/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.
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)
{
diff --git a/ld/ldlang.c b/ld/ldlang.c
index a25f5f3..0f5c630 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 867eb14..d518398 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 b103d5b..7d6344c 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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-20 Nathan Sidwell <nathan@codesourcery.com>
* ld-scripts/align.{s,t,exp}: New.