elfcpp/
[deliverable/binutils-gdb.git] / ld / ldexp.c
index 59743ea1ec9d2fbd30070b27da6919c576de5e05..cc43b7225c4446ab364c9b2ac1e265d4b0783da9 100644 (file)
@@ -213,10 +213,14 @@ new_rel (bfd_vma value, asection *section)
 static void
 new_rel_from_abs (bfd_vma value)
 {
+  asection *s = expld.section;
+
+  if (s == bfd_abs_section_ptr && expld.phase == lang_final_phase_enum)
+    s = section_for_dot ();
   expld.result.valid_p = TRUE;
-  expld.result.value = value - expld.section->vma;
+  expld.result.value = value - s->vma;
   expld.result.str = NULL;
-  expld.result.section = expld.section;
+  expld.result.section = s;
 }
 
 static void
@@ -606,7 +610,8 @@ fold_name (etree_type *tree)
                         output_section);
            }
          else if (expld.phase == lang_final_phase_enum
-                  || expld.assigning_to_dot)
+                  || (expld.phase != lang_mark_phase_enum
+                      && expld.assigning_to_dot))
            einfo (_("%F%S: undefined symbol `%s'"
                     " referenced in expression\n"),
                   tree, tree->name.name);
@@ -680,7 +685,7 @@ fold_name (etree_type *tree)
                       tree, tree->name.name);
              new_number (0);
            }
-         else if (os->processed_vma)
+         else if (os->bfd_section != NULL)
            {
              bfd_vma val;
 
@@ -692,6 +697,8 @@ fold_name (etree_type *tree)
              
              new_number (val);
            }
+         else
+           new_number (0);
        }
       break;
 
@@ -797,14 +804,7 @@ exp_fold_tree_1 (etree_type *tree)
          if (tree->type.node_class != etree_assign)
            einfo (_("%F%S can not PROVIDE assignment to"
                     " location counter\n"), tree);
-         /* After allocation, assignment to dot should not be done inside
-            an output section since allocation adds a padding statement
-            that effectively duplicates the assignment.  */
-         if (expld.phase == lang_mark_phase_enum
-             || expld.phase == lang_allocating_phase_enum
-             || ((expld.phase == lang_assigning_phase_enum
-                  || expld.phase == lang_final_phase_enum)
-                 && expld.section == bfd_abs_section_ptr))
+         if (expld.phase != lang_first_phase_enum)
            {
              /* Notify the folder that this is an assignment to dot.  */
              expld.assigning_to_dot = TRUE;
@@ -819,8 +819,14 @@ exp_fold_tree_1 (etree_type *tree)
                }
              else if (expld.dotp == NULL)
                einfo (_("%F%S assignment to location counter"
-                        " invalid outside of SECTION\n"), tree);
-             else
+                        " invalid outside of SECTIONS\n"), tree);
+
+             /* After allocation, assignment to dot should not be
+                done inside an output section since allocation adds a
+                padding statement that effectively duplicates the
+                assignment.  */
+             else if (expld.phase <= lang_allocating_phase_enum
+                      || expld.section == bfd_abs_section_ptr)
                {
                  bfd_vma nextdot;
 
@@ -886,7 +892,7 @@ exp_fold_tree_1 (etree_type *tree)
          if (expld.result.valid_p
              || (expld.phase <= lang_mark_phase_enum
                  && tree->type.node_class == etree_assign
-                 && tree->assign.hidden))
+                 && tree->assign.defsym))
            {
              if (h == NULL)
                {
@@ -1048,6 +1054,7 @@ static etree_type *
 exp_assop (const char *dst,
           etree_type *src,
           enum node_tree_enum class,
+          bfd_boolean defsym,
           bfd_boolean hidden)
 {
   etree_type *n;
@@ -1059,20 +1066,25 @@ exp_assop (const char *dst,
   n->assign.type.node_class = class;
   n->assign.src = src;
   n->assign.dst = dst;
+  n->assign.defsym = defsym;
   n->assign.hidden = hidden;
   return n;
 }
 
+/* Handle linker script assignments and HIDDEN.  */
+
 etree_type *
-exp_assign (const char *dst, etree_type *src)
+exp_assign (const char *dst, etree_type *src, bfd_boolean hidden)
 {
-  return exp_assop (dst, src, etree_assign, FALSE);
+  return exp_assop (dst, src, etree_assign, FALSE, hidden);
 }
 
+/* Handle --defsym command-line option.  */
+
 etree_type *
 exp_defsym (const char *dst, etree_type *src)
 {
-  return exp_assop (dst, src, etree_assign, TRUE);
+  return exp_assop (dst, src, etree_assign, TRUE, FALSE);
 }
 
 /* Handle PROVIDE.  */
@@ -1080,7 +1092,7 @@ exp_defsym (const char *dst, etree_type *src)
 etree_type *
 exp_provide (const char *dst, etree_type *src, bfd_boolean hidden)
 {
-  return exp_assop (dst, src, etree_provide, hidden);
+  return exp_assop (dst, src, etree_provide, FALSE, hidden);
 }
 
 /* Handle ASSERT.  */
This page took 0.024449 seconds and 4 git commands to generate.