2006-05-11 Paul Brook <paul@codesourcery.com>
[platform/upstream/binutils.git] / ld / ldlang.c
index f6d849e..f376652 100644 (file)
@@ -81,6 +81,7 @@ static void print_statement (lang_statement_union_type *,
 static void print_statement_list (lang_statement_union_type *,
                                  lang_output_section_statement_type *);
 static void print_statements (void);
+static void print_input_section (asection *);
 static bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *);
 static void lang_record_phdrs (void);
 static void lang_do_version_exports_section (void);
@@ -1596,8 +1597,31 @@ void
 lang_map (void)
 {
   lang_memory_region_type *m;
+  bfd_boolean dis_header_printed = FALSE;
   bfd *p;
 
+  LANG_FOR_EACH_INPUT_STATEMENT (file)
+    {
+      asection *s;
+
+      if ((file->the_bfd->flags & (BFD_LINKER_CREATED | DYNAMIC)) != 0
+         || file->just_syms_flag)
+       continue;
+
+      for (s = file->the_bfd->sections; s != NULL; s = s->next)
+       if (s->output_section == NULL
+           || s->output_section->owner != output_bfd)
+         {
+           if (! dis_header_printed)
+             {
+               fprintf (config.map_file, _("\nDiscarded input sections\n\n"));
+               dis_header_printed = TRUE;
+             }
+
+           print_input_section (s);
+         }
+    }
+
   minfo (_("\nMemory Configuration\n\n"));
   fprintf (config.map_file, "%-16s %-18s %-18s %s\n",
           _("Name"), _("Origin"), _("Length"), _("Attributes"));
@@ -2299,6 +2323,7 @@ load_symbols (lang_input_statement_type *entry,
       lang_statement_list_type *hold;
       bfd_boolean bad_load = TRUE;
       bfd_boolean save_ldlang_sysrooted_script;
+      bfd_boolean save_as_needed, save_add_needed;
 
       err = bfd_get_error ();
 
@@ -2332,6 +2357,10 @@ load_symbols (lang_input_statement_type *entry,
       stat_ptr = place;
       save_ldlang_sysrooted_script = ldlang_sysrooted_script;
       ldlang_sysrooted_script = entry->sysrooted;
+      save_as_needed = as_needed;
+      as_needed = entry->as_needed;
+      save_add_needed = add_needed;
+      add_needed = entry->add_needed;
 
       ldfile_assumed_script = TRUE;
       parser_input = input_script;
@@ -2342,6 +2371,8 @@ load_symbols (lang_input_statement_type *entry,
       ldfile_assumed_script = FALSE;
 
       ldlang_sysrooted_script = save_ldlang_sysrooted_script;
+      as_needed = save_as_needed;
+      add_needed = save_add_needed;
       stat_ptr = hold;
 
       return ! bad_load;
@@ -2427,17 +2458,15 @@ wild (lang_wild_statement_type *s,
 
   walk_wild (s, output_section_callback, output);
 
-  for (sec = s->section_list; sec != NULL; sec = sec->next)
-    {
-      if (default_common_section != NULL)
-       break;
+  if (default_common_section == NULL)
+    for (sec = s->section_list; sec != NULL; sec = sec->next)
       if (sec->spec.name != NULL && strcmp (sec->spec.name, "COMMON") == 0)
        {
          /* Remember the section that common is going to in case we
             later get something which doesn't know where to put it.  */
          default_common_section = output;
+         break;
        }
-    }
 }
 
 /* Return TRUE iff target is the sought target.  */
@@ -3475,68 +3504,64 @@ print_all_symbols (sec)
 /* Print information about an input section to the map file.  */
 
 static void
-print_input_section (lang_input_section_type *in)
+print_input_section (asection *i)
 {
-  asection *i = in->section;
   bfd_size_type size = i->size;
+  int len;
+  bfd_vma addr;
 
   init_opb ();
-  if (size != 0)
-    {
-      int len;
-      bfd_vma addr;
 
-      print_space ();
-      minfo ("%s", i->name);
+  print_space ();
+  minfo ("%s", i->name);
 
-      len = 1 + strlen (i->name);
-      if (len >= SECTION_NAME_MAP_LENGTH - 1)
-       {
-         print_nl ();
-         len = 0;
-       }
-      while (len < SECTION_NAME_MAP_LENGTH)
-       {
-         print_space ();
-         ++len;
-       }
+  len = 1 + strlen (i->name);
+  if (len >= SECTION_NAME_MAP_LENGTH - 1)
+    {
+      print_nl ();
+      len = 0;
+    }
+  while (len < SECTION_NAME_MAP_LENGTH)
+    {
+      print_space ();
+      ++len;
+    }
 
-      if (i->output_section != NULL && (i->flags & SEC_EXCLUDE) == 0)
-       addr = i->output_section->vma + i->output_offset;
-      else
-       {
-         addr = print_dot;
-         size = 0;
-       }
+  if (i->output_section != NULL && i->output_section->owner == output_bfd)
+    addr = i->output_section->vma + i->output_offset;
+  else
+    {
+      addr = print_dot;
+      size = 0;
+    }
 
-      minfo ("0x%V %W %B\n", addr, TO_ADDR (size), i->owner);
+  minfo ("0x%V %W %B\n", addr, TO_ADDR (size), i->owner);
 
-      if (size != i->rawsize && i->rawsize != 0)
-       {
-         len = SECTION_NAME_MAP_LENGTH + 3;
+  if (size != i->rawsize && i->rawsize != 0)
+    {
+      len = SECTION_NAME_MAP_LENGTH + 3;
 #ifdef BFD64
-         len += 16;
+      len += 16;
 #else
-         len += 8;
+      len += 8;
 #endif
-         while (len > 0)
-           {
-             print_space ();
-             --len;
-           }
-
-         minfo (_("%W (size before relaxing)\n"), i->rawsize);
+      while (len > 0)
+       {
+         print_space ();
+         --len;
        }
 
-      if (i->output_section != NULL && (i->flags & SEC_EXCLUDE) == 0)
-       {
-         if (command_line.reduce_memory_overheads)
-           bfd_link_hash_traverse (link_info.hash, print_one_symbol, i);
-         else
-           print_all_symbols (i);
+      minfo (_("%W (size before relaxing)\n"), i->rawsize);
+    }
 
-         print_dot = addr + TO_ADDR (size);
-       }
+  if (i->output_section != NULL && i->output_section->owner == output_bfd)
+    {
+      if (command_line.reduce_memory_overheads)
+       bfd_link_hash_traverse (link_info.hash, print_one_symbol, i);
+      else
+       print_all_symbols (i);
+
+      print_dot = addr + TO_ADDR (size);
     }
 }
 
@@ -3797,7 +3822,7 @@ print_statement (lang_statement_union_type *s,
       print_reloc_statement (&s->reloc_statement);
       break;
     case lang_input_section_enum:
-      print_input_section (&s->input_section);
+      print_input_section (s->input_section.section);
       break;
     case lang_padding_statement_enum:
       print_padding_statement (&s->padding_statement);
@@ -5388,6 +5413,37 @@ lang_gc_sections (void)
     bfd_gc_sections (output_bfd, &link_info);
 }
 
+/* Relax all sections until bfd_relax_section gives up.  */
+
+static void
+relax_sections (void)
+{
+  /* Keep relaxing until bfd_relax_section gives up.  */
+  bfd_boolean relax_again;
+
+  do
+    {
+      relax_again = FALSE; 
+
+      /* Note: pe-dll.c does something like this also.  If you find
+        you need to change this code, you probably need to change
+        pe-dll.c also.  DJ  */
+
+      /* Do all the assignments with our current guesses as to
+        section sizes.  */
+      lang_do_assignments ();
+
+      /* We must do this after lang_do_assignments, because it uses
+        size.  */
+      lang_reset_memory_regions ();
+
+      /* Perform another relax pass - this time we know where the
+        globals are, so can make a better guess.  */
+      lang_size_sections (&relax_again, FALSE);
+    }
+  while (relax_again);
+}
+
 void
 lang_process (void)
 {
@@ -5484,38 +5540,17 @@ lang_process (void)
   /* Now run around and relax if we can.  */
   if (command_line.relax)
     {
-      /* Keep relaxing until bfd_relax_section gives up.  */
-      bfd_boolean relax_again;
-
-      do
-       {
-         relax_again = FALSE;
-
-         /* Note: pe-dll.c does something like this also.  If you find
-            you need to change this code, you probably need to change
-            pe-dll.c also.  DJ  */
+      /* We may need more than one relaxation pass.  */
+      int i = link_info.relax_pass;
 
-         /* Do all the assignments with our current guesses as to
-            section sizes.  */
-         lang_do_assignments ();
+      /* The backend can use it to determine the current pass.  */
+      link_info.relax_pass = 0;
 
-         /* We must do this after lang_do_assignments, because it uses
-            size.  */
-         lang_reset_memory_regions ();
-
-         /* Perform another relax pass - this time we know where the
-            globals are, so can make a better guess.  */
-         lang_size_sections (&relax_again, FALSE);
-
-         /* If the normal relax is done and the relax finalize pass
-            is not performed yet, we perform another relax pass.  */
-         if (!relax_again && link_info.need_relax_finalize)
-           {
-             link_info.need_relax_finalize = FALSE;
-             relax_again = TRUE;
-           }
+      while (i--)
+       {
+         relax_sections ();
+         link_info.relax_pass++;
        }
-      while (relax_again);
 
       /* Final extra sizing to report errors.  */
       lang_do_assignments ();