* ldlang.c (new_afile): Add new argument add_to_list. Don't set
authorIan Lance Taylor <ian@airs.com>
Thu, 24 Mar 1994 20:25:12 +0000 (20:25 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 24 Mar 1994 20:25:12 +0000 (20:25 +0000)
real to true for lang_input_file_is_marker_enum.  Clear the_bfd.
(lang_add_input_file): Pass true to new_afile for add_to_list.
(lookup_name): Remove force_load argument.  Changed all callers.
Pass false to new_afile for add_to_list.  Split loading of symbols
out into separate function.
(load_symbols): New function split out of lookup_name.  Don't load
the symbols if they are already loaded.
(open_input_bfds): For lang_input_statement_enum call load_symbols
rather than lookup_name.
(lang_process): Pass abs_output_section rather than NULL to
lang_size_sections.
(lang_startup): Set real field of first_file to true.

ld/ChangeLog
ld/ldlang.c

index caa13fcf84d0ac6c9601883feb0f5687e157f509..891d42553dac0b354eda0ead687882ed2c7dda13 100644 (file)
@@ -1,5 +1,29 @@
+Thu Mar 24 15:20:47 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       * ldlang.c (new_afile): Add new argument add_to_list.  Don't set
+       real to true for lang_input_file_is_marker_enum.  Clear the_bfd.
+       (lang_add_input_file): Pass true to new_afile for add_to_list.
+       (lookup_name): Remove force_load argument.  Changed all callers.
+       Pass false to new_afile for add_to_list.  Split loading of symbols
+       out into separate function.
+       (load_symbols): New function split out of lookup_name.  Don't load
+       the symbols if they are already loaded.
+       (open_input_bfds): For lang_input_statement_enum call load_symbols
+       rather than lookup_name.
+       (lang_process): Pass abs_output_section rather than NULL to
+       lang_size_sections.
+       (lang_startup): Set real field of first_file to true.
+
 Wed Mar 23 14:15:44 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
+       * ldlang.c (had_relax): Removed.
+       (relax_again): New static variable.
+       (lang_size_sections): Change call to bfd_relax_section to
+       correspond to BFD changes.  Set relax_again appropriately.
+       (lang_process): Remove #if 0 code.  When relaxing, keep calling
+       lang_do_assignments and lang_size_sections until relax_again
+       becomes false.
+
        * emultemp/gld960.em: Include libiberty.h
        (gld960_before_parse): Pass NULL as final argument to concat.
 
index 712eb80e1db3832342972b87a2d521ca56fd38cb..484a8d03ee96ae57942d5c2a1cc320010c707773 100644 (file)
@@ -74,7 +74,7 @@ static void lang_for_each_statement_worker
           lang_statement_union_type *s));
 static lang_input_statement_type *new_afile
   PARAMS ((const char *name, lang_input_file_enum_type file_type,
-          const char *target));
+          const char *target, boolean add_to_list));
 static void print_flags PARAMS ((int *ignore_flags));
 static void init_os PARAMS ((lang_output_section_statement_type *s));
 static void wild_doit PARAMS ((lang_statement_list_type *ptr,
@@ -87,8 +87,8 @@ static void wild_section PARAMS ((lang_wild_statement_type *ptr,
                                  const char *section,
                                  lang_input_statement_type *file,
                                  lang_output_section_statement_type *output));
-static lang_input_statement_type *lookup_name PARAMS ((const char *name,
-                                                      int force_load));
+static lang_input_statement_type *lookup_name PARAMS ((const char *name));
+static void load_symbols PARAMS ((lang_input_statement_type *entry));
 static void wild PARAMS ((lang_wild_statement_type *s,
                          const char *section, const char *file,
                          const char *target,
@@ -300,14 +300,22 @@ new_statement (type, size, list)
 
  */
 static lang_input_statement_type *
-new_afile (name, file_type, target)
+new_afile (name, file_type, target, add_to_list)
      CONST char *name;
      lang_input_file_enum_type file_type;
      CONST char *target;
+     boolean add_to_list;
 {
+  lang_input_statement_type *p;
 
-  lang_input_statement_type *p = new_stat (lang_input_statement,
-                                          stat_ptr);
+  if (add_to_list)
+    p = new_stat (lang_input_statement, stat_ptr);
+  else
+    {
+      p = ((lang_input_statement_type *)
+          stat_alloc (sizeof (lang_input_statement_type)));
+      p->header.next = NULL;
+    }
 
   lang_has_input_file = true;
   p->target = target;
@@ -338,8 +346,15 @@ new_afile (name, file_type, target)
       p->just_syms_flag = false;
       p->search_dirs_flag = true;
       break;
-    case lang_input_file_is_search_file_enum:
     case lang_input_file_is_marker_enum:
+      p->filename = name;
+      p->is_archive = false;
+      p->real = false;
+      p->local_sym_name = name;
+      p->just_syms_flag = false;
+      p->search_dirs_flag = true;
+      break;
+    case lang_input_file_is_search_file_enum:
       p->filename = name;
       p->is_archive = false;
       p->real = true;
@@ -358,6 +373,7 @@ new_afile (name, file_type, target)
     default:
       FAIL ();
     }
+  p->the_bfd = (bfd *) NULL;
   p->asymbols = (asymbol **) NULL;
   p->superfile = (lang_input_statement_type *) NULL;
   p->next_real_file = (lang_statement_union_type *) NULL;
@@ -396,7 +412,7 @@ lang_add_input_file (name, file_type, target)
 
     }
 #endif
-  return new_afile (name, file_type, target);
+  return new_afile (name, file_type, target, true);
 }
 
 /* Build enough state so that the parser can build its tree */
@@ -745,11 +761,9 @@ wild_section (ptr, section, file, output)
    not define anything we need at the time, they won't have all their
    symbols read. If we need them later, we'll have to redo it.
    */
-static
-lang_input_statement_type *
-lookup_name (name, force_load)
+static lang_input_statement_type *
+lookup_name (name)
      CONST char *name;
-     int force_load;
 {
   lang_input_statement_type *search;
 
@@ -766,50 +780,52 @@ lookup_name (name, force_load)
     }
 
   if (search == (lang_input_statement_type *) NULL)
-    {
-      /* There isn't an afile entry for this file yet, this must be
-        because the name has only appeared inside a load script and
-        not on the command line */
-      search = new_afile (name, lang_input_file_is_file_enum, default_target);
-    }
+    search = new_afile (name, lang_input_file_is_file_enum, default_target,
+                       false);
 
   /* If we have already added this file, or this file is not real
      (FIXME: can that ever actually happen?) or the name is NULL
      (FIXME: can that ever actually happen?) don't add this file.  */
-  if ((search->loaded && ! force_load)
+  if (search->loaded
       || ! search->real
       || search->filename == (const char *) NULL)
     return search;
-/* start-sanitize-mpw */
-#ifdef MPW
-  /* I hate adding code that works, but for reasons I don't know. */
-  search->the_bfd = NULL;
-#endif
-/* end-sanitize-mpw */
 
-  ldfile_open_file (search);
+  load_symbols (search);
+
+  return search;
+}
+
+/* Get the symbols for an input file.  */
 
-  if (bfd_check_format (search->the_bfd, bfd_object))
+static void
+load_symbols (entry)
+     lang_input_statement_type *entry;
+{
+  if (entry->loaded)
+    return;
+
+  ldfile_open_file (entry);
+
+  if (bfd_check_format (entry->the_bfd, bfd_object))
     {
-      ldlang_add_file (search);
+      ldlang_add_file (entry);
       if (trace_files || trace_file_tries)
-       info_msg ("%I\n", search);
+       info_msg ("%I\n", entry);
     }
-  else if (bfd_check_format (search->the_bfd, bfd_archive))
+  else if (bfd_check_format (entry->the_bfd, bfd_archive))
     {
       /* There is nothing to do here; the add_symbols routine will
         call ldlang_add_file (via the add_archive_element callback)
         for each element of the archive which is used.  */
     }
   else
-    einfo ("%F%B: file not recognized: %E\n", search->the_bfd);
-
-  if (bfd_link_add_symbols (search->the_bfd, &link_info) == false)
-    einfo ("%F%B: could not read symbols: %E\n", search->the_bfd);
+    einfo ("%F%B: file not recognized: %E\n", entry->the_bfd);
 
-  search->loaded = true;
+  if (bfd_link_add_symbols (entry->the_bfd, &link_info) == false)
+    einfo ("%F%B: could not read symbols: %E\n", entry->the_bfd);
 
-  return search;
+  entry->loaded = true;
 }
 
 static void
@@ -835,7 +851,7 @@ wild (s, section, file, target, output)
   else
     {
       /* Perform the iteration over a single file */
-      wild_section (s, section, lookup_name (file, 0), output);
+      wild_section (s, section, lookup_name (file), output);
     }
   if (section != (char *) NULL
       && strcmp (section, "COMMON") == 0
@@ -938,14 +954,14 @@ open_input_bfds (statement)
       /* Maybe we should load the file's symbols */
       if (statement->wild_statement.filename)
        {
-         (void) lookup_name (statement->wild_statement.filename, 1);
+         (void) lookup_name (statement->wild_statement.filename);
        }
       break;
     case lang_input_statement_enum:
       if (statement->input_statement.real == true)
        {
          statement->input_statement.target = current_target;
-         lookup_name (statement->input_statement.filename, 1);
+         load_symbols (&statement->input_statement);
        }
       break;
     default:
@@ -1613,11 +1629,12 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax)
   return dot;
 }
 
-/* Sizing happens in two passes, first pass we allocate worst case
-   stuff. The second pass (if relaxing), we use what we learnt to
-   change the size of some relocs from worst case to better
-   */
-static boolean had_relax;
+/* This variable indicates whether bfd_relax_section should be called
+   again.  */
+
+static boolean relax_again;
+
+/* Set the sizes for all the output sections.  */
 
 bfd_vma
 lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
@@ -1800,50 +1817,26 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
      case lang_target_statement_enum:
       break;
      case lang_input_section_enum:
-      if (relax)
       {
-       lang_input_section_type *is;
        asection *i;
 
-       is = &(*prev)->input_section;
-       i = is->section;
-
-       /* FIXME: The interface to bfd_relax_section should be changed
-          to not require the generic symbols to be read.  Changing
-          this would require changing both b_out_relax_section and
-          bfd_coff_relax16_section.  */
-       if (is->ifile->asymbols == (asymbol **) NULL)
+       i = (*prev)->input_section.section;
+       if (! relax)
+         i->_cooked_size = i->_raw_size;
+       else
          {
-           unsigned int symsize;
-
-           symsize = get_symtab_upper_bound (i->owner);
-           is->ifile->asymbols = (asymbol **) xmalloc (symsize);
-           is->ifile->symbol_count =
-             bfd_canonicalize_symtab (i->owner, is->ifile->asymbols);
-
-           /* The generic linker code in BFD requires that these
-              symbols be stored in the outsymbols and symcount
-              fields.  When the bfd_relax_section is interface is
-              fixed this should also be fixed.  */
-           i->owner->outsymbols = is->ifile->asymbols;
-           i->owner->symcount = is->ifile->symbol_count;
-         }
-
-       bfd_set_error (bfd_error_no_error);
-       if (bfd_relax_section (i->owner, i, &link_info, is->ifile->asymbols))
-         had_relax = true;
-       else if (bfd_get_error () != bfd_error_no_error)
-         einfo ("%P%F: can't relax section: %E");
-      }
-      else  {
-       (*prev)->input_section.section->_cooked_size = 
-        (*prev)->input_section.section->_raw_size ;
+           boolean again;
 
+           if (! bfd_relax_section (i->owner, i, &link_info, &again))
+             einfo ("%P%F: can't relax section: %E\n");
+           if (again)
+             relax_again = true;
+         }
+       dot = size_input_section (prev,
+                                 output_section_statement,
+                                 output_section_statement->fill,
+                                 dot, relax);
       }
-      dot = size_input_section (prev,
-                               output_section_statement,
-                               output_section_statement->fill,
-                               dot, relax);
       break;
      case lang_input_statement_enum:
       break;
@@ -2529,49 +2522,36 @@ lang_process ()
 
   ldemul_before_allocation ();
 
-
-#if 0
-  had_relax = true;
-  while (had_relax)
-    {
-
-      had_relax = false;
-
-      lang_size_sections (statement_list.head,
-                         (lang_output_section_statement_type *) NULL,
-                         &(statement_list.head), 0, (bfd_vma) 0, true);
-      /* FIXME. Until the code in relax is fixed so that it only reads in
-         stuff once, we cant iterate since there is no way for the linker to
-         know what has been patched and what hasn't */
-      break;
-
-    }
-#endif
-
   /* Now run around and relax if we can */
   if (command_line.relax)
     {
       /* First time round is a trial run to get the 'worst case'
         addresses of the objects if there was no relaxing.  */
       lang_size_sections (statement_list.head,
-                         (lang_output_section_statement_type *) NULL,
+                         abs_output_section,
                          &(statement_list.head), 0, (bfd_vma) 0, false);
 
 
       reset_memory_regions ();
 
-      /* Do all the assignments, now that we know the final resting
-        places of all the symbols.  */
+      /* Keep relaxing until bfd_relax_section gives up.  */
+      do
+       {
+         relax_again = false;
 
-      lang_do_assignments (statement_list.head,
-                          abs_output_section,
-                          (fill_type) 0, (bfd_vma) 0);
+         /* Do all the assignments with our current guesses as to
+            section sizes.  */
+         lang_do_assignments (statement_list.head,
+                              abs_output_section,
+                              (fill_type) 0, (bfd_vma) 0);
 
-      /* Perform another relax pass - this time we know where the
-        globals are, so can make better guess.  */
-      lang_size_sections (statement_list.head,
-                         (lang_output_section_statement_type *) NULL,
-                         &(statement_list.head), 0, (bfd_vma) 0, true);
+         /* Perform another relax pass - this time we know where the
+            globals are, so can make better guess.  */
+         lang_size_sections (statement_list.head,
+                             abs_output_section,
+                             &(statement_list.head), 0, (bfd_vma) 0, true);
+       }
+      while (relax_again);
     }
   else
     {
@@ -2749,6 +2729,7 @@ lang_startup (name)
     }
   first_file->filename = name;
   first_file->local_sym_name = name;
+  first_file->real = true;
 
   startup_file = name;
 }