Add linker relaxation support for the AVR
[deliverable/binutils-gdb.git] / ld / ldlang.c
index b82a7e55cf6de2502c4fd7c31baecc18d3bd7ace..f51f68ef4b09054443d600bb8018f596dd2efb97 100644 (file)
@@ -783,6 +783,7 @@ new_afile (const char *name,
   else
     {
       p = stat_alloc (sizeof (lang_input_statement_type));
+      p->header.type = lang_input_statement_enum;
       p->header.next = NULL;
     }
 
@@ -871,26 +872,62 @@ lang_add_input_file (const char *name,
 struct output_statement_hash_entry
 {
   struct bfd_hash_entry root;
-  lang_output_section_statement_type *entry;
+  lang_output_section_statement_type os;
 };
 
 /* The hash table.  */
 
 static struct bfd_hash_table output_statement_table;
 
-/* Support routines for the hash table used by lang_output_section_find_1,
+/* Support routines for the hash table used by lang_output_section_find,
    initialize the table, fill in an entry and remove the table.  */
 
 static struct bfd_hash_entry *
-output_statement_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED
+output_statement_newfunc (struct bfd_hash_entry *entry, 
                          struct bfd_hash_table *table,
-                         const char *string ATTRIBUTE_UNUSED)
+                         const char *string)
 {
-  struct output_statement_hash_entry *ret
-    = bfd_hash_allocate (table,
-                        sizeof (struct output_statement_hash_entry));
-  ret->entry = NULL;
-  return (struct bfd_hash_entry *) ret;
+  lang_output_section_statement_type **nextp;
+  struct output_statement_hash_entry *ret;
+
+  if (entry == NULL)
+    {
+      entry = bfd_hash_allocate (table, sizeof (*ret));
+      if (entry == NULL)
+       return entry;
+    }
+
+  entry = bfd_hash_newfunc (entry, table, string);
+  if (entry == NULL)
+    return entry;
+
+  ret = (struct output_statement_hash_entry *) entry;
+  memset (&ret->os, 0, sizeof (ret->os));
+  ret->os.header.type = lang_output_section_statement_enum;
+  ret->os.subsection_alignment = -1;
+  ret->os.section_alignment = -1;
+  ret->os.block_value = 1;
+  lang_list_init (&ret->os.children);
+  lang_statement_append (stat_ptr,
+                        (lang_statement_union_type *) &ret->os,
+                        &ret->os.header.next);
+
+  /* For every output section statement added to the list, except the
+     first one, lang_output_section_statement.tail points to the "next"
+     field of the last element of the list.  */
+  if (lang_output_section_statement.head != NULL)
+    ret->os.prev = (lang_output_section_statement_type *)
+      ((char *) lang_output_section_statement.tail
+       - offsetof (lang_output_section_statement_type, next));
+
+  /* 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 = &ret->os.next;
+  lang_statement_append (&lang_output_section_statement,
+                        (lang_statement_union_type *) &ret->os,
+                        (lang_statement_union_type **) nextp);
+  return &ret->root;
 }
 
 static void
@@ -898,7 +935,7 @@ output_statement_table_init (void)
 {
   if (! bfd_hash_table_init_n (&output_statement_table,
                               output_statement_newfunc, 61))
-    einfo (_("%P%F: Failed to create hash table\n"));
+    einfo (_("%P%F: can not create hash table: %E\n"));
 }
 
 static void
@@ -938,7 +975,7 @@ lang_init (void)
      looks like other code here.  */
   if (!bfd_hash_table_init_n (&lang_definedness_table,
                              lang_definedness_newfunc, 3))
-    einfo (_("%P%F: out of memory during initialization"));
+    einfo (_("%P%F: can not create hash table: %E\n"));
 }
 
 void
@@ -1028,96 +1065,79 @@ lang_memory_default (asection *section)
   return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE);
 }
 
-static lang_output_section_statement_type *
-lang_output_section_find_1 (const char *const name, int constraint)
+lang_output_section_statement_type *
+lang_output_section_find (const char *const name)
 {
-  lang_output_section_statement_type *lookup;
   struct output_statement_hash_entry *entry;
   unsigned long hash;
 
   entry = ((struct output_statement_hash_entry *)
-          bfd_hash_lookup (&output_statement_table, name, FALSE,
-                           FALSE));
-  if (entry == NULL || (lookup = entry->entry) == NULL)
+          bfd_hash_lookup (&output_statement_table, name, FALSE, FALSE));
+  if (entry == NULL)
     return NULL;
 
   hash = entry->root.hash;
   do
     {
-      if (lookup->constraint != -1
-         && (constraint == 0
-             || (constraint == lookup->constraint
-                 && constraint != SPECIAL)))
-       return lookup;
+      if (entry->os.constraint != -1)
+       return &entry->os;
       entry = (struct output_statement_hash_entry *) entry->root.next;
-      lookup = entry ? entry->entry : NULL;
     }
   while (entry != NULL
         && entry->root.hash == hash
-        && strcmp (name, lookup->name) == 0);
+        && strcmp (name, entry->os.name) == 0);
 
   return NULL;
 }
 
-lang_output_section_statement_type *
-lang_output_section_find (const char *const name)
-{
-  return lang_output_section_find_1 (name, 0);
-}
-
 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;
+  struct output_statement_hash_entry *entry;
+  struct output_statement_hash_entry *last_ent;
+  unsigned long hash;
 
-  lookup = lang_output_section_find_1 (name, constraint);
-  if (lookup == NULL)
-    {
-      struct output_statement_hash_entry *entry;
-
-      lookup = new_stat (lang_output_section_statement, stat_ptr);
-      lookup->region = NULL;
-      lookup->lma_region = NULL;
-      lookup->fill = 0;
-      lookup->block_value = 1;
-      lookup->name = name;
-
-      lookup->next = NULL;
-      lookup->bfd_section = NULL;
-      lookup->processed = FALSE;
-      lookup->constraint = constraint;
-      lookup->ignored = FALSE;
-      lookup->sectype = normal_section;
-      lookup->addr_tree = NULL;
-      lang_list_init (&lookup->children);
-
-      lookup->memspec = NULL;
-      lookup->flags = 0;
-      lookup->subsection_alignment = -1;
-      lookup->section_alignment = -1;
-      lookup->load_base = NULL;
-      lookup->update_dot_tree = NULL;
-      lookup->phdrs = NULL;
+  entry = ((struct output_statement_hash_entry *)
+          bfd_hash_lookup (&output_statement_table, name, TRUE, FALSE));
+  if (entry == NULL)
+    {
+      einfo (_("%P%F: failed creating section `%s': %E\n"), name);
+      return NULL;
+    }
+
+  if (entry->os.name != NULL)
+    {
+      /* We have a section of this name, but it might not have the correct
+        constraint.  */
+      hash = entry->root.hash;
+      do
+       {
+         if (entry->os.constraint != -1
+             && (constraint == 0
+                 || (constraint == entry->os.constraint
+                     && constraint != SPECIAL)))
+           return &entry->os;
+         last_ent = entry;
+         entry = (struct output_statement_hash_entry *) entry->root.next;
+       }
+      while (entry != NULL
+            && entry->root.hash == hash
+            && strcmp (name, entry->os.name) == 0);
 
       entry = ((struct output_statement_hash_entry *)
-              bfd_hash_lookup (&output_statement_table, name, TRUE,
-                               FALSE));
+              output_statement_newfunc (NULL, &output_statement_table, name));
       if (entry == NULL)
-       einfo (_("%P%F: bfd_hash_lookup failed creating section `%s'\n"),
-              name);
-
-      entry->entry = lookup;
-
-      /* 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 **) nextp);
+       {
+         einfo (_("%P%F: failed creating section `%s': %E\n"), name);
+         return NULL;
+       }
+      entry->root = last_ent->root;
+      last_ent->root.next = &entry->root;
     }
-  return lookup;
+
+  entry->os.name = name;
+  entry->os.constraint = constraint;
+  return &entry->os;
 }
 
 lang_output_section_statement_type *
@@ -1133,7 +1153,8 @@ lang_output_section_statement_lookup (const char *const name)
 
 lang_output_section_statement_type *
 lang_output_section_find_by_flags (const asection *sec,
-                                  lang_output_section_statement_type **exact)
+                                  lang_output_section_statement_type **exact,
+                                  lang_match_sec_type_func match_type)
 {
   lang_output_section_statement_type *first, *look, *found;
   flagword flags;
@@ -1151,9 +1172,8 @@ lang_output_section_find_by_flags (const asection *sec,
       if (look->bfd_section != NULL)
        {
          flags = look->bfd_section->flags;
-         if (!bfd_match_sections_by_type (output_bfd,
-                                          look->bfd_section,
-                                          sec->owner, sec))
+         if (match_type && !match_type (output_bfd, look->bfd_section,
+                                        sec->owner, sec))
            continue;
        }
       flags ^= sec->flags;
@@ -1163,7 +1183,8 @@ lang_output_section_find_by_flags (const asection *sec,
     }
   if (found != NULL)
     {
-      *exact = found;
+      if (exact != NULL)
+       *exact = found;
       return found;
     }
 
@@ -1176,9 +1197,8 @@ lang_output_section_find_by_flags (const asection *sec,
          if (look->bfd_section != NULL)
            {
              flags = look->bfd_section->flags;
-             if (!bfd_match_sections_by_type (output_bfd,
-                                              look->bfd_section,
-                                              sec->owner, sec))
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
                continue;
            }
          flags ^= sec->flags;
@@ -1186,10 +1206,8 @@ lang_output_section_find_by_flags (const asection *sec,
                         | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
            found = look;
        }
-      return found;
     }
-
-  if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
+  else if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
     {
       /* .rodata can go after .text, .sdata2 after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1198,9 +1216,8 @@ lang_output_section_find_by_flags (const asection *sec,
          if (look->bfd_section != NULL)
            {
              flags = look->bfd_section->flags;
-             if (!bfd_match_sections_by_type (output_bfd,
-                                              look->bfd_section,
-                                              sec->owner, sec))
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
                continue;
            }
          flags ^= sec->flags;
@@ -1209,10 +1226,8 @@ lang_output_section_find_by_flags (const asection *sec,
              && !(look->flags & (SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
            found = look;
        }
-      return found;
     }
-
-  if (sec->flags & SEC_SMALL_DATA)
+  else if (sec->flags & SEC_SMALL_DATA)
     {
       /* .sdata goes after .data, .sbss after .sdata.  */
       for (look = first; look; look = look->next)
@@ -1221,9 +1236,8 @@ lang_output_section_find_by_flags (const asection *sec,
          if (look->bfd_section != NULL)
            {
              flags = look->bfd_section->flags;
-             if (!bfd_match_sections_by_type (output_bfd,
-                                              look->bfd_section,
-                                              sec->owner, sec))
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
                continue;
            }
          flags ^= sec->flags;
@@ -1233,10 +1247,8 @@ lang_output_section_find_by_flags (const asection *sec,
                  && !(sec->flags & SEC_HAS_CONTENTS)))
            found = look;
        }
-      return found;
     }
-
-  if (sec->flags & SEC_HAS_CONTENTS)
+  else if (sec->flags & SEC_HAS_CONTENTS)
     {
       /* .data goes after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1245,9 +1257,8 @@ lang_output_section_find_by_flags (const asection *sec,
          if (look->bfd_section != NULL)
            {
              flags = look->bfd_section->flags;
-             if (!bfd_match_sections_by_type (output_bfd,
-                                              look->bfd_section,
-                                              sec->owner, sec))
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
                continue;
            }
          flags ^= sec->flags;
@@ -1255,27 +1266,30 @@ lang_output_section_find_by_flags (const asection *sec,
                         | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
            found = look;
        }
-      return found;
     }
-
-  /* .bss goes last.  */
-  for (look = first; look; look = look->next)
+  else
     {
-      flags = look->flags;
-      if (look->bfd_section != NULL)
+      /* .bss goes last.  */
+      for (look = first; look; look = look->next)
        {
-         flags = look->bfd_section->flags;
-         if (!bfd_match_sections_by_type (output_bfd,
-                                          look->bfd_section,
-                                          sec->owner, sec))
-           continue;
+         flags = look->flags;
+         if (look->bfd_section != NULL)
+           {
+             flags = look->bfd_section->flags;
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
+               continue;
+           }
+         flags ^= sec->flags;
+         if (!(flags & SEC_ALLOC))
+           found = look;
        }
-      flags ^= sec->flags;
-      if (!(flags & SEC_ALLOC))
-       found = look;
     }
 
-  return found;
+  if (found || !match_type)
+    return found;
+
+  return lang_output_section_find_by_flags (sec, NULL, NULL);
 }
 
 /* Find the last output section before given output statement.
@@ -1284,28 +1298,22 @@ lang_output_section_find_by_flags (const asection *sec,
 static asection *
 output_prev_sec_find (lang_output_section_statement_type *os)
 {
-  asection *s = (asection *) NULL;
   lang_output_section_statement_type *lookup;
 
-  for (lookup = &lang_output_section_statement.head->output_section_statement;
-       lookup != NULL;
-       lookup = lookup->next)
+  for (lookup = os->prev; lookup != NULL; lookup = lookup->prev)
     {
       if (lookup->constraint == -1)
        continue;
-      if (lookup == os)
-       return s;
 
       if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL)
-       s = lookup->bfd_section;
+       return lookup->bfd_section;
     }
 
   return NULL;
 }
 
 lang_output_section_statement_type *
-lang_insert_orphan (lang_input_statement_type *file,
-                   asection *s,
+lang_insert_orphan (asection *s,
                    const char *secname,
                    lang_output_section_statement_type *after,
                    struct orphan_save *place,
@@ -1376,7 +1384,7 @@ lang_insert_orphan (lang_input_statement_type *file,
 
   if (add_child == NULL)
     add_child = &os->children;
-  lang_add_section (add_child, s, os, file);
+  lang_add_section (add_child, s, os);
 
   lang_leave_output_section_statement (0, "*default*", NULL, NULL);
 
@@ -1459,13 +1467,20 @@ lang_insert_orphan (lang_input_statement_type *file,
            {
              lang_statement_union_type **where;
              lang_statement_union_type **assign = NULL;
+             bfd_boolean ignore_first;
 
              /* Look for a suitable place for the new statement list.
                 The idea is to skip over anything that might be inside
                 a SECTIONS {} statement in a script, before we find
                 another output_section_statement.  Assignments to "dot"
                 before an output section statement are assumed to
-                belong to it.  */
+                belong to it.  An exception to this rule is made for
+                the first assignment to dot, otherwise we might put an
+                orphan before . = . + SIZEOF_HEADERS or similar
+                assignments that set the initial address.  */
+
+             ignore_first = after == (&lang_output_section_statement.head
+                                      ->output_section_statement);
              for (where = &after->header.next;
                   *where != NULL;
                   where = &(*where)->header.next)
@@ -1479,9 +1494,11 @@ lang_insert_orphan (lang_input_statement_type *file,
                          ass = &(*where)->assignment_statement;
                          if (ass->exp->type.node_class != etree_assert
                              && ass->exp->assign.dst[0] == '.'
-                             && ass->exp->assign.dst[1] == 0)
+                             && ass->exp->assign.dst[1] == 0
+                             && !ignore_first)
                            assign = where;
                        }
+                     ignore_first = FALSE;
                      continue;
                    case lang_wild_statement_enum:
                    case lang_input_section_enum:
@@ -1530,7 +1547,12 @@ lang_insert_orphan (lang_input_statement_type *file,
          /* Do the same for the list of output section statements.  */
          newly_added_os = *os_tail;
          *os_tail = NULL;
+         newly_added_os->prev = (lang_output_section_statement_type *)
+           ((char *) place->os_tail
+            - offsetof (lang_output_section_statement_type, next));
          newly_added_os->next = *place->os_tail;
+         if (newly_added_os->next != NULL)
+           newly_added_os->next->prev = newly_added_os;
          *place->os_tail = newly_added_os;
          place->os_tail = &newly_added_os->next;
 
@@ -1674,7 +1696,7 @@ sort_def_symbol (hash_entry, info)
 /* Initialize an output section.  */
 
 static void
-init_os (lang_output_section_statement_type *s)
+init_os (lang_output_section_statement_type *s, asection *isec)
 {
   if (s->bfd_section != NULL)
     return;
@@ -1691,9 +1713,6 @@ init_os (lang_output_section_statement_type *s)
             output_bfd->xvec->name, s->name);
     }
   s->bfd_section->output_section = s->bfd_section;
-
-  /* We initialize an output sections output offset to minus its own
-     vma to allow us to output a section through itself.  */
   s->bfd_section->output_offset = 0;
   if (!command_line.reduce_memory_overheads)
     {
@@ -1711,6 +1730,15 @@ init_os (lang_output_section_statement_type *s)
 
   if (s->load_base != NULL)
     exp_init_os (s->load_base);
+
+  /* If supplied an alignment, set it.  */
+  if (s->section_alignment != -1)
+    s->bfd_section->alignment_power = s->section_alignment;
+
+  if (isec)
+    bfd_init_private_section_data (isec->owner, isec,
+                                  output_bfd, s->bfd_section,
+                                  &link_info);
 }
 
 /* Make sure that all output sections mentioned in an expression are
@@ -1756,7 +1784,7 @@ exp_init_os (etree_type *exp)
 
            os = lang_output_section_find (exp->name.name);
            if (os != NULL && os->bfd_section == NULL)
-             init_os (os);
+             init_os (os, NULL);
          }
        }
       break;
@@ -1796,8 +1824,7 @@ section_already_linked (bfd *abfd, asection *sec, void *data)
 void
 lang_add_section (lang_statement_list_type *ptr,
                  asection *section,
-                 lang_output_section_statement_type *output,
-                 lang_input_statement_type *file)
+                 lang_output_section_statement_type *output)
 {
   flagword flags = section->flags;
   bfd_boolean discard;
@@ -1833,7 +1860,7 @@ lang_add_section (lang_statement_list_type *ptr,
       flagword flags;
 
       if (output->bfd_section == NULL)
-       init_os (output);
+       init_os (output, section);
 
       first = ! output->bfd_section->linker_has_input;
       output->bfd_section->linker_has_input = 1;
@@ -1855,7 +1882,6 @@ lang_add_section (lang_statement_list_type *ptr,
       new = new_stat (lang_input_section, ptr);
 
       new->section = section;
-      new->ifile = file;
       section->output_section = output->bfd_section;
 
       flags = section->flags;
@@ -1928,10 +1954,6 @@ lang_add_section (lang_statement_list_type *ptr,
       if (section->alignment_power > output->bfd_section->alignment_power)
        output->bfd_section->alignment_power = section->alignment_power;
 
-      /* If supplied an alignment, then force it.  */
-      if (output->section_alignment != -1)
-       output->bfd_section->alignment_power = output->section_alignment;
-
       if (bfd_get_arch (section->owner) == bfd_arch_tic54x
          && (section->flags & SEC_TIC54X_BLOCK) != 0)
        {
@@ -2035,15 +2057,14 @@ wild_sort (lang_wild_statement_type *wild,
              fa = FALSE;
            }
 
-         if (ls->ifile->the_bfd != NULL
-             && bfd_my_archive (ls->ifile->the_bfd) != NULL)
+         if (bfd_my_archive (ls->section->owner) != NULL)
            {
-             ln = bfd_get_filename (bfd_my_archive (ls->ifile->the_bfd));
+             ln = bfd_get_filename (bfd_my_archive (ls->section->owner));
              la = TRUE;
            }
          else
            {
-             ln = ls->ifile->filename;
+             ln = ls->section->owner->filename;
              la = FALSE;
            }
 
@@ -2058,7 +2079,7 @@ wild_sort (lang_wild_statement_type *wild,
              if (fa)
                fn = file->filename;
              if (la)
-               ln = ls->ifile->filename;
+               ln = ls->section->owner->filename;
 
              i = strcmp (fn, ln);
              if (i > 0)
@@ -2104,8 +2125,7 @@ output_section_callback (lang_wild_statement_type *ptr,
 
   if (before == NULL)
     lang_add_section (&ptr->children, section,
-                     (lang_output_section_statement_type *) output,
-                     file);
+                     (lang_output_section_statement_type *) output);
   else
     {
       lang_statement_list_type list;
@@ -2113,8 +2133,7 @@ output_section_callback (lang_wild_statement_type *ptr,
 
       lang_list_init (&list);
       lang_add_section (&list, section,
-                       (lang_output_section_statement_type *) output,
-                       file);
+                       (lang_output_section_statement_type *) output);
 
       /* If we are discarding the section, LIST.HEAD will
         be NULL.  */
@@ -2669,7 +2688,7 @@ open_output (const char *name)
 
   link_info.hash = bfd_link_hash_table_create (output);
   if (link_info.hash == NULL)
-    einfo (_("%P%F: can not create link hash table: %E\n"));
+    einfo (_("%P%F: can not create hash table: %E\n"));
 
   bfd_set_gp_size (output, g_switch_value);
   return output;
@@ -3099,7 +3118,7 @@ map_input_to_output_sections
             are initialized.  */
          exp_init_os (s->data_statement.exp);
          if (os != NULL && os->bfd_section == NULL)
-           init_os (os);
+           init_os (os, NULL);
          /* The output section gets contents, and then we inspect for
             any flags set in the input script which override any ALLOC.  */
          os->bfd_section->flags |= SEC_HAS_CONTENTS;
@@ -3113,11 +3132,11 @@ map_input_to_output_sections
        case lang_padding_statement_enum:
        case lang_input_statement_enum:
          if (os != NULL && os->bfd_section == NULL)
-           init_os (os);
+           init_os (os, NULL);
          break;
        case lang_assignment_statement_enum:
          if (os != NULL && os->bfd_section == NULL)
-           init_os (os);
+           init_os (os, NULL);
 
          /* Make sure that any sections mentioned in the assignment
             are initialized.  */
@@ -3145,7 +3164,7 @@ map_input_to_output_sections
                   (s->address_statement.section_name));
              
              if (aos->bfd_section == NULL)
-               init_os (aos);
+               init_os (aos, NULL);
              aos->addr_tree = s->address_statement.address;
            }
          break;
@@ -3540,7 +3559,7 @@ print_data_statement (lang_data_statement_type *data)
   for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
     print_space ();
 
-  addr = data->output_vma;
+  addr = data->output_offset;
   if (data->output_section != NULL)
     addr += data->output_section->vma;
 
@@ -3607,7 +3626,7 @@ print_reloc_statement (lang_reloc_statement_type *reloc)
   for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
     print_space ();
 
-  addr = reloc->output_vma;
+  addr = reloc->output_offset;
   if (reloc->output_section != NULL)
     addr += reloc->output_section->vma;
 
@@ -3892,7 +3911,8 @@ size_input_section
   lang_input_section_type *is = &((*this_ptr)->input_section);
   asection *i = is->section;
 
-  if (!is->ifile->just_syms_flag && (i->flags & SEC_EXCLUDE) == 0)
+  if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
+      && (i->flags & SEC_EXCLUDE) == 0)
     {
       unsigned int alignment_needed;
       asection *o;
@@ -4131,6 +4151,8 @@ lang_size_sections_1
              }
            else
              {
+               int align;
+
                if (os->addr_tree == NULL)
                  {
                    /* No address specified for this section, get one
@@ -4180,27 +4202,25 @@ lang_size_sections_1
                      }
 
                    newdot = os->region->current;
-
-                   if (os->section_alignment == -1)
-                     {
-                       bfd_vma savedot = newdot;
-                       newdot = align_power (newdot,
-                                             os->bfd_section->alignment_power);
-
-                       if (newdot != savedot
-                           && config.warn_section_align
-                           && expld.phase != lang_mark_phase_enum)
-                         einfo (_("%P: warning: changing start of section"
-                                  " %s by %lu bytes\n"),
-                                os->name, (unsigned long) (newdot - savedot));
-                     }
+                   align = os->bfd_section->alignment_power;
                  }
+               else
+                 align = os->section_alignment;
 
-               /* The section starts here.
-                  First, align to what the section needs.  */
+               /* Align to what the section needs.  */
+               if (align > 0)
+                 {
+                   bfd_vma savedot = newdot;
+                   newdot = align_power (newdot, align);
 
-               if (os->section_alignment != -1)
-                 newdot = align_power (newdot, os->section_alignment);
+                   if (newdot != savedot
+                       && (config.warn_section_align
+                           || os->addr_tree != NULL)
+                       && expld.phase != lang_mark_phase_enum)
+                     einfo (_("%P: warning: changing start of section"
+                              " %s by %lu bytes\n"),
+                            os->name, (unsigned long) (newdot - savedot));
+                 }
 
                bfd_set_section_vma (0, os->bfd_section, newdot);
 
@@ -4287,7 +4307,7 @@ lang_size_sections_1
          {
            unsigned int size = 0;
 
-           s->data_statement.output_vma =
+           s->data_statement.output_offset =
              dot - output_section_statement->bfd_section->vma;
            s->data_statement.output_section =
              output_section_statement->bfd_section;
@@ -4325,7 +4345,7 @@ lang_size_sections_1
          {
            int size;
 
-           s->reloc_statement.output_vma =
+           s->reloc_statement.output_offset =
              dot - output_section_statement->bfd_section->vma;
            s->reloc_statement.output_section =
              output_section_statement->bfd_section;
@@ -5055,17 +5075,17 @@ lang_place_orphans (void)
 
                        }
                      lang_add_section (&default_common_section->children, s,
-                                       default_common_section, file);
+                                       default_common_section);
                    }
                }
-             else if (ldemul_place_orphan (file, s))
+             else if (ldemul_place_orphan (s))
                ;
              else
                {
                  lang_output_section_statement_type *os;
 
                  os = lang_output_section_statement_lookup (s->name);
-                 lang_add_section (&os->children, s, os, file);
+                 lang_add_section (&os->children, s, os);
                }
            }
        }
@@ -5213,10 +5233,9 @@ lang_enter_output_section_statement (const char *output_section_statement_name,
 {
   lang_output_section_statement_type *os;
 
-  current_section =
-   os =
-    lang_output_section_statement_lookup_1 (output_section_statement_name,
-                                           constraint);
+   os = lang_output_section_statement_lookup_1 (output_section_statement_name,
+                                               constraint);
+   current_section = os;
 
   /* Make next things chain into subchain of this.  */
 
@@ -5244,9 +5263,9 @@ lang_enter_output_section_statement (const char *output_section_statement_name,
 void
 lang_final (void)
 {
-  lang_output_statement_type *new =
-    new_stat (lang_output_statement, stat_ptr);
+  lang_output_statement_type *new;
 
+  new = new_stat (lang_output_statement, stat_ptr);
   new->name = output_filename;
 }
 
@@ -5608,11 +5627,10 @@ lang_default_entry (const char *name)
 void
 lang_add_target (const char *name)
 {
-  lang_target_statement_type *new = new_stat (lang_target_statement,
-                                             stat_ptr);
+  lang_target_statement_type *new;
 
+  new = new_stat (lang_target_statement, stat_ptr);
   new->target = name;
-
 }
 
 void
@@ -5633,22 +5651,20 @@ lang_add_map (const char *name)
 void
 lang_add_fill (fill_type *fill)
 {
-  lang_fill_statement_type *new = new_stat (lang_fill_statement,
-                                           stat_ptr);
+  lang_fill_statement_type *new;
 
+  new = new_stat (lang_fill_statement, stat_ptr);
   new->fill = fill;
 }
 
 void
 lang_add_data (int type, union etree_union *exp)
 {
+  lang_data_statement_type *new;
 
-  lang_data_statement_type *new = new_stat (lang_data_statement,
-                                           stat_ptr);
-
+  new = new_stat (lang_data_statement, stat_ptr);
   new->exp = exp;
   new->type = type;
-
 }
 
 /* Create a new reloc statement.  RELOC is the BFD relocation type to
@@ -5675,15 +5691,15 @@ lang_add_reloc (bfd_reloc_code_real_type reloc,
 
   p->addend_value = 0;
   p->output_section = NULL;
-  p->output_vma = 0;
+  p->output_offset = 0;
 }
 
 lang_assignment_statement_type *
 lang_add_assignment (etree_type *exp)
 {
-  lang_assignment_statement_type *new = new_stat (lang_assignment_statement,
-                                                 stat_ptr);
+  lang_assignment_statement_type *new;
 
+  new = new_stat (lang_assignment_statement, stat_ptr);
   new->exp = exp;
   return new;
 }
@@ -5691,7 +5707,7 @@ lang_add_assignment (etree_type *exp)
 void
 lang_add_attribute (enum statement_enum attribute)
 {
-  new_statement (attribute, sizeof (lang_statement_union_type), stat_ptr);
+  new_statement (attribute, sizeof (lang_statement_header_type), stat_ptr);
 }
 
 void
This page took 0.038976 seconds and 4 git commands to generate.