2005-09-27 Paul Brook <paul@codesourcery.com>
[deliverable/binutils-gdb.git] / ld / ldlang.c
index ce178f18408f72e6138cffe3c03b472419e8cf29..dc5f4eec4a3a8e384b9e3a1ab9ba25348ae6eeb3 100644 (file)
@@ -1010,6 +1010,7 @@ static lang_output_section_statement_type *
 lang_output_section_statement_lookup_1 (const char *const name, int constraint)
 {
   lang_output_section_statement_type *lookup;
+  lang_output_section_statement_type **nextp;
 
   lookup = lang_output_section_find_1 (name, constraint);
   if (lookup == NULL)
@@ -1023,7 +1024,7 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint)
 
       lookup->next = NULL;
       lookup->bfd_section = NULL;
-      lookup->processed = 0;
+      lookup->processed = FALSE;
       lookup->constraint = constraint;
       lookup->ignored = FALSE;
       lookup->sectype = normal_section;
@@ -1038,9 +1039,13 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint)
       lookup->update_dot_tree = NULL;
       lookup->phdrs = NULL;
 
+      /* GCC's strict aliasing rules prevent us from just casting the
+        address, so we store the pointer in a variable and cast that
+        instead.  */
+      nextp = &lookup->next;
       lang_statement_append (&lang_output_section_statement,
                             (lang_statement_union_type *) lookup,
-                            (lang_statement_union_type **) &lookup->next);
+                            (lang_statement_union_type **) nextp);
     }
   return lookup;
 }
@@ -1611,6 +1616,7 @@ exp_init_os (etree_type *exp)
   switch (exp->type.node_class)
     {
     case etree_assign:
+    case etree_provide:
       exp_init_os (exp->assign.src);
       break;
 
@@ -3049,11 +3055,8 @@ void
 strip_excluded_output_sections (void)
 {
   lang_output_section_statement_type *os;
-  unsigned int gc_sections;
 
-  /* Run lang_size_sections (if not already done) to ensure that all
-     symbols defined in the linker script are put in the bfd hash
-     table.  */
+  /* Run lang_size_sections (if not already done).  */
   if (expld.phase != lang_mark_phase_enum)
     {
       expld.phase = lang_mark_phase_enum;
@@ -3062,13 +3065,6 @@ strip_excluded_output_sections (void)
       lang_reset_memory_regions ();
     }
 
-  /* Now call into bfd_gc_sections to mark all sections defining global
-     symbols with SEC_KEEP.  */
-  gc_sections = link_info.gc_sections;
-  link_info.gc_sections = 0;
-  bfd_gc_sections (output_bfd, &link_info);
-  link_info.gc_sections = gc_sections;
-
   for (os = &lang_output_section_statement.head->output_section_statement;
        os != NULL;
        os = os->next)
@@ -3978,6 +3974,20 @@ lang_size_sections_1
            lang_output_section_statement_type *os;
 
            os = &s->output_section_statement;
+           if (os->addr_tree != NULL)
+             {
+               os->processed = FALSE;
+               exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot);
+
+               if (!expld.result.valid_p
+                   && expld.phase != lang_mark_phase_enum)
+                 einfo (_("%F%S: non constant or forward reference"
+                          " address expression for section %s\n"),
+                        os->name);
+
+               dot = expld.result.value + expld.result.section->vma;
+             }
+
            if (os->bfd_section == NULL)
              /* This section was removed or never actually created.  */
              break;
@@ -4007,6 +4017,7 @@ lang_size_sections_1
                break;
              }
 
+           newdot = dot;
            if (bfd_is_abs_section (os->bfd_section))
              {
                /* No matter what happens, an abs section starts at zero.  */
@@ -4078,22 +4089,6 @@ lang_size_sections_1
                                 os->name, (unsigned long) (newdot - savedot));
                      }
                  }
-               else
-                 {
-                   newdot = dot;
-                   os->processed = -1;
-                   exp_fold_tree (os->addr_tree, bfd_abs_section_ptr,
-                                  &newdot);
-                   os->processed = 0;
-
-                   if (!expld.result.valid_p
-                       && expld.phase != lang_mark_phase_enum)
-                     einfo (_("%F%S: non constant or forward reference"
-                              " address expression for section %s\n"),
-                            os->name);
-
-                   newdot = expld.result.value + expld.result.section->vma;
-                 }
 
                /* The section starts here.
                   First, align to what the section needs.  */
@@ -4109,7 +4104,7 @@ lang_size_sections_1
            lang_size_sections_1 (os->children.head, os, &os->children.head,
                                  os->fill, newdot, relax, check_regions);
 
-           os->processed = 1;
+           os->processed = TRUE;
 
            if (bfd_is_abs_section (os->bfd_section) || os->ignored)
              {
@@ -5167,7 +5162,7 @@ lang_reset_memory_regions (void)
   for (os = &lang_output_section_statement.head->output_section_statement;
        os != NULL;
        os = os->next)
-    os->processed = 0;
+    os->processed = FALSE;
 
   for (o = output_bfd->sections; o != NULL; o = o->next)
     {
This page took 0.025614 seconds and 4 git commands to generate.