daily update
[binutils-gdb.git] / ld / ldlang.c
index 0feeb6924e8eb2b1ffc301ae756197a3b772f820..5cca71ff345564fbdd91bd8d4c75dfc90ce92588 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 */
 
@@ -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;
@@ -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;
@@ -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);
@@ -3047,6 +3056,7 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
                        && (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,
@@ -3098,7 +3108,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 +3149,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 +3165,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 +3177,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 +3241,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 +3339,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 +3356,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 +3386,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);
        }
     }
 
@@ -4348,7 +4362,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)
@@ -4377,9 +4392,19 @@ lang_process ()
          lang_size_sections (statement_list.head,
                              abs_output_section,
                              &statement_list.head, 0, (bfd_vma) 0,
-                             &relax_again);
+                             &relax_again, FALSE);
        }
       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
@@ -5251,6 +5276,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;
     }