2001-06-19 H.J. Lu <hjl@gnu.org>
[deliverable/binutils-gdb.git] / ld / ldlang.c
index f417a30bfd521a9878987a208a4eeb580742dc3d..5e57cacb45dbc1e636ec86fec49edc97a6946341 100644 (file)
@@ -42,9 +42,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <ctype.h>
 
 /* FORWARDS */
-static lang_statement_union_type *new_statement PARAMS ((enum statement_enum,
-                                                        size_t,
-                                                        lang_statement_list_type *));
+static lang_statement_union_type *new_statement
+  PARAMS ((enum statement_enum, size_t, lang_statement_list_type *));
 
 /* LOCALS */
 static struct obstack stat_obstack;
@@ -85,7 +84,7 @@ static void output_section_callback
   PARAMS ((lang_wild_statement_type *, asection *,
           lang_input_statement_type *, PTR));
 static lang_input_statement_type *lookup_name PARAMS ((const char *));
-static void load_symbols
+static boolean load_symbols
   PARAMS ((lang_input_statement_type *, lang_statement_list_type *));
 static void wild
   PARAMS ((lang_wild_statement_type *, const char *, const char *,
@@ -128,7 +127,6 @@ static bfd_vma size_input_section
           fill_type, bfd_vma, boolean));
 static void lang_finish PARAMS ((void));
 static void ignore_bfd_errors PARAMS ((const char *, ...));
-static void record_bfd_errors PARAMS ((const char *, ...));
 static void lang_check PARAMS ((void));
 static void lang_common PARAMS ((void));
 static boolean lang_one_common PARAMS ((struct bfd_link_hash_entry *, PTR));
@@ -192,18 +190,22 @@ struct unique_sections *unique_section_list;
 
 etree_type *base; /* Relocation base - or null */
 
-#if defined(__STDC__) || defined(ALMOST_STDC)
+#if defined (__STDC__) || defined (ALMOST_STDC)
 #define cat(a,b) a##b
 #else
 #define cat(a,b) a/**/b
 #endif
 
-/* Don't beautify the line below with "innocent" whitespace, it breaks the K&R C preprocessor!  */
-#define new_stat(x, y) (cat (x,_type)*) new_statement (cat (x,_enum), sizeof (cat (x,_type)), y)
+/* Don't beautify the line below with "innocent" whitespace, it breaks
+   the K&R C preprocessor!  */
+#define new_stat(x, y) \
+  (cat (x,_type)*) new_statement (cat (x,_enum), sizeof (cat (x,_type)), y)
 
-#define outside_section_address(q) ((q)->output_offset + (q)->output_section->vma)
+#define outside_section_address(q) \
+  ((q)->output_offset + (q)->output_section->vma)
 
-#define outside_symbol_address(q) ((q)->value + outside_section_address (q->section))
+#define outside_symbol_address(q) \
+  ((q)->value + outside_section_address (q->section))
 
 #define SECTION_NAME_MAP_LENGTH (16)
 
@@ -245,14 +247,16 @@ walk_wild_section (ptr, section, file, callback, data)
   if (ptr->exclude_filename_list != NULL)
     {
       struct name_list *list_tmp;
-      for (list_tmp = ptr->exclude_filename_list; list_tmp; list_tmp = list_tmp->next)
+      for (list_tmp = ptr->exclude_filename_list;
+          list_tmp;
+          list_tmp = list_tmp->next)
        {
          boolean match;
 
          if (wildcardp (list_tmp->name))
-           match = fnmatch (list_tmp->name, file->filename, 0) == 0 ? true : false;
+           match = fnmatch (list_tmp->name, file->filename, 0) == 0;
          else
-           match = strcmp (list_tmp->name, file->filename) == 0 ? true : false;
+           match = strcmp (list_tmp->name, file->filename) == 0;
 
          if (match)
            return;
@@ -275,9 +279,9 @@ walk_wild_section (ptr, section, file, callback, data)
          if (section == NULL)
            match = true;
          else if (wildcard)
-           match = fnmatch (section, sname, 0) == 0 ? true : false;
+           match = fnmatch (section, sname, 0) == 0;
          else
-           match = strcmp (section, sname) == 0 ? true : false;
+           match = strcmp (section, sname) == 0;
 
          /* If this is a wild-card output section statement, exclude
             sections that match UNIQUE_SECTION_LIST.  */
@@ -356,7 +360,8 @@ walk_wild (s, section, file, callback, data)
 
       /* Perform the iteration over a single file.  */
       f = lookup_name (file);
-      walk_wild_file (s, section, f, callback, data);
+      if (f)
+       walk_wild_file (s, section, f, callback, data);
     }
 }
 
@@ -450,7 +455,7 @@ new_statement (type, size, list)
 
    We can be supplied with requests for input files more than once;
    they may, for example be split over serveral lines like foo.o(.text)
-   foo.o(.data) etc, so when asked for a file we check that we havn't
+   foo.o(.data) etc, so when asked for a file we check that we haven't
    got it already so we don't duplicate the bfd.  */
 
 static lang_input_statement_type *
@@ -623,7 +628,7 @@ lang_memory_region_lookup (name)
     lang_memory_region_type *new =
     (lang_memory_region_type *) stat_alloc (sizeof (lang_memory_region_type));
 
-    new->name = buystring (name);
+    new->name = xstrdup (name);
     new->next = (lang_memory_region_type *) NULL;
 
     *lang_memory_region_list_tail = new;
@@ -809,7 +814,7 @@ init_os (s)
     return;
 
   if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
-    einfo (_("%P%F: Illegal use of `%s' section"), DISCARD_SECTION_NAME);
+    einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
 
   new = ((section_userdata_type *)
         stat_alloc (sizeof (section_userdata_type)));
@@ -1136,12 +1141,10 @@ wild_doit (ptr, section, output, file)
       flagword flags;
 
       if (output->bfd_section == NULL)
-       {
-         init_os (output);
-         first = true;
-       }
-      else
-       first = false;
+       init_os (output);
+
+      first = ! output->bfd_section->linker_has_input;
+      output->bfd_section->linker_has_input = 1;
 
       /* Add a section reference to the list.  */
       new = new_stat (lang_input_section, ptr);
@@ -1176,8 +1179,22 @@ wild_doit (ptr, section, output, file)
       if (! first && (section->output_section->flags & SEC_READONLY) == 0)
        flags &= ~ SEC_READONLY;
 
+      /* Keep SEC_MERGE and SEC_STRINGS only if they are the same.  */
+      if (! first
+         && ((section->output_section->flags & (SEC_MERGE | SEC_STRINGS))
+             != (flags & (SEC_MERGE | SEC_STRINGS))
+             || ((flags & SEC_MERGE)
+                 && section->output_section->entsize != section->entsize)))
+       {
+         section->output_section->flags &= ~ (SEC_MERGE | SEC_STRINGS);
+         flags &= ~ (SEC_MERGE | SEC_STRINGS);
+       }
+
       section->output_section->flags |= flags;
 
+      if (flags & SEC_MERGE)
+       section->output_section->entsize = section->entsize;
+
       /* If SEC_READONLY is not set in the input section, then clear
          it from the output section.  */
       if ((section->flags & SEC_READONLY) == 0)
@@ -1409,14 +1426,15 @@ lookup_name (name)
       || search->filename == (const char *) NULL)
     return search;
 
-  load_symbols (search, (lang_statement_list_type *) NULL);
+  if (! load_symbols (search, (lang_statement_list_type *) NULL))
+    return NULL;
 
   return search;
 }
 
 /* Get the symbols for an input file.  */
 
-static void
+static boolean
 load_symbols (entry, place)
      lang_input_statement_type *entry;
      lang_statement_list_type *place;
@@ -1424,7 +1442,7 @@ load_symbols (entry, place)
   char **matching;
 
   if (entry->loaded)
-    return;
+    return true;
 
   ldfile_open_file (entry);
 
@@ -1433,8 +1451,14 @@ load_symbols (entry, place)
     {
       bfd_error_type err;
       lang_statement_list_type *hold;
-
+      boolean bad_load = true;
+      
       err = bfd_get_error ();
+
+      /* See if the emulation has some special knowledge.  */
+      if (ldemul_unrecognized_file (entry))
+       return true;
+
       if (err == bfd_error_file_ambiguously_recognized)
        {
          char **p;
@@ -1447,18 +1471,14 @@ load_symbols (entry, place)
        }
       else if (err != bfd_error_file_not_recognized
               || place == NULL)
-       einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd);
-
+         einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd);
+      else
+       bad_load = false;
+      
       bfd_close (entry->the_bfd);
       entry->the_bfd = NULL;
 
-      /* See if the emulation has some special knowledge.  */
-
-      if (ldemul_unrecognized_file (entry))
-       return;
-
       /* Try to interpret the file as a linker script.  */
-
       ldfile_open_command_file (entry->filename);
 
       hold = stat_ptr;
@@ -1471,11 +1491,11 @@ load_symbols (entry, place)
 
       stat_ptr = hold;
 
-      return;
+      return ! bad_load;
     }
 
   if (ldemul_recognized_file (entry))
-    return;
+    return true;
 
   /* We don't call ldlang_add_file for an archive.  Instead, the
      add_symbols entry point will call ldlang_add_file, via the
@@ -1495,32 +1515,46 @@ load_symbols (entry, place)
     case bfd_archive:
       if (entry->whole_archive)
        {
-         bfd *member = bfd_openr_next_archived_file (entry->the_bfd,
-                                                     (bfd *) NULL);
-         while (member != NULL)
+         bfd * member = NULL;
+         boolean loaded = true;
+
+         for (;;)
            {
+             member = bfd_openr_next_archived_file (entry->the_bfd, member);
+
+             if (member == NULL)
+               break;
+             
              if (! bfd_check_format (member, bfd_object))
-               einfo (_("%F%B: object %B in archive is not object\n"),
-                      entry->the_bfd, member);
+               {
+                 einfo (_("%F%B: member %B in archive is not an object\n"),
+                        entry->the_bfd, member);
+                 loaded = false;
+               }
+
              if (! ((*link_info.callbacks->add_archive_element)
                     (&link_info, member, "--whole-archive")))
                abort ();
+
              if (! bfd_link_add_symbols (member, &link_info))
-               einfo (_("%F%B: could not read symbols: %E\n"), member);
-             member = bfd_openr_next_archived_file (entry->the_bfd,
-                                                    member);
+               {
+                 einfo (_("%F%B: could not read symbols: %E\n"), member);
+                 loaded = false;
+               }
            }
 
-         entry->loaded = true;
-
-         return;
+         entry->loaded = loaded;
+         return loaded;
        }
+      break;
     }
 
-  if (! bfd_link_add_symbols (entry->the_bfd, &link_info))
+  if (bfd_link_add_symbols (entry->the_bfd, &link_info))
+    entry->loaded = true;
+  else
     einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd);
 
-  entry->loaded = true;
+  return entry->loaded;
 }
 
 /* Handle a wild statement.  SECTION or FILE or both may be NULL,
@@ -1677,7 +1711,8 @@ closest_target_match (target, data)
 
   /* Oh dear, we now have two potential candidates for a successful match.
      Compare their names and choose the better one.  */
-  if (name_compare (target->name, original->name) > name_compare (winner->name, original->name))
+  if (name_compare (target->name, original->name)
+      > name_compare (winner->name, original->name))
     winner = target;
 
   /* Keep on searching until wqe have checked them all.  */
@@ -1773,7 +1808,8 @@ open_output (name)
                  /* Try to find a target as similar as possible to
                     the default target, but which has the desired
                     endian characteristic.  */
-                 (void) bfd_search_for_target (closest_target_match, (PTR) target);
+                 (void) bfd_search_for_target (closest_target_match,
+                                               (PTR) target);
 
                  /* Oh dear - we could not find any targets that
                     satisfy our requirements.  */
@@ -1896,7 +1932,6 @@ open_input_bfds (s, force)
          if (s->input_statement.real)
            {
              lang_statement_list_type add;
-             bfd_error_handler_type pfn;
 
              s->input_statement.target = current_target;
 
@@ -1911,16 +1946,10 @@ open_input_bfds (s, force)
                                       bfd_archive))
                s->input_statement.loaded = false;
 
-             lang_list_init (& add);
-
-             /* We need to know if an error occurs whilst loading the 
-                symbols, since this means that a valid executable can
-                not be produced.  */
-             pfn = bfd_set_error_handler (record_bfd_errors);
-
-             load_symbols (&s->input_statement, &add);
+             lang_list_init (&add);
 
-             bfd_set_error_handler (pfn);
+             if (! load_symbols (&s->input_statement, &add))
+               config.make_executable = false;
 
              if (add.head != NULL)
                {
@@ -1981,7 +2010,7 @@ ldlang_add_undef (name)
   new->next = ldlang_undef_chain_list_head;
   ldlang_undef_chain_list_head = new;
 
-  new->name = buystring (name);
+  new->name = xstrdup (name);
 }
 
 /* Run through the list of undefineds created above and place them
@@ -2674,8 +2703,10 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax)
 }
 
 #define IGNORE_SECTION(bfd, s) \
-  (((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_LOAD)) != (SEC_ALLOC | SEC_LOAD)) \
+  (((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_LOAD))  \
+    != (SEC_ALLOC | SEC_LOAD))                                 \
    || bfd_section_size (bfd, s) == 0)
+
 /* Check to see if any allocated sections overlap with other allocated
    sections.  This can happen when the linker script specifically specifies
    the output section addresses of the two sections.  */
@@ -2686,7 +2717,6 @@ lang_check_section_addresses ()
   asection *s;
   unsigned opb = bfd_octets_per_byte (output_bfd);
 
-
   /* Scan all sections in the output list.  */
   for (s = output_bfd->sections; s != NULL; s = s->next)
     {
@@ -2797,8 +2827,9 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
        case lang_output_section_statement_enum:
          {
            bfd_vma after;
-           lang_output_section_statement_type *os = &s->output_section_statement;
+           lang_output_section_statement_type *os;
 
+           os = &s->output_section_statement;
            if (os->bfd_section == NULL)
              /* This section was never actually created.  */
              break;
@@ -2853,10 +2884,12 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
                        && ! link_info.relocateable
                        && strcmp (os->region->name, "*default*") == 0
                        && lang_memory_region_list != NULL
-                       && (strcmp (lang_memory_region_list->name, "*default*") != 0
+                       && (strcmp (lang_memory_region_list->name,
+                                   "*default*") != 0
                            || lang_memory_region_list->next != NULL))
                      einfo (_("%P: warning: no memory region specified for section `%s'\n"),
-                            bfd_get_section_name (output_bfd, os->bfd_section));
+                            bfd_get_section_name (output_bfd,
+                                                  os->bfd_section));
 
                    dot = os->region->current;
 
@@ -2865,7 +2898,8 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
                        bfd_vma olddot;
 
                        olddot = dot;
-                       dot = align_power (dot, os->bfd_section->alignment_power);
+                       dot = align_power (dot,
+                                          os->bfd_section->alignment_power);
 
                        if (dot != olddot && config.warn_section_align)
                          einfo (_("%P: warning: changing start of section %s by %u bytes\n"),
@@ -3182,9 +3216,9 @@ lang_do_assignments (s, output_section_statement, fill, dot)
 
        case lang_output_section_statement_enum:
          {
-           lang_output_section_statement_type *os =
-             &(s->output_section_statement);
+           lang_output_section_statement_type *os;
 
+           os = &(s->output_section_statement);
            if (os->bfd_section != NULL)
              {
                dot = os->bfd_section->vma;
@@ -3357,8 +3391,10 @@ lang_set_startof ()
       h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
       if (h != NULL && h->type == bfd_link_hash_undefined)
        {
-          unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-                                                       ldfile_output_machine);
+          unsigned opb;
+
+          opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+                                              ldfile_output_machine);
          h->type = bfd_link_hash_defined;
          if (s->_cooked_size != 0)
            h->u.def.value = s->_cooked_size / opb;
@@ -3445,53 +3481,6 @@ lang_finish ()
     }
 }
 
-
-/* This is the routine to handle BFD error messages.  */
-
-#ifdef ANSI_PROTOTYPES
-
-static void
-record_bfd_errors (const char *s, ...)
-{
-  va_list p;
-
-  einfo ("%P: ");
-
-  va_start (p, s);
-
-  vfprintf (stderr, s, p);
-
-  va_end (p);
-
-  fprintf (stderr, "\n");
-
-  einfo ("%X");
-}
-
-#else /* ! defined (ANSI_PROTOTYPES) */
-
-static void
-record_bfd_errors (va_alist)
-     va_dcl
-{
-  va_list p;
-  const char *s;
-
-  einfo ("%P: ");
-
-  va_start (p);
-
-  s = va_arg (p, const char *);
-  vfprintf (stderr, s, p);
-
-  va_end (p);
-
-  fprintf (stderr, "\n");
-
-  einfo ("%X");
-}
-
-#endif /* ! defined (ANSI_PROTOTYPES) */
 /* This is a small function used when we want to ignore errors from
    BFD.  */
 
@@ -4117,6 +4106,12 @@ lang_process ()
   if (command_line.gc_sections)
     lang_gc_sections ();
 
+  /* If there were any SEC_MERGE sections, finish their merging, so that
+     section sizes can be computed.  This has to be done after GC of sections,
+     so that GCed sections are not merged, but before assigning output
+     sections, since removing whole input sections is hard then.  */
+  bfd_merge_sections (output_bfd, &link_info);
+
   /* Size up the common data.  */
   lang_common ();
 
@@ -4238,8 +4233,9 @@ lang_section_start (name, address)
      const char *name;
      etree_type *address;
 {
-  lang_address_statement_type *ad = new_stat (lang_address_statement, stat_ptr);
+  lang_address_statement_type *ad;
 
+  ad = new_stat (lang_address_statement, stat_ptr);
   ad->section_name = name;
   ad->address = address;
 }
@@ -4632,9 +4628,7 @@ lang_record_phdrs ()
                          lang_final_phase_enum);
 
       if (! bfd_record_phdr (output_bfd, l->type,
-                            l->flags == NULL ? false : true,
-                            flags,
-                            l->at == NULL ? false : true,
+                            l->flags != NULL, flags, l->at != NULL,
                             at, l->filehdr, l->phdrs, c, secs))
        einfo (_("%F%P: bfd_record_phdr failed: %E\n"));
     }
@@ -5104,7 +5098,7 @@ lang_do_version_exports_section ()
       len = bfd_section_size (is->the_bfd, sec);
       contents = xmalloc (len);
       if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len))
-       einfo (_("%X%P: unable to read .exports section contents"), sec);
+       einfo (_("%X%P: unable to read .exports section contents\n"), sec);
 
       p = contents;
       while (p < contents + len)
This page took 0.039284 seconds and 4 git commands to generate.