* emultempl/hppaosf.em: Various fixes and support for linker stub
[deliverable/binutils-gdb.git] / ld / ldlang.c
index 588660ba58eef211ef8c92ffd03aea01caf7ba34..0fb4a1856dab4d445c43923c8a63d0ce1b12cf57 100644 (file)
@@ -1,5 +1,5 @@
 /* Linker command language support.
-   Copyright 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1991, 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of GLD, the Gnu Linker.
 
@@ -32,10 +32,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "ldmisc.h"
 #include "ldindr.h"
 #include "ldctor.h"
+
 /* FORWARDS */
 static void print_statements PARAMS ((void));
 static void print_statement PARAMS ((lang_statement_union_type *,
                                      lang_output_section_statement_type *));
+static lang_statement_union_type *new_statement PARAMS ((enum statement_enum,
+                                                        size_t,
+                                                        lang_statement_list_type*));
+
 
 /* LOCALS */
 static struct obstack stat_obstack;
@@ -69,7 +74,6 @@ boolean relaxing;
 lang_output_section_statement_type *abs_output_section;
 lang_statement_list_type *stat_ptr = &statement_list;
 lang_input_statement_type *script_file = 0;
-boolean option_longmap = false;
 lang_statement_list_type file_chain =
 {0};
 CONST char *entry_symbol = 0;
@@ -78,11 +82,11 @@ boolean lang_has_input_file = false;
 lang_output_section_statement_type *create_object_symbols = 0;
 boolean had_output_filename = false;
 boolean lang_float_flag = false;
+boolean delete_output_file_on_failure = false;
 
 /* IMPORTS */
 extern char *default_target;
 
-extern unsigned int undefined_global_sym_count;
 extern char *current_file;
 extern bfd *output_bfd;
 extern enum bfd_architecture ldfile_output_architecture;
@@ -92,8 +96,12 @@ extern ldsym_type *symbol_head;
 extern unsigned int commons_pending;
 extern args_type command_line;
 extern ld_config_type config;
-extern boolean had_script;
 extern boolean write_map;
+extern int g_switch_value;
+
+
+etree_type *base; /* Relocation base - or null */
+
 
 #ifdef __STDC__
 #define cat(a,b) a##b
@@ -110,34 +118,34 @@ extern boolean write_map;
 void lang_add_data PARAMS ((int type, union etree_union * exp));
 
 PTR
-DEFUN (stat_alloc, (size),
-       size_t size)
+stat_alloc (size)
+     size_t size;
 {
   return obstack_alloc (&stat_obstack, size);
 }
 static void
-DEFUN (print_size, (value),
-       size_t value)
+print_size (value)
+     size_t value;
 {
   fprintf (config.map_file, "%5x", (unsigned) value);
 }
 static void
-DEFUN (print_alignment, (value),
-       unsigned int value)
+print_alignment (value)
+     unsigned int value;
 {
   fprintf (config.map_file, "2**%1u", value);
 }
 static void
 DEFUN (print_fill, (value),
-       fill_type value)
+     fill_type value)
 {
   fprintf (config.map_file, "%04x", (unsigned) value);
 }
 
 
 static void
-DEFUN (print_section, (name),
-       CONST char *CONST name)
+print_section (name)
+     CONST char *CONST name;
 {
   fprintf (config.map_file, "%*s", -longest_section_name, name);
 }
@@ -148,9 +156,9 @@ DEFUN (print_section, (name),
 */
 
 static void
-DEFUN (lang_for_each_statement_worker, (func, s),
-       void (*func) ()AND
-       lang_statement_union_type * s)
+lang_for_each_statement_worker (func, s)
+     void (*func) ();
+     lang_statement_union_type *s;
 {
   for (; s != (lang_statement_union_type *) NULL; s = s->next)
     {
@@ -189,8 +197,8 @@ DEFUN (lang_for_each_statement_worker, (func, s),
 }
 
 void
-DEFUN (lang_for_each_statement, (func),
-       void (*func) ())
+lang_for_each_statement (func)
+     void (*func) ();
 {
   lang_for_each_statement_worker (func,
                                  statement_list.head);
@@ -198,8 +206,8 @@ DEFUN (lang_for_each_statement, (func),
 
 /*----------------------------------------------------------------------*/
 void
-DEFUN (lang_list_init, (list),
-       lang_statement_list_type * list)
+lang_list_init (list)
+     lang_statement_list_type *list;
 {
   list->head = (lang_statement_union_type *) NULL;
   list->tail = &list->head;
@@ -213,10 +221,10 @@ DEFUN (lang_list_init, (list),
 
 static
 lang_statement_union_type *
-DEFUN (new_statement, (type, size, list),
-       enum statement_enum type AND
-       bfd_size_type size AND
-       lang_statement_list_type * list)
+new_statement (type, size, list)
+     enum statement_enum type;
+     size_t size;
+     lang_statement_list_type * list;
 {
   lang_statement_union_type *new = (lang_statement_union_type *)
   stat_alloc (size);
@@ -239,10 +247,10 @@ DEFUN (new_statement, (type, size, list),
 
  */
 static lang_input_statement_type *
-DEFUN (new_afile, (name, file_type, target),
-       CONST char *CONST name AND
-       CONST lang_input_file_enum_type file_type AND
-       CONST char *CONST target)
+new_afile (name, file_type, target)
+     CONST char *CONST name;
+     CONST lang_input_file_enum_type file_type;
+     CONST char *CONST target;
 {
 
   lang_input_statement_type *p = new_stat (lang_input_statement,
@@ -310,13 +318,14 @@ DEFUN (new_afile, (name, file_type, target),
 }
 
 lang_input_statement_type *
-DEFUN (lang_add_input_file, (name, file_type, target),
-       CONST char *name AND
-       lang_input_file_enum_type file_type AND
-       CONST char *target)
+lang_add_input_file (name, file_type, target)
+     CONST char *name;
+     lang_input_file_enum_type file_type;
+     CONST char *target;
 {
   /* Look it up or build a new one */
   lang_has_input_file = true;
+
 #if 0
   lang_input_statement_type *p;
 
@@ -337,21 +346,21 @@ DEFUN (lang_add_input_file, (name, file_type, target),
 }
 
 void
-DEFUN (lang_add_keepsyms_file, (filename),
-       CONST char *filename)
+lang_add_keepsyms_file (filename)
+     CONST char *filename;
 {
   extern strip_symbols_type strip_symbols;
   if (keepsyms_file != 0)
-    info ("%X%P error: duplicated keep-symbols-file value\n");
+    info_msg ("%X%P: error: duplicated keep-symbols-file value\n");
   keepsyms_file = filename;
   if (strip_symbols != STRIP_NONE)
-    info ("%P `-keep-only-symbols-file' overrides `-s' and `-S'\n");
+    info_msg ("%P: `-keep-only-symbols-file' overrides `-s' and `-S'\n");
   strip_symbols = STRIP_SOME;
 }
 
 /* Build enough state so that the parser can build its tree */
 void
-DEFUN_VOID (lang_init)
+lang_init ()
 {
   obstack_begin (&stat_obstack, 1000);
 
@@ -386,8 +395,8 @@ static lang_memory_region_type *lang_memory_region_list;
 static lang_memory_region_type **lang_memory_region_list_tail = &lang_memory_region_list;
 
 lang_memory_region_type *
-DEFUN (lang_memory_region_lookup, (name),
-       CONST char *CONST name)
+lang_memory_region_lookup (name)
+     CONST char *CONST name;
 {
 
   lang_memory_region_type *p = lang_memory_region_list;
@@ -419,7 +428,7 @@ DEFUN (lang_memory_region_lookup, (name),
     *lang_memory_region_list_tail = new;
     lang_memory_region_list_tail = &new->next;
     new->origin = 0;
-    new->length = ~0;
+    new->length = ~(bfd_size_type)0;
     new->current = 0;
     new->had_full_message = false;
 
@@ -429,8 +438,8 @@ DEFUN (lang_memory_region_lookup, (name),
 
 
 lang_output_section_statement_type *
-DEFUN (lang_output_section_find, (name),
-       CONST char *CONST name)
+lang_output_section_find (name)
+     CONST char *CONST name;
 {
   lang_statement_union_type *u;
   lang_output_section_statement_type *lookup;
@@ -449,8 +458,8 @@ DEFUN (lang_output_section_find, (name),
 }
 
 lang_output_section_statement_type *
-DEFUN (lang_output_section_statement_lookup, (name),
-       CONST char *CONST name)
+lang_output_section_statement_lookup (name)
+     CONST char *CONST name;
 {
   lang_output_section_statement_type *lookup;
 
@@ -472,6 +481,12 @@ DEFUN (lang_output_section_statement_lookup, (name),
       lookup->addr_tree = (etree_type *) NULL;
       lang_list_init (&lookup->children);
 
+      lookup->memspec = (CONST char *) NULL;
+      lookup->flags = 0;
+      lookup->subsection_alignment = -1;
+      lookup->section_alignment = -1;
+      lookup->load_base = (union etree_union *) NULL;
+
       lang_statement_append (&lang_output_section_statement,
                             (lang_statement_union_type *) lookup,
                             &lookup->next);
@@ -481,8 +496,8 @@ DEFUN (lang_output_section_statement_lookup, (name),
 
 /*ARGSUSED*/
 static void
-DEFUN (print_flags, (ignore_flags),
-       int *ignore_flags)
+print_flags (ignore_flags)
+     int *ignore_flags;
 {
   fprintf (config.map_file, "(");
 #if 0
@@ -499,7 +514,7 @@ DEFUN (print_flags, (ignore_flags),
 }
 
 void
-DEFUN_VOID (lang_map)
+lang_map ()
 {
   lang_memory_region_type *m;
 
@@ -518,9 +533,9 @@ DEFUN_VOID (lang_map)
       fprintf (config.map_file, "%-16s", m->name);
       print_address (m->origin);
       print_space ();
-      print_address (m->length);
+      print_address ((bfd_vma)m->length);
       print_space ();
-      print_address (m->old_length);
+      print_address ((bfd_vma)m->old_length);
       print_space();
       print_address (m->current - m->origin);
       print_space();
@@ -541,8 +556,8 @@ DEFUN_VOID (lang_map)
  *
  */
 static void
-DEFUN (init_os, (s),
-       lang_output_section_statement_type * s)
+init_os (s)
+     lang_output_section_statement_type * s;
 {
 /*  asection *section = bfd_get_section_by_name(output_bfd, s->name);*/
   section_userdata_type *new =
@@ -554,7 +569,7 @@ DEFUN (init_os, (s),
     s->bfd_section = bfd_make_section (output_bfd, s->name);
   if (s->bfd_section == (asection *) NULL)
     {
-      einfo ("%P%F output format %s cannot represent section called %s\n",
+      einfo ("%P%F: output format %s cannot represent section called %s\n",
             output_bfd->xvec->name, s->name);
     }
   s->bfd_section->output_section = s->bfd_section;
@@ -582,11 +597,11 @@ DEFUN (init_os, (s),
 */
 
 static void
-DEFUN (wild_doit, (ptr, section, output, file),
-       lang_statement_list_type * ptr AND
-       asection * section AND
-       lang_output_section_statement_type * output AND
-       lang_input_statement_type * file)
+wild_doit (ptr, section, output, file)
+     lang_statement_list_type * ptr;
+     asection * section;
+     lang_output_section_statement_type * output;
+     lang_input_statement_type * file;
 {
   if (output->bfd_section == (asection *) NULL)
   {
@@ -615,7 +630,10 @@ DEFUN (wild_doit, (ptr, section, output, file),
     /* Be selective about what the output section inherits from the
        input section */
 
-    section->output_section->flags |= section->flags & ~SEC_NEVER_LOAD;
+    if ((section->flags & SEC_SHARED_LIBRARY) != 0)
+      section->output_section->flags |= section->flags;
+    else
+      section->output_section->flags |= section->flags & ~SEC_NEVER_LOAD;
 
     if (!output->loadable) 
     {
@@ -636,19 +654,19 @@ DEFUN (wild_doit, (ptr, section, output, file),
 }
 
 static asection *
-DEFUN (our_bfd_get_section_by_name, (abfd, section),
-       bfd * abfd AND
-       CONST char *section)
+our_bfd_get_section_by_name (abfd, section)
+     bfd * abfd;
+     CONST char *section;
 {
   return bfd_get_section_by_name (abfd, section);
 }
 
 static void
-DEFUN (wild_section, (ptr, section, file, output),
-       lang_wild_statement_type * ptr AND
-       CONST char *section AND
-       lang_input_statement_type * file AND
-       lang_output_section_statement_type * output)
+wild_section (ptr, section, file, output)
+     lang_wild_statement_type * ptr;
+     CONST char *section;
+     lang_input_statement_type * file;
+     lang_output_section_statement_type * output;
 {
   asection *s;
 
@@ -686,8 +704,8 @@ DEFUN (wild_section, (ptr, section, file, output),
    */
 static
 lang_input_statement_type *
-DEFUN (lookup_name, (name),
-       CONST char *CONST name)
+lookup_name (name)
+     CONST char *CONST name;
 {
   lang_input_statement_type *search;
 
@@ -720,12 +738,12 @@ DEFUN (lookup_name, (name),
 }
 
 static void
-DEFUN (wild, (s, section, file, target, output),
-       lang_wild_statement_type * s AND
-       CONST char *CONST section AND
-       CONST char *CONST file AND
-       CONST char *CONST target AND
-       lang_output_section_statement_type * output)
+wild (s, section, file, target, output)
+     lang_wild_statement_type * s;
+     CONST char *CONST section;
+     CONST char *CONST file;
+     CONST char *CONST target;
+     lang_output_section_statement_type * output;
 {
   lang_input_statement_type *f;
 
@@ -759,9 +777,10 @@ DEFUN (wild, (s, section, file, target, output),
 /*
   read in all the files
   */
+
 static bfd *
-DEFUN (open_output, (name),
-       CONST char *CONST name)
+open_output (name)
+     CONST char *CONST name;
 {
   extern unsigned long ldfile_output_machine;
   extern enum bfd_architecture ldfile_output_architecture;
@@ -783,17 +802,23 @@ DEFUN (open_output, (name),
     {
       if (bfd_error == invalid_target)
        {
-         einfo ("%P%F target %s not found\n", output_target);
+         einfo ("%P%F: target %s not found\n", output_target);
        }
-      einfo ("%P%F problem opening output file %s, %E\n", name);
+      einfo ("%P%F: cannot open output file %s: %E\n", name);
     }
 
+  delete_output_file_on_failure = 1;
+
   /*  output->flags |= D_PAGED;*/
 
-  bfd_set_format (output, bfd_object);
-  bfd_set_arch_mach (output,
-                    ldfile_output_architecture,
-                    ldfile_output_machine);
+  if (! bfd_set_format (output, bfd_object))
+    einfo ("%P%F:%s: can not make object file: %E\n", name);
+  if (! bfd_set_arch_mach (output,
+                          ldfile_output_architecture,
+                          ldfile_output_machine))
+    einfo ("%P%F:%s: can not set architecture: %E\n", name);
+
+  bfd_set_gp_size (output, g_switch_value);
   return output;
 }
 
@@ -801,8 +826,8 @@ DEFUN (open_output, (name),
 
 
 static void
-DEFUN (ldlang_open_output, (statement),
-       lang_statement_union_type * statement)
+ldlang_open_output (statement)
+     lang_statement_union_type * statement;
 {
   switch (statement->header.type)
     {
@@ -828,8 +853,8 @@ DEFUN (ldlang_open_output, (statement),
 }
 
 static void
-DEFUN (open_input_bfds, (statement),
-       lang_statement_union_type * statement)
+open_input_bfds (statement)
+     lang_statement_union_type * statement;
 {
   switch (statement->header.type)
     {
@@ -898,8 +923,8 @@ typedef struct ldlang_undef_chain_list
 static ldlang_undef_chain_list_type *ldlang_undef_chain_list_head;
 
 void
-DEFUN (ldlang_add_undef, (name),
-       CONST char *CONST name)
+ldlang_add_undef (name)
+     CONST char *CONST name;
 {
   ldlang_undef_chain_list_type *new =
   (ldlang_undef_chain_list_type
@@ -916,7 +941,7 @@ DEFUN (ldlang_add_undef, (name),
    script file.
 */
 static void
-DEFUN_VOID (lang_place_undefineds)
+lang_place_undefineds ()
 {
   ldlang_undef_chain_list_type *ptr = ldlang_undef_chain_list_head;
 
@@ -929,7 +954,7 @@ DEFUN_VOID (lang_place_undefineds)
       *def_ptr = def;
       def->name = ptr->name;
       def->section = &bfd_und_section;
-      Q_enter_global_ref (def_ptr, ptr->name);
+      enter_global_ref (def_ptr, ptr->name);
       ptr = ptr->next;
     }
 }
@@ -939,7 +964,7 @@ DEFUN_VOID (lang_place_undefineds)
  */
 
 static void
-DEFUN_VOID (lang_create_output_section_statements)
+lang_create_output_section_statements ()
 {
   lang_statement_union_type *os;
 
@@ -956,7 +981,7 @@ DEFUN_VOID (lang_create_output_section_statements)
 }
 
 static void
-DEFUN_VOID (lang_init_script_file)
+lang_init_script_file ()
 {
   script_file = lang_add_input_file ("command line",
                                     lang_input_file_is_fake_enum,
@@ -979,10 +1004,10 @@ DEFUN_VOID (lang_init_script_file)
 
 /* Open input files and attatch to output sections */
 static void
-DEFUN (map_input_to_output_sections, (s, target, output_section_statement),
-       lang_statement_union_type * s AND
-       CONST char *target AND
-       lang_output_section_statement_type * output_section_statement)
+map_input_to_output_sections (s, target, output_section_statement)
+     lang_statement_union_type * s;
+     CONST char *target;
+     lang_output_section_statement_type * output_section_statement;
 {
   for (; s != (lang_statement_union_type *) NULL; s = s->next)
     {
@@ -1031,7 +1056,7 @@ DEFUN (map_input_to_output_sections, (s, target, output_section_statement),
            os->addr_tree = s->address_statement.address;
            if (os->bfd_section == (asection *) NULL)
              {
-               einfo ("%P%F can't set the address of undefined section %s\n",
+               einfo ("%P%F: cannot set the address of undefined section %s\n",
                       s->address_statement.section_name);
              }
          }
@@ -1049,8 +1074,8 @@ DEFUN (map_input_to_output_sections, (s, target, output_section_statement),
 
 
 static void
-DEFUN (print_output_section_statement, (output_section_statement),
-       lang_output_section_statement_type * output_section_statement)
+print_output_section_statement (output_section_statement)
+     lang_output_section_statement_type * output_section_statement;
 {
   asection *section = output_section_statement->bfd_section;
 
@@ -1091,6 +1116,12 @@ DEFUN (print_output_section_statement, (output_section_statement),
     fprintf (config.map_file, "No attached output section");
   }
   print_nl ();
+  if (output_section_statement->load_base)
+    {
+      int b = exp_get_value_int(output_section_statement->load_base,
+                               0, "output base", lang_final_phase_enum);
+      printf("Output address   %08x\n", b);
+    }
   if (output_section_statement->section_alignment >= 0
       || output_section_statement->section_alignment >= 0) 
   {
@@ -1112,9 +1143,9 @@ DEFUN (print_output_section_statement, (output_section_statement),
 }
 
 static void
-DEFUN (print_assignment, (assignment, output_section),
-       lang_assignment_statement_type * assignment AND
-       lang_output_section_statement_type * output_section)
+print_assignment (assignment, output_section)
+     lang_assignment_statement_type * assignment;
+     lang_output_section_statement_type * output_section;
 {
   etree_value_type result;
 
@@ -1145,8 +1176,8 @@ DEFUN (print_assignment, (assignment, output_section),
 }
 
 static void
-DEFUN (print_input_statement, (statm),
-       lang_input_statement_type * statm)
+print_input_statement (statm)
+     lang_input_statement_type * statm;
 {
   if (statm->filename != (char *) NULL)
     {
@@ -1155,8 +1186,8 @@ DEFUN (print_input_statement, (statm),
 }
 
 static void
-DEFUN (print_symbol, (q),
-       asymbol * q)
+print_symbol (q)
+     asymbol * q;
 {
   print_section ("");
   fprintf (config.map_file, " ");
@@ -1164,12 +1195,14 @@ DEFUN (print_symbol, (q),
   fprintf (config.map_file, " ");
   print_address (outside_symbol_address (q));
   fprintf (config.map_file, "              %s", q->name ? q->name : " ");
+  if (q->flags & BSF_WEAK)
+    fprintf (config.map_file, " *weak*");
   print_nl ();
 }
 
 static void
-DEFUN (print_input_section, (in),
-       lang_input_section_type * in)
+print_input_section (in)
+     lang_input_section_type * in;
 {
   asection *i = in->section;
   int size = i->reloc_done ?
@@ -1225,7 +1258,8 @@ DEFUN (print_input_section, (in),
                    {
                      asymbol *q = *p;
 
-                     if (bfd_get_section (q) == i && q->flags & BSF_GLOBAL)
+                     if (bfd_get_section (q) == i
+                         && (q->flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
                        {
                          print_symbol (q);
                        }
@@ -1248,16 +1282,16 @@ DEFUN (print_input_section, (in),
 }
 
 static void
-DEFUN (print_fill_statement, (fill),
-       lang_fill_statement_type * fill)
+print_fill_statement (fill)
+     lang_fill_statement_type * fill;
 {
   fprintf (config.map_file, "FILL mask ");
   print_fill (fill->fill);
 }
 
 static void
-DEFUN (print_data_statement, (data),
-       lang_data_statement_type * data)
+print_data_statement (data)
+     lang_data_statement_type * data;
 {
 /*  bfd_vma value; */
   print_section ("");
@@ -1293,8 +1327,8 @@ DEFUN (print_data_statement, (data),
 
 
 static void
-DEFUN (print_padding_statement, (s),
-       lang_padding_statement_type * s)
+print_padding_statement (s)
+     lang_padding_statement_type * s;
 {
   print_section ("");
   print_space ();
@@ -1312,9 +1346,9 @@ DEFUN (print_padding_statement, (s),
 }
 
 static void
-DEFUN (print_wild_statement, (w, os),
-       lang_wild_statement_type * w AND
-       lang_output_section_statement_type * os)
+print_wild_statement (w, os)
+     lang_wild_statement_type * w;
+     lang_output_section_statement_type * os;
 {
   fprintf (config.map_file, " from ");
   if (w->filename != (char *) NULL)
@@ -1338,9 +1372,9 @@ DEFUN (print_wild_statement, (w, os),
 
 }
 static void
-DEFUN (print_statement, (s, os),
-       lang_statement_union_type * s AND
-       lang_output_section_statement_type * os)
+print_statement (s, os)
+     lang_statement_union_type * s;
+     lang_output_section_statement_type * os;
 {
   while (s)
     {
@@ -1403,7 +1437,7 @@ DEFUN (print_statement, (s, os),
 
 
 static void
-DEFUN_VOID (print_statements)
+print_statements ()
 {
   print_statement (statement_list.head,
                   abs_output_section);
@@ -1412,11 +1446,11 @@ DEFUN_VOID (print_statements)
 
 static bfd_vma
 DEFUN (insert_pad, (this_ptr, fill, power, output_section_statement, dot),
-       lang_statement_union_type ** this_ptr AND
-       fill_type fill AND
-       unsigned int power AND
-       asection * output_section_statement AND
-       bfd_vma dot)
+     lang_statement_union_type ** this_ptr AND
+     fill_type fill AND
+     unsigned int power AND
+     asection * output_section_statement AND
+     bfd_vma dot)
 {
   /* Align this section first to the
      input sections requirement, then
@@ -1458,13 +1492,12 @@ DEFUN (insert_pad, (this_ptr, fill, power, output_section_statement, dot),
 
 /* Work out how much this section will move the dot point */
 static bfd_vma
-DEFUN (size_input_section, (this_ptr, output_section_statement, fill,
-                           dot, relax),
-       lang_statement_union_type ** this_ptr AND
-       lang_output_section_statement_type * output_section_statement AND
-       unsigned short fill AND
-       bfd_vma dot AND
-       boolean relax)
+DEFUN (size_input_section, (this_ptr, output_section_statement, fill, dot, relax),
+     lang_statement_union_type ** this_ptr AND
+     lang_output_section_statement_type * output_section_statement AND
+     unsigned short fill AND
+     bfd_vma dot AND
+     boolean relax)
 {
   lang_input_section_type *is = &((*this_ptr)->input_section);
   asection *i = is->section;
@@ -1481,8 +1514,7 @@ DEFUN (size_input_section, (this_ptr, output_section_statement, fill,
       /* remember the largest size so we can malloc the largest area
          needed for the output stage. Only remember the size of sections
          which we will actually allocate  */
-      if (((i->flags &
-           (SEC_HAS_CONTENTS | SEC_ALLOC)) == (SEC_HAS_CONTENTS | SEC_ALLOC))
+      if ((i->flags & SEC_HAS_CONTENTS) != 0
          && (bfd_get_section_size_before_reloc (i) > largest_section))
        {
          largest_section = bfd_get_section_size_before_reloc (i);
@@ -1519,14 +1551,13 @@ DEFUN (size_input_section, (this_ptr, output_section_statement, fill,
 static boolean had_relax;
 
 static bfd_vma
-DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
-                           dot, relax),
-       lang_statement_union_type * s AND
-       lang_output_section_statement_type * output_section_statement AND
-       lang_statement_union_type ** prev AND
-       unsigned short fill AND
-       bfd_vma dot AND
-       boolean relax)
+DEFUN (lang_size_sections, (s, output_section_statement, prev, fill, dot, relax),
+     lang_statement_union_type * s AND
+     lang_output_section_statement_type * output_section_statement AND
+     lang_statement_union_type ** prev AND
+     unsigned short fill AND
+     bfd_vma dot AND
+     boolean relax)
 {
   /* Size up the sections from their constituent parts */
   for (; s != (lang_statement_union_type *) NULL; s = s->next)
@@ -1583,6 +1614,11 @@ DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
 
         dot = align_power (dot, os->bfd_section->alignment_power);
         bfd_set_section_vma (0, os->bfd_section, dot);
+        
+        if (os->load_base) {
+          os->bfd_section->lma 
+            = exp_get_value_int(os->load_base, 0,"load base", lang_final_phase_enum);
+        }
        }
 
 
@@ -1593,11 +1629,10 @@ DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
        /* Ignore the size of the input sections, use the vma and size to */
        /* align against */
 
-
-       after = ALIGN (os->bfd_section->vma +
-                     os->bfd_section->_raw_size,
-                     os->block_value);
-
+       after = ALIGN_N (os->bfd_section->vma +
+                       os->bfd_section->_raw_size,
+                       /* The coercion here is important, see ld.h.  */
+                       (bfd_vma) os->block_value);
 
        os->bfd_section->_raw_size = after - os->bfd_section->vma;
        dot = os->bfd_section->vma + os->bfd_section->_raw_size;
@@ -1609,18 +1644,18 @@ DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
        {
         os->region->current = dot;
         /* Make sure this isn't silly */
-        if (os->region->current >
-            os->region->origin +
-            os->region->length)
-        {
-          einfo ("%X%P: Region %s is full (%B section %s)\n",
-                 os->region->name,
-                 os->bfd_section->owner,
-                 os->bfd_section->name);
-          /* Reset the region pointer */
-          os->region->current = 0;
+        if (( os->region->current
+              > os->region->origin + os->region->length)
+            || ( os->region->origin > os->region->current ))
+          {
+            einfo ("%X%P: region %s is full (%B section %s)\n",
+                   os->region->name,
+                   os->bfd_section->owner,
+                   os->bfd_section->name);
+            /* Reset the region pointer */
+            os->region->current = 0;
 
-        }
+          }
 
        }
      }
@@ -1753,10 +1788,10 @@ DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
 
 static bfd_vma
 DEFUN (lang_do_assignments, (s, output_section_statement, fill, dot),
-       lang_statement_union_type * s AND
-       lang_output_section_statement_type * output_section_statement AND
-       unsigned short fill AND
-       bfd_vma dot)
+     lang_statement_union_type * s AND
+     lang_output_section_statement_type * output_section_statement AND
+     unsigned short fill AND
+     bfd_vma dot)
 {
 
   for (; s != (lang_statement_union_type *) NULL; s = s->next)
@@ -1804,7 +1839,7 @@ DEFUN (lang_do_assignments, (s, output_section_statement, fill, dot),
                                   lang_final_phase_enum, dot, &dot);
            s->data_statement.value = value.value;
            if (value.valid == false)
-             einfo ("%F%P: Invalid data statement\n");
+             einfo ("%F%P: invalid data statement\n");
          }
          switch (s->data_statement.type)
            {
@@ -1859,9 +1894,8 @@ DEFUN (lang_do_assignments, (s, output_section_statement, fill, dot),
 
 
 static void
-DEFUN_VOID (lang_relocate_globals)
+lang_relocate_globals ()
 {
-
   /*
     Each ldsym_type maintains a chain of pointers to asymbols which
     references the definition.  Replace each pointer to the referenence
@@ -1874,6 +1908,10 @@ DEFUN_VOID (lang_relocate_globals)
   {
     asymbol *it;
 
+    /* Skip indirect symbols.  */
+    if (lgs->flags & SYM_INDIRECT)
+      continue;
+
     if (lgs->sdefs_chain)
       {
        it = *(lgs->sdefs_chain);
@@ -1916,7 +1954,7 @@ DEFUN_VOID (lang_relocate_globals)
 
 
 static void
-DEFUN_VOID (lang_finish)
+lang_finish ()
 {
   ldsym_type *lgs;
   int warn = config.relocateable_output != true;
@@ -1938,14 +1976,14 @@ DEFUN_VOID (lang_finish)
   }
   else
   {
-    /* Can't find anything reasonable,
+    /* Cannot find anything reasonable,
        use the first address in the text section
        */
     asection *ts = bfd_get_section_by_name (output_bfd, ".text");
     if (ts)
     {
       if (warn)
-       einfo ("%P: Warning, can't find entry symbol %s, defaulting to %V\n",
+       einfo ("%P: warning: cannot find entry symbol %s, defaulting to %V\n",
              entry_symbol, ts->vma);
 
       bfd_set_start_address (output_bfd, ts->vma);
@@ -1953,7 +1991,7 @@ DEFUN_VOID (lang_finish)
     else 
     {
       if (warn)
-       einfo ("%P: Warning, can't find entry symbol %s, not setting start address\n",
+       einfo ("%P: warning: cannot find entry symbol %s, not setting start address\n",
              entry_symbol);
     }
   }
@@ -1962,7 +2000,7 @@ DEFUN_VOID (lang_finish)
 /* By now we know the target architecture, and we may have an */
 /* ldfile_output_machine_name */
 static void
-DEFUN_VOID (lang_check)
+lang_check ()
 {
   lang_statement_union_type *file;
   bfd *input_bfd;
@@ -1994,13 +2032,15 @@ DEFUN_VOID (lang_check)
       else
        {
 
-         info ("%P: warning, %s architecture of input file `%B' incompatible with %s output\n",
+         info_msg ("%P: warning: %s architecture of input file `%B' is incompatible with %s output\n",
                bfd_printable_name (input_bfd), input_bfd,
                bfd_printable_name (output_bfd));
 
-         bfd_set_arch_mach (output_bfd,
-                            input_architecture,
-                            input_machine);
+         if (! bfd_set_arch_mach (output_bfd,
+                                  input_architecture,
+                                  input_machine))
+           einfo ("%P%F:%s: can't set architecture: %E\n",
+                  bfd_get_filename (output_bfd));
        }
 
     }
@@ -2015,7 +2055,7 @@ DEFUN_VOID (lang_check)
   */
 
 static void
-DEFUN_VOID (lang_common)
+lang_common ()
 {
   ldsym_type *lgs;
   size_t power;
@@ -2093,14 +2133,16 @@ DEFUN_VOID (lang_common)
                                                            name);
                          /* BFD backend must provide this section. */
                          if (newsec == (asection *) NULL)
-                           einfo ("%P%F: No output section %s", name);
+                           einfo ("%P%F: no output section %s", name);
                          com->section = newsec;
                        }
 
                      /*  Fix the size of the common section */
 
                      com->section->_raw_size =
-                       ALIGN (com->section->_raw_size, align);
+                       ALIGN_N (com->section->_raw_size,
+                                /* The coercion here is important, see ld.h.  */
+                                (bfd_vma) align);
 
                      /* Remember if this is the biggest alignment ever seen */
                      if (power_of_two > com->section->alignment_power)
@@ -2143,7 +2185,7 @@ into the statement tree.
 */
 
 static void
-DEFUN_VOID (lang_place_orphans)
+lang_place_orphans ()
 {
   lang_input_statement_type *file;
 
@@ -2173,7 +2215,7 @@ DEFUN_VOID (lang_place_orphans)
                      if (default_common_section ==
                          (lang_output_section_statement_type *) NULL)
                        {
-                         info ("%P: No [COMMON] command, defaulting to .bss\n");
+                         info_msg ("%P: no [COMMON] command, defaulting to .bss\n");
 
                          default_common_section =
                            lang_output_section_statement_lookup (".bss");
@@ -2197,9 +2239,9 @@ DEFUN_VOID (lang_place_orphans)
 
 
 void
-DEFUN (lang_set_flags, (ptr, flags),
-       int *ptr AND
-       CONST char *flags)
+lang_set_flags (ptr, flags)
+     int *ptr;
+     CONST char *flags;
 {
   boolean state = false;
 
@@ -2229,7 +2271,7 @@ DEFUN (lang_set_flags, (ptr, flags),
          /*      ptr->flag_loadable= state;*/
          break;
        default:
-         einfo ("%P%F illegal syntax in flags\n");
+         einfo ("%P%F: invalid syntax in flags\n");
          break;
        }
       flags++;
@@ -2239,8 +2281,8 @@ DEFUN (lang_set_flags, (ptr, flags),
 
 
 void
-DEFUN (lang_for_each_file, (func),
-       void (*func) PARAMS ((lang_input_statement_type *)))
+lang_for_each_file (func)
+     void (*func) PARAMS ((lang_input_statement_type *));
 {
   lang_input_statement_type *f;
 
@@ -2254,8 +2296,8 @@ DEFUN (lang_for_each_file, (func),
 
 
 void
-DEFUN (lang_for_each_input_section, (func),
-       void (*func) PARAMS ((bfd * ab, asection * as)))
+lang_for_each_input_section (func)
+     void (*func) PARAMS ((bfd * ab, asection * as));
 {
   lang_input_statement_type *f;
 
@@ -2277,8 +2319,8 @@ DEFUN (lang_for_each_input_section, (func),
 
 
 void
-DEFUN (ldlang_add_file, (entry),
-       lang_input_statement_type * entry)
+ldlang_add_file (entry)
+     lang_input_statement_type * entry;
 {
 
   lang_statement_append (&file_chain,
@@ -2287,8 +2329,8 @@ DEFUN (ldlang_add_file, (entry),
 }
 
 void
-DEFUN (lang_add_output, (name),
-       CONST char *name)
+lang_add_output (name)
+     CONST char *name;
 {
   lang_output_statement_type *new = new_stat (lang_output_statement,
                                              stat_ptr);
@@ -2314,18 +2356,16 @@ static int topower(x)
   return 0;
 }
 void
-DEFUN (lang_enter_output_section_statement,
-       (output_section_statement_name,
-       address_exp,
-       flags,
-       block_value, 
-       align, subalign),
-       char *output_section_statement_name AND
-       etree_type * address_exp AND
-       int flags AND
-       bfd_vma block_value AND
-       etree_type *align AND
-       etree_type *subalign)
+lang_enter_output_section_statement (output_section_statement_name,
+                                    address_exp, flags, block_value,
+                                    align, subalign, base)
+     char *output_section_statement_name;
+     etree_type * address_exp;
+     int flags;
+     bfd_vma block_value;
+     etree_type *align;
+     etree_type *subalign;
+     etree_type *base;
 {
   lang_output_section_statement_type *os;
 
@@ -2361,10 +2401,13 @@ DEFUN (lang_enter_output_section_statement,
   os->section_alignment = topower(
    exp_get_value_int(align, -1,
                     "section alignment", 0));
+
+  os->load_base = base;
 }
 
+
 void
-DEFUN_VOID (lang_final)
+lang_final ()
 {
   if (had_output_filename == false)
     {
@@ -2376,7 +2419,7 @@ DEFUN_VOID (lang_final)
 
 /* Reset the current counters in the regions */
 static void
-DEFUN_VOID (reset_memory_regions)
+reset_memory_regions ()
 {
   lang_memory_region_type *p = lang_memory_region_list;
 
@@ -2384,7 +2427,7 @@ DEFUN_VOID (reset_memory_regions)
        p != (lang_memory_region_type *) NULL;
        p = p->next)
     {
-      p->old_length = p->current - p->origin;
+      p->old_length = (bfd_size_type) (p->current - p->origin);
       p->current = p->origin;
     }
 }
@@ -2393,9 +2436,9 @@ DEFUN_VOID (reset_memory_regions)
 
 asymbol *
 DEFUN (create_symbol, (name, flags, section),
-       CONST char *name AND
-       flagword flags AND
-       asection * section)
+     CONST char *name AND
+     flagword flags AND
+     asection * section)
 {
   extern lang_input_statement_type *script_file;
   asymbol **def_ptr = (asymbol **) stat_alloc ((bfd_size_type) (sizeof (asymbol **)));
@@ -2407,18 +2450,13 @@ DEFUN (create_symbol, (name, flags, section),
   def->flags = flags;
   def->section = section;
   *def_ptr = def;
-  Q_enter_global_ref (def_ptr, name);
+  enter_global_ref (def_ptr, name);
   return def;
 }
 
 void
-DEFUN_VOID (lang_process)
+lang_process ()
 {
-
-  if (had_script == false)
-    {
-      parse_line (ldemul_get_script (), 1);
-    }
   lang_reasonable_defaults ();
   current_target = default_target;
 
@@ -2427,6 +2465,8 @@ DEFUN_VOID (lang_process)
      file */
   lang_create_output_section_statements ();
 
+  ldemul_create_output_section_statements ();
+
   /* Create a dummy bfd for the script */
   lang_init_script_file ();
 
@@ -2475,50 +2515,41 @@ DEFUN_VOID (lang_process)
   /* 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 */
+      /* 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,
                          &(statement_list.head), 0, (bfd_vma) 0, false);
 
+      /* Move the global symbols around so the second pass of relaxing
+        can see them.  */
+      lang_relocate_globals ();
 
+      reset_memory_regions ();
 
-  /* Move the global symbols around so the second pass of relaxing can
-     see them */
-  lang_relocate_globals ();
-
-  reset_memory_regions ();
-
-  /* Do all the assignments, now that we know the final restingplaces
-     of all the symbols */
-
-  lang_do_assignments (statement_list.head,
-                      abs_output_section,
-                      0, (bfd_vma) 0);
+      /* Do all the assignments, now that we know the final resting
+        places of all the symbols.  */
 
+      lang_do_assignments (statement_list.head,
+                          abs_output_section,
+                          0, (bfd_vma) 0);
 
       /* Perform another relax pass - this time we know where the
-        globals are, so can make better guess */
+        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);
-
-
-
     }
-
   else
     {
-      /* Size up the sections */
+      /* Size up the sections */
       lang_size_sections (statement_list.head,
                          abs_output_section,
                          &(statement_list.head), 0, (bfd_vma) 0, false);
-
     }
 
-
   /* See if anything special should be done now we know how big
-     everything is */
+     everything is */
   ldemul_after_allocation ();
 
   /* Do all the assignments, now that we know the final restingplaces
@@ -2537,15 +2568,21 @@ DEFUN_VOID (lang_process)
   lang_check ();
 
   /* Final stuffs */
+
+  ldemul_finish ();
+  /* Size up the sections.  */
+  lang_size_sections (statement_list.head,
+                     abs_output_section,
+                     &(statement_list.head), 0, (bfd_vma) 0, false);
   lang_finish ();
 }
 
 /* EXPORTED TO YACC */
 
 void
-DEFUN (lang_add_wild, (section_name, filename),
-       CONST char *CONST section_name AND
-       CONST char *CONST filename)
+lang_add_wild (section_name, filename)
+     CONST char *CONST section_name;
+     CONST char *CONST filename;
 {
   lang_wild_statement_type *new = new_stat (lang_wild_statement,
                                            stat_ptr);
@@ -2564,9 +2601,9 @@ DEFUN (lang_add_wild, (section_name, filename),
 }
 
 void
-DEFUN (lang_section_start, (name, address),
-       CONST char *name AND
-       etree_type * address)
+lang_section_start (name, address)
+     CONST char *name;
+     etree_type * address;
 {
   lang_address_statement_type *ad = new_stat (lang_address_statement, stat_ptr);
 
@@ -2575,15 +2612,15 @@ DEFUN (lang_section_start, (name, address),
 }
 
 void
-DEFUN (lang_add_entry, (name),
-       CONST char *name)
+lang_add_entry (name)
+     CONST char *name;
 {
   entry_symbol = name;
 }
 
 void
-DEFUN (lang_add_target, (name),
-       CONST char *name)
+lang_add_target (name)
+     CONST char *name;
 {
   lang_target_statement_type *new = new_stat (lang_target_statement,
                                              stat_ptr);
@@ -2593,8 +2630,8 @@ DEFUN (lang_add_target, (name),
 }
 
 void
-DEFUN (lang_add_map, (name),
-       CONST char *name)
+lang_add_map (name)
+     CONST char *name;
 {
   while (*name)
     {
@@ -2609,8 +2646,8 @@ DEFUN (lang_add_map, (name),
 }
 
 void
-DEFUN (lang_add_fill, (exp),
-       int exp)
+lang_add_fill (exp)
+     int exp;
 {
   lang_fill_statement_type *new = new_stat (lang_fill_statement,
                                            stat_ptr);
@@ -2619,9 +2656,9 @@ DEFUN (lang_add_fill, (exp),
 }
 
 void
-DEFUN (lang_add_data, (type, exp),
-       int type AND
-       union etree_union *exp)
+lang_add_data (type, exp)
+     int type;
+     union etree_union *exp;
 {
 
   lang_data_statement_type *new = new_stat (lang_data_statement,
@@ -2633,8 +2670,8 @@ DEFUN (lang_add_data, (type, exp),
 }
 
 void
-DEFUN (lang_add_assignment, (exp),
-       etree_type * exp)
+lang_add_assignment (exp)
+     etree_type * exp;
 {
   lang_assignment_statement_type *new = new_stat (lang_assignment_statement,
                                                  stat_ptr);
@@ -2643,19 +2680,19 @@ DEFUN (lang_add_assignment, (exp),
 }
 
 void
-DEFUN (lang_add_attribute, (attribute),
-       enum statement_enum attribute)
+lang_add_attribute (attribute)
+     enum statement_enum attribute;
 {
   new_statement (attribute, sizeof (lang_statement_union_type), stat_ptr);
 }
 
 void
-DEFUN (lang_startup, (name),
-       CONST char *name)
+lang_startup (name)
+     CONST char *name;
 {
   if (startup_file != (char *) NULL)
     {
-      einfo ("%P%FMultiple STARTUP files\n");
+      einfo ("%P%Fmultiple STARTUP files\n");
     }
   first_file->filename = name;
   first_file->local_sym_name = name;
@@ -2664,16 +2701,16 @@ DEFUN (lang_startup, (name),
 }
 
 void
-DEFUN (lang_float, (maybe),
-       boolean maybe)
+lang_float (maybe)
+     boolean maybe;
 {
   lang_float_flag = maybe;
 }
 
 void
-DEFUN (lang_leave_output_section_statement, (fill, memspec),
-       bfd_vma fill AND
-       CONST char *memspec)
+lang_leave_output_section_statement (fill, memspec)
+     bfd_vma fill;
+     CONST char *memspec;
 {
   current_section->fill = fill;
   current_section->region = lang_memory_region_lookup (memspec);
@@ -2695,9 +2732,9 @@ DEFUN (lang_leave_output_section_statement, (fill, memspec),
  If the symbol already exists, then do nothing.
 */
 void
-DEFUN (lang_abs_symbol_at_beginning_of, (section, name),
-       CONST char *section AND
-       CONST char *name)
+lang_abs_symbol_at_beginning_of (section, name)
+     CONST char *section;
+     CONST char *name;
 {
   if (ldsym_undefined (name))
     {
@@ -2724,9 +2761,9 @@ DEFUN (lang_abs_symbol_at_beginning_of, (section, name),
  If the symbol already exists, then do nothing.
 */
 void
-DEFUN (lang_abs_symbol_at_end_of, (section, name),
-       CONST char *section AND
-       CONST char *name)
+lang_abs_symbol_at_end_of (section, name)
+     CONST char *section;
+     CONST char *name;
 {
   if (ldsym_undefined (name))
     {
@@ -2749,19 +2786,21 @@ DEFUN (lang_abs_symbol_at_end_of, (section, name),
 }
 
 void
-DEFUN (lang_statement_append, (list, element, field),
-       lang_statement_list_type * list AND
-       lang_statement_union_type * element AND
-       lang_statement_union_type ** field)
+lang_statement_append (list, element, field)
+     lang_statement_list_type * list;
+     lang_statement_union_type * element;
+     lang_statement_union_type ** field;
 {
   *(list->tail) = element;
   list->tail = field;
 }
 
-/* Set the output format type */
+/* Set the output format type.  -oformat overrides scripts.  */
 void
-DEFUN (lang_add_output_format, (format),
-       CONST char *format)
+lang_add_output_format (format, from_script)
+     CONST char *format;
+     int from_script;
 {
-  output_target = format;
+  if (!from_script || output_target == NULL)
+    output_target = format;
 }
This page took 0.041203 seconds and 4 git commands to generate.