* ldlang.h (struct lang_output_section_state): Change processed
authorNathan Sidwell <nathan@codesourcery.com>
Mon, 23 Feb 2004 10:10:02 +0000 (10:10 +0000)
committerNathan Sidwell <nathan@codesourcery.com>
Mon, 23 Feb 2004 10:10:02 +0000 (10:10 +0000)
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.

15 files changed:
ld/ChangeLog
ld/ldexp.c
ld/ldlang.c
ld/ldlang.h
ld/testsuite/ChangeLog
ld/testsuite/ld-scripts/provide-1.d [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-1.s [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-1.t [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-2.d [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-2.s [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-2.t [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-3.d [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-3.s [new file with mode: 0644]
ld/testsuite/ld-scripts/provide-3.t [new file with mode: 0644]
ld/testsuite/ld-scripts/provide.exp [new file with mode: 0644]

index 12716fba5f5bedd7dd2b673275e9b827e3b970b4..391292ee5d368885155193e770e154b968b89e6e 100644 (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.
index 23a23924fecd6a44bfd8e64470f5e0eabc383d26..4d9a8575fb736b08625481740fab0159579a0f97 100644 (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)
                {
index a25f5f300a4578cf20700dd684205ab29c0bfeba..0f5c63032338c1372258baad12ddaeef1dd9f2e1 100644 (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);
        }
index 867eb14236799cbc4298c8c648e06a854628612a..d518398b27f5f95546998df18d9bfb3228634cd0 100644 (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.  */
index 2bb75100c9152098976694f280999dd2ca4097b2..9622064497987a6525ab969ed828d2f93852aaed 100644 (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
diff --git a/ld/testsuite/ld-scripts/provide-1.d b/ld/testsuite/ld-scripts/provide-1.d
new file mode 100644 (file)
index 0000000..bec3982
--- /dev/null
@@ -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 (file)
index 0000000..6395f3a
--- /dev/null
@@ -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 (file)
index 0000000..dd30956
--- /dev/null
@@ -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 (file)
index 0000000..3b59e32
--- /dev/null
@@ -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 (file)
index 0000000..6fa93e4
--- /dev/null
@@ -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 (file)
index 0000000..f128d5e
--- /dev/null
@@ -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 (file)
index 0000000..1ee38e3
--- /dev/null
@@ -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 (file)
index 0000000..6395f3a
--- /dev/null
@@ -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 (file)
index 0000000..f6229d4
--- /dev/null
@@ -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 (file)
index 0000000..0092674
--- /dev/null
@@ -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