* alpha-tdep.c (alpha_register_virtual_type): Use alpha-specific
[binutils-gdb.git] / ld / ldlang.c
index 66b4b13e20c3c7a5a26a7916b982f98cb7de0d8d..fccab0d681af0745030ce6f3e8f3e16d76017bcc 100644 (file)
@@ -1,6 +1,6 @@
 /* Linker command language support.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002
+   2001, 2002, 2003
    Free Software Foundation, Inc.
 
    This file is part of GLD, the Gnu Linker.
 #include "demangle.h"
 
 #ifndef offsetof
-#define offsetof(TYPE,MEMBER) ((size_t)&(((TYPE*)0)->MEMBER))
+#define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE*) 0)->MEMBER))
 #endif
 
-/* FORWARDS */
-static lang_statement_union_type *new_statement
-  PARAMS ((enum statement_enum, size_t, lang_statement_list_type *));
-
-/* LOCALS */
+/* Locals variables.  */
 static struct obstack stat_obstack;
 
 #define obstack_chunk_alloc xmalloc
@@ -65,6 +61,9 @@ static const char *output_target;
 static lang_statement_list_type statement_list;
 static struct lang_phdr *lang_phdr_list;
 
+/* Forward declarations.  */
+static lang_statement_union_type *new_statement
+  PARAMS ((enum statement_enum, size_t, lang_statement_list_type *));
 static void lang_for_each_statement_worker
   PARAMS ((void (*) (lang_statement_union_type *),
           lang_statement_union_type *));
@@ -201,7 +200,8 @@ static void os_region_check
           struct memory_region_struct *, etree_type *, bfd_vma));
 static bfd_vma lang_size_sections_1
   PARAMS ((lang_statement_union_type *, lang_output_section_statement_type *,
-          lang_statement_union_type **, fill_type *, bfd_vma, bfd_boolean *));
+          lang_statement_union_type **, fill_type *, bfd_vma, bfd_boolean *,
+          bfd_boolean));
 typedef void (*callback_t)
   PARAMS ((lang_wild_statement_type *, struct wildcard_list *, asection *,
           lang_input_statement_type *, PTR));
@@ -226,7 +226,7 @@ static int closest_target_match
 static char * get_first_input_target
   PARAMS ((void));
 
-/* EXPORTS */
+/* Exported variables.  */
 lang_output_section_statement_type *abs_output_section;
 lang_statement_list_type lang_output_section_statement;
 lang_statement_list_type *stat_ptr = &statement_list;
@@ -240,6 +240,7 @@ bfd_boolean lang_float_flag = FALSE;
 bfd_boolean delete_output_file_on_failure = FALSE;
 struct lang_nocrossrefs *nocrossref_list;
 struct unique_sections *unique_section_list;
+static bfd_boolean ldlang_sysrooted_script = FALSE;
 
 etree_type *base; /* Relocation base - or null */
 
@@ -523,7 +524,7 @@ new_statement (type, size, list)
    or prefix it with a -l etc.
 
    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)
+   they may, for example be split over several lines like foo.o(.text)
    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.  */
 
@@ -547,6 +548,7 @@ new_afile (name, file_type, target, add_to_list)
 
   lang_has_input_file = TRUE;
   p->target = target;
+  p->sysrooted = FALSE;
   switch (file_type)
     {
     case lang_input_file_is_symbols_only_enum:
@@ -582,6 +584,7 @@ new_afile (name, file_type, target, add_to_list)
       p->search_dirs_flag = TRUE;
       break;
     case lang_input_file_is_search_file_enum:
+      p->sysrooted = ldlang_sysrooted_script;
       p->filename = name;
       p->is_archive = FALSE;
       p->real = TRUE;
@@ -1304,7 +1307,7 @@ lang_add_section (ptr, section, output, file)
       if (section->alignment_power > output->bfd_section->alignment_power)
        output->bfd_section->alignment_power = section->alignment_power;
 
-      /* If supplied an aligment, then force it.  */
+      /* If supplied an alignment, then force it.  */
       if (output->section_alignment != -1)
        output->bfd_section->alignment_power = output->section_alignment;
 
@@ -1539,6 +1542,7 @@ load_symbols (entry, place)
       bfd_error_type err;
       lang_statement_list_type *hold;
       bfd_boolean bad_load = TRUE;
+      bfd_boolean save_ldlang_sysrooted_script;
 
       err = bfd_get_error ();
 
@@ -1570,12 +1574,15 @@ load_symbols (entry, place)
 
       hold = stat_ptr;
       stat_ptr = place;
+      save_ldlang_sysrooted_script = ldlang_sysrooted_script;
+      ldlang_sysrooted_script = entry->sysrooted;
 
       ldfile_assumed_script = TRUE;
       parser_input = input_script;
       yyparse ();
       ldfile_assumed_script = FALSE;
 
+      ldlang_sysrooted_script = save_ldlang_sysrooted_script;
       stat_ptr = hold;
 
       return ! bad_load;
@@ -1700,7 +1707,7 @@ stricpy (dest, src)
   *dest = 0;
 }
 
-/* Remove the first occurance of needle (if any) in haystack
+/* Remove the first occurrence of needle (if any) in haystack
    from haystack.  */
 
 static void
@@ -2144,7 +2151,7 @@ lang_place_undefineds ()
     }
 }
 
-/* Open input files and attatch to output sections.  */
+/* Open input files and attach to output sections.  */
 
 static void
 map_input_to_output_sections (s, target, output_section_statement)
@@ -2971,13 +2978,15 @@ os_region_check (os, region, tree, base)
 /* Set the sizes for all the output sections.  */
 
 static bfd_vma
-lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
+lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax,
+                     check_regions)
      lang_statement_union_type *s;
      lang_output_section_statement_type *output_section_statement;
      lang_statement_union_type **prev;
      fill_type *fill;
      bfd_vma dot;
      bfd_boolean *relax;
+     bfd_boolean check_regions;
 {
   unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
                                                ldfile_output_machine);
@@ -3041,20 +3050,37 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
 
                    /* If a loadable section is using the default memory
                       region, and some non default memory regions were
-                      defined, issue a warning.  */
+                      defined, issue an error message.  */
                    if ((bfd_get_section_flags (output_bfd, os->bfd_section)
                         & (SEC_ALLOC | SEC_LOAD)) != 0
                        && (bfd_get_section_flags (output_bfd, os->bfd_section)
                            & SEC_NEVER_LOAD) == 0
                        && ! link_info.relocateable
+                       && check_regions
                        && strcmp (os->region->name, "*default*") == 0
                        && lang_memory_region_list != NULL
                        && (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));
+                     {
+                       /* By default this is an error rather than just a
+                          warning because if we allocate the section to the
+                          default memory region we can end up creating an
+                          excessivly large binary, or even seg faulting when
+                          attmepting to perform a negative seek.  See
+                            http://sources.redhat.com/ml/binutils/2003-04/msg00423.html                         
+                          for an example of this.  This behaviour can be
+                          overridden by the using the --no-check-sections
+                          switch.  */
+                       if (command_line.check_section_addresses)
+                         einfo (_("%P%F: error: no memory region specified for loadable section `%s'\n"),
+                                bfd_get_section_name (output_bfd,
+                                                      os->bfd_section));
+                       else
+                         einfo (_("%P: warning: no memory region specified for loadable section `%s'\n"),
+                                bfd_get_section_name (output_bfd,
+                                                      os->bfd_section));
+                     }
 
                    dot = os->region->current;
 
@@ -3098,7 +3124,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
              }
 
            lang_size_sections_1 (os->children.head, os, &os->children.head,
-                                 os->fill, dot, relax);
+                                 os->fill, dot, relax, check_regions);
 
            /* Put the section within the requested block size, or
               align at the block boundary.  */
@@ -3139,9 +3165,10 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
              {
                os->region->current = dot;
 
-               /* Make sure the new address is within the region.  */
-               os_region_check (os, os->region, os->addr_tree,
-                                os->bfd_section->vma);
+               if (check_regions)
+                 /* Make sure the new address is within the region.  */
+                 os_region_check (os, os->region, os->addr_tree,
+                                  os->bfd_section->vma);
 
                /* If there's no load address specified, use the run
                   region as the load region.  */
@@ -3154,8 +3181,9 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
                    os->load_base = exp_intop (os->lma_region->current);
                    os->lma_region->current +=
                      os->bfd_section->_raw_size / opb;
-                   os_region_check (os, os->lma_region, NULL,
-                                    os->bfd_section->lma);
+                   if (check_regions)
+                     os_region_check (os, os->lma_region, NULL,
+                                      os->bfd_section->lma);
                  }
              }
          }
@@ -3165,7 +3193,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
          dot = lang_size_sections_1 (constructor_list.head,
                                      output_section_statement,
                                      &s->wild_statement.children.head,
-                                     fill, dot, relax);
+                                     fill, dot, relax, check_regions);
          break;
 
        case lang_data_statement_enum:
@@ -3229,7 +3257,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
          dot = lang_size_sections_1 (s->wild_statement.children.head,
                                      output_section_statement,
                                      &s->wild_statement.children.head,
-                                     fill, dot, relax);
+                                     fill, dot, relax, check_regions);
 
          break;
 
@@ -3327,7 +3355,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
          dot = lang_size_sections_1 (s->group_statement.children.head,
                                      output_section_statement,
                                      &s->group_statement.children.head,
-                                     fill, dot, relax);
+                                     fill, dot, relax, check_regions);
          break;
 
        default:
@@ -3344,19 +3372,21 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
 }
 
 bfd_vma
-lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
+lang_size_sections (s, output_section_statement, prev, fill, dot, relax,
+                   check_regions)
      lang_statement_union_type *s;
      lang_output_section_statement_type *output_section_statement;
      lang_statement_union_type **prev;
      fill_type *fill;
      bfd_vma dot;
      bfd_boolean *relax;
+     bfd_boolean check_regions;
 {
   bfd_vma result;
 
   exp_data_seg.phase = exp_dataseg_none;
   result = lang_size_sections_1 (s, output_section_statement, prev, fill,
-                                dot, relax);
+                                dot, relax, check_regions);
   if (exp_data_seg.phase == exp_dataseg_end_seen)
     {
       /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_END pair was seen, check whether
@@ -3372,7 +3402,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
        {
          exp_data_seg.phase = exp_dataseg_adjust;
          result = lang_size_sections_1 (s, output_section_statement, prev,
-                                        fill, dot, relax);
+                                        fill, dot, relax, check_regions);
        }
     }
 
@@ -3699,7 +3729,8 @@ lang_check ()
        file = file->input_statement.next)
     {
       input_bfd = file->input_statement.the_bfd;
-      compatible = bfd_arch_get_compatible (input_bfd, output_bfd);
+      compatible = bfd_arch_get_compatible (input_bfd, output_bfd,
+                                           command_line.accept_unknown_input_arch);
 
       /* In general it is not possible to perform a relocatable
         link between differing object formats when the input
@@ -3889,7 +3920,7 @@ lang_place_orphans ()
        {
          if (s->output_section == (asection *) NULL)
            {
-             /* This section of the file is not attatched, root
+             /* This section of the file is not attached, root
                 around for a sensible place for it to go.  */
 
              if (file->just_syms_flag)
@@ -4347,7 +4378,8 @@ lang_process ()
   /* Size up the sections.  */
   lang_size_sections (statement_list.head,
                      abs_output_section,
-                     &statement_list.head, 0, (bfd_vma) 0, NULL);
+                     &statement_list.head, 0, (bfd_vma) 0, NULL,
+                     command_line.relax ? FALSE : TRUE);
 
   /* Now run around and relax if we can.  */
   if (command_line.relax)
@@ -4376,9 +4408,27 @@ lang_process ()
          lang_size_sections (statement_list.head,
                              abs_output_section,
                              &statement_list.head, 0, (bfd_vma) 0,
-                             &relax_again);
+                             &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.relax_finalizing)
+           {
+             link_info.relax_finalizing = TRUE;
+             relax_again = TRUE;
+           }
        }
       while (relax_again);
+
+      /* Final extra sizing to report errors.  */
+      lang_reset_memory_regions ();
+      lang_do_assignments (statement_list.head,
+                          abs_output_section,
+                          (fill_type *) 0, (bfd_vma) 0);
+      lang_size_sections (statement_list.head,
+                         abs_output_section,
+                         & statement_list.head, 0, (bfd_vma) 0, 
+                         NULL, TRUE);
     }
 
   /* See if anything special should be done now we know how big
@@ -5250,6 +5300,7 @@ lang_register_vers_node (name, version, deps)
       || (lang_elf_version_info && lang_elf_version_info->name[0] == '\0'))
     {
       einfo (_("%X%P: anonymous version tag cannot be combined with other version tags\n"));
+      free (version);
       return;
     }