Merging from VMS port. Doc to follow..
authorSteve Chamberlain <sac@cygnus>
Fri, 24 Jan 1992 18:41:32 +0000 (18:41 +0000)
committerSteve Chamberlain <sac@cygnus>
Fri, 24 Jan 1992 18:41:32 +0000 (18:41 +0000)
ld/config.h
ld/ldexp.c
ld/ldgram.y
ld/ldlang.c
ld/ldlang.h
ld/ldmain.c
ld/ldmisc.c
ld/ldsym.c

index 838276b..50cc3ca 100644 (file)
 #define EBMON29K_EMULATION_NAME "ebmon29k"
 #define GLDI386AOUT_EMULATION_NAME "gldi386aout"
 /* Otherwise default to this emulation */
-#ifndef DEFAULT_EMULATION
-#ifdef GNU960
-#define DEFAULT_EMULATION GLD960_EMULATION_NAME
-#else
-#define DEFAULT_EMULATION GLD68K_EMULATION_NAME
-#endif
-#endif /* DEFAULT_EMULATION */
+
+#define DEFAULT_EMULATION LNK960_EMULATION_NAME
+
 
 /* Look in this variable for a target format */
 #define TARGET_ENVIRON "GNUTARGET"
@@ -47,6 +43,7 @@
 #define GLD_TARGET "a.out-sunos-big"
 #define GLD68K_TARGET "a.out-sunos-big"
 #define LNK960_TARGET "coff-Intel-big"
+#define LNK960_TARGET_LITTLE "coff-Intel-little"
 #define GLD960_TARGET "b.out.big"
 #define VANILLA_TARGET "a.out-sunos-big"
 #define GLDM88KBCS_TARGET "m88kbcs"
index c91af29..849f235 100644 (file)
@@ -1,10 +1,12 @@
-/* Copyright (C) 1991 Free Software Foundation, Inc.
+/* This module handles expression trees.
+Copyright (C) 1991 Free Software Foundation, Inc.
+Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com).
 
 This file is part of GLD, the Gnu Linker.
 
 GLD is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GLD is distributed in the hope that it will be useful,
@@ -17,25 +19,23 @@ along with GLD; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /*
-   $Id$ 
-*/
+This module is in charge of working out the contents of expressions.
 
-/*
- * Written by Steve Chamberlain
- * steve@cygnus.com
- *
- * This module handles expression trees.
- */
+It has to keep track of the relative/absness of a symbol etc. This is
+done by keeping all values in a struct (an etree_value_type) which
+contains a value, a section to which it is relative and a valid bit.
+
+*/
 
 
-#include "sysdep.h"
 #include "bfd.h"
+#include "sysdep.h"
 
 #include "ld.h"
 #include "ldmain.h"
 #include "ldmisc.h"
 #include "ldexp.h"
-#include "ldgram.tab.h"
+#include "ldgram.h"
 #include "ldsym.h"
 #include "ldlang.h"
 
@@ -43,7 +43,7 @@ extern char *output_filename;
 extern unsigned int undefined_global_sym_count;
 extern unsigned int defined_global_sym_count;
 extern bfd *output_bfd;
-extern size_t largest_section;
+extern bfd_size_type largest_section;
 extern lang_statement_list_type file_chain;
 extern args_type command_line;
 extern ld_config_type config;
@@ -55,55 +55,55 @@ extern bfd_vma print_dot;
 
 
 static void
-exp_print_token(outfile, code)
-FILE *outfile;
-token_code_type code;
+DEFUN(exp_print_token,(outfile, code),
+      FILE *outfile AND
+      token_code_type code)
 {
   static struct  {
     token_code_type code;
     char *name;
   } table[] =
-    {
-      INT,     "int",
-      NAME,"NAME",
-      PLUSEQ,"+=",
-      MINUSEQ,"-=",
-      MULTEQ,"*=",
-      DIVEQ,"/=",
-      LSHIFTEQ,"<<=",
-      RSHIFTEQ,">>=",
-      ANDEQ,"&=",
-      OREQ,"|=",
-      OROR,"||",
-      ANDAND,"&&",
-      EQ,"==",
-      NE,"!=",
-      LE,"<=",
-      GE,">=",
-      LSHIFT,"<<",
-      RSHIFT,">>=",
-      ALIGN_K,"ALIGN",
-      BLOCK,"BLOCK",
-      SECTIONS,"SECTIONS",
-      SIZEOF_HEADERS,"SIZEOF_HEADERS",
-      NEXT,"NEXT",
-      SIZEOF,"SIZEOF",
-      ADDR,"ADDR",
-      MEMORY,"MEMORY",
-
-
-
-
-
-      DEFINED,"DEFINED",
-      TARGET_K,"TARGET",
-      SEARCH_DIR,"SEARCH_DIR",
-      MAP,"MAP",
-      LONG,"LONG",
-      SHORT,"SHORT",
-      BYTE,"BYTE",
-      ENTRY,"ENTRY",
-    0,(char *)NULL} ;
+      {
+       INT,    "int",
+       NAME,"NAME",
+       PLUSEQ,"+=",
+       MINUSEQ,"-=",
+       MULTEQ,"*=",
+       DIVEQ,"/=",
+       LSHIFTEQ,"<<=",
+       RSHIFTEQ,">>=",
+       ANDEQ,"&=",
+       OREQ,"|=",
+       OROR,"||",
+       ANDAND,"&&",
+       EQ,"==",
+       NE,"!=",
+       LE,"<=",
+       GE,">=",
+       LSHIFT,"<<",
+       RSHIFT,">>=",
+       ALIGN_K,"ALIGN",
+       BLOCK,"BLOCK",
+       SECTIONS,"SECTIONS",
+       SIZEOF_HEADERS,"SIZEOF_HEADERS",
+       NEXT,"NEXT",
+       SIZEOF,"SIZEOF",
+       ADDR,"ADDR",
+       MEMORY,"MEMORY",
+
+
+
+
+
+       DEFINED,"DEFINED",
+       TARGET_K,"TARGET",
+       SEARCH_DIR,"SEARCH_DIR",
+       MAP,"MAP",
+       LONG,"LONG",
+       SHORT,"SHORT",
+       BYTE,"BYTE",
+       ENTRY,"ENTRY",
+       0,(char *)NULL} ;
 
 
 
@@ -119,8 +119,8 @@ token_code_type code;
 }
 
 static void 
-make_abs(ptr)
-etree_value_type *ptr;
+DEFUN(make_abs,(ptr),
+      etree_value_type *ptr)
 {
   if (ptr->section != (lang_output_section_statement_type *)NULL) {
     asection *s = ptr->section->bfd_section;
@@ -129,9 +129,10 @@ etree_value_type *ptr;
   }
 
 }
+
 static
-etree_value_type new_abs(value)
-bfd_vma value;
+DEFUN(etree_value_type new_abs,(value),
+      bfd_vma value)
 {
   etree_value_type new;
   new.valid = true;
@@ -147,17 +148,18 @@ DEFUN(check, (os, name, op),
       CONST char *op)
 {
   if (os == (lang_output_section_statement_type *)NULL) {
-    info("%F%P %s uses undefined section %s\n", op, name);
+    einfo("%F%P %s uses undefined section %s\n", op, name);
   }
   if (os->processed == false) {
-    info("%F%P %s forward reference of section %s\n",op, name);
+    einfo("%F%P %s forward reference of section %s\n",op, name);
   }
 }
 
-etree_type *exp_intop(value)
-bfd_vma value;
+etree_type *
+DEFUN(exp_intop,(value),
+      bfd_vma value)
 {
-  etree_type *new = (etree_type *)ldmalloc(sizeof(new->value));
+  etree_type *new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->value)));
   new->type.node_code = INT;
   new->value.value = value;
   new->type.node_class = etree_value;
@@ -167,9 +169,9 @@ bfd_vma value;
 
 
 static
-etree_value_type new_rel(value, section)
-bfd_vma value;
-lang_output_section_statement_type *section;
+DEFUN(etree_value_type new_rel,(value, section),
+      bfd_vma value AND
+      lang_output_section_statement_type *section)
 {
   etree_value_type new;
   new.valid = true;
@@ -179,9 +181,10 @@ lang_output_section_statement_type *section;
 }
 
 static
-etree_value_type new_rel_from_section(value, section)
-bfd_vma value;
-lang_output_section_statement_type *section;
+DEFUN(etree_value_type
+      new_rel_from_section, (value, section),
+      bfd_vma value AND
+      lang_output_section_statement_type *section)
 {
   etree_value_type new;
   new.valid = true;
@@ -194,12 +197,12 @@ lang_output_section_statement_type *section;
 }
 
 static etree_value_type 
-fold_binary(tree, current_section, allocation_done, dot, dotp)
-etree_type *tree;
-lang_output_section_statement_type *current_section;
-lang_phase_type  allocation_done;
-bfd_vma dot;
-bfd_vma *dotp;
+DEFUN(fold_binary,(tree, current_section, allocation_done, dot, dotp),
+      etree_type *tree AND
+      lang_output_section_statement_type *current_section AND
+      lang_phase_type  allocation_done AND
+      bfd_vma dot AND
+      bfd_vma *dotp)
 {
   etree_value_type result;
 
@@ -226,13 +229,13 @@ bfd_vma *dotp;
          /* Mod,  both absolule*/
 
          if (other.value == 0) {
-           info("%F%S % by zero\n");
+           einfo("%F%S % by zero\n");
          }
          result.value %= other.value;
          break;
        case '/':
          if (other.value == 0) {
-           info("%F%S / by zero\n");
+           einfo("%F%S / by zero\n");
          }
          result.value /= other.value;
          break;
@@ -263,19 +266,20 @@ bfd_vma *dotp;
   }
   return result;
 }
-etree_value_type invalid()
+etree_value_type 
+DEFUN_VOID(invalid)
 {
   etree_value_type new;
   new.valid = false;
   return new;
 }
 
-etree_value_type fold_name(tree, current_section, allocation_done, dot)
-etree_type *tree;
-lang_output_section_statement_type *current_section;
-lang_phase_type  allocation_done;
-bfd_vma dot;
-
+etree_value_type 
+DEFUN(fold_name, (tree, current_section, allocation_done, dot),
+      etree_type *tree AND
+      lang_output_section_statement_type *current_section AND
+      lang_phase_type  allocation_done AND
+      bfd_vma dot)
 {
   etree_value_type result;
   switch (tree->type.node_code) 
@@ -341,7 +345,7 @@ bfd_vma dot;
              }
            }
            if (result.valid == false) {
-             info("%F%S: undefined symbol `%s' referenced in expression.\n",
+             einfo("%F%S: undefined symbol `%s' referenced in expression.\n",
                   tree->name.name);
            }
 
@@ -367,7 +371,7 @@ bfd_vma dot;
          lang_output_section_statement_type *os = 
            lang_output_section_find(tree->name.name);
          check(os,tree->name.name,"SIZEOF");
-         result = new_abs((bfd_vma)(os->bfd_section->size));
+         result = new_abs((bfd_vma)(os->bfd_section->_raw_size));
        }
        else {
          result = invalid();
@@ -381,118 +385,119 @@ bfd_vma dot;
 
   return result;
 }
-etree_value_type exp_fold_tree(tree, current_section, allocation_done,
-                              dot, dotp)
-etree_type *tree;
-lang_output_section_statement_type *current_section;
-lang_phase_type  allocation_done;
-bfd_vma dot;
-bfd_vma *dotp;
+etree_value_type 
+DEFUN(exp_fold_tree,(tree, current_section, allocation_done,
+                   dot, dotp),
+      etree_type *tree AND
+      lang_output_section_statement_type *current_section AND
+      lang_phase_type  allocation_done AND
+      bfd_vma dot AND
+      bfd_vma *dotp)
 {
   etree_value_type result;
 
   if (tree == (etree_type *)NULL) {
-    result.valid = false;
-  }
+      result.valid = false;
+    }
   else {
-    switch (tree->type.node_class) 
+      switch (tree->type.node_class) 
+      {
+      case etree_value:
+       result = new_rel(tree->value.value, current_section);
+       break;
+      case etree_unary:
+       result = exp_fold_tree(tree->unary.child,
+                              current_section,
+                              allocation_done, dot, dotp);
+       if (result.valid == true)
        {
-       case etree_value:
-         result = new_rel(tree->value.value, current_section);
-         break;
-       case etree_unary:
-         result = exp_fold_tree(tree->unary.child,
-                                current_section,
-                                allocation_done, dot, dotp);
-         if (result.valid == true)
-             {
-               switch(tree->type.node_code) 
-                   {
-                   case ALIGN_K:
-                     if (allocation_done != lang_first_phase_enum) {
-                       result = new_rel_from_section(ALIGN(dot,
-                                                           result.value) ,
-                                                     current_section);
+         switch(tree->type.node_code) 
+         {
+         case ALIGN_K:
+           if (allocation_done != lang_first_phase_enum) {
+               result = new_rel_from_section(ALIGN(dot,
+                                                   result.value) ,
+                                             current_section);
 
-                     }
-                     else {
-                       result.valid = false;
-                     }
-                     break;
-                   case '~':
-                     make_abs(&result);
-                     result.value = ~result.value;
-                     break;
-                   case '!':
-                     make_abs(&result);
-                     result.value = !result.value;
-                     break;
-                   case '-':
-                     make_abs(&result);
-                     result.value = -result.value;
-                     break;
-                   case NEXT:
-                     if (allocation_done ==lang_allocating_phase_enum) {
-                       make_abs(&result);
-                       result.value = ALIGN(dot, result.value);
-                     }
-                     else {
-                     /* Return next place aligned to value */
-                     result.valid = false;
-                   }
-                     break;
-                   default:
-                     FAIL();
-                   }
              }
+           else {
+               result.valid = false;
+             }
+           break;
+         case '~':
+           make_abs(&result);
+           result.value = ~result.value;
+           break;
+         case '!':
+           make_abs(&result);
+           result.value = !result.value;
+           break;
+         case '-':
+           make_abs(&result);
+           result.value = -result.value;
+           break;
+         case NEXT:
+           if (allocation_done ==lang_allocating_phase_enum) {
+               make_abs(&result);
+               result.value = ALIGN(dot, result.value);
+             }
+           else {
+               /* Return next place aligned to value */
+               result.valid = false;
+             }
+           break;
+         default:
+           FAIL();
+         }
+       }
 
-         break;
-       case etree_trinary:
+       break;
+      case etree_trinary:
 
-         result = exp_fold_tree(tree->trinary.cond,
-                                current_section,
-                                allocation_done, dot, dotp);
-         if (result.valid) {
+       result = exp_fold_tree(tree->trinary.cond,
+                              current_section,
+                              allocation_done, dot, dotp);
+       if (result.valid) {
            result = exp_fold_tree(result.value ?
                                   tree->trinary.lhs:tree->trinary.rhs,
                                   current_section,
                                   allocation_done, dot, dotp);
          }
 
-         break;
-       case etree_binary:
-         result = fold_binary(tree, current_section, allocation_done,
-                              dot, dotp);
-         break;
-       case etree_assign:
-         if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) {
+       break;
+      case etree_binary:
+       result = fold_binary(tree, current_section, allocation_done,
+                            dot, dotp);
+       break;
+      case etree_assign:
+       if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) {
            /* Assignment to dot can only be done during allocation */
            if (allocation_done == lang_allocating_phase_enum) {
-             result = exp_fold_tree(tree->assign.src,
-                                    current_section,
-                                    lang_allocating_phase_enum, dot, dotp);
-             if (result.valid == false) {
-               info("%F%S invalid assignment to location counter\n");
-             }
-             else {
-               if (current_section ==
-                   (lang_output_section_statement_type  *)NULL) {
-                 info("%F%S assignment to location counter invalid outside of SECTION\n");
-               }
-               else {
-                 unsigned long nextdot =result.value +
-                   current_section->bfd_section->vma;
-                 if (nextdot < dot) {
-                   info("%F%S cannot move location counter backwards");
+               result = exp_fold_tree(tree->assign.src,
+                                      current_section,
+                                      lang_allocating_phase_enum, dot, dotp);
+               if (result.valid == false) {
+                   einfo("%F%S invalid assignment to location counter\n");
                  }
-                 else {
-                   *dotp = nextdot; 
+               else {
+                   if (current_section ==
+                       (lang_output_section_statement_type  *)NULL) {
+                       einfo("%F%S assignment to location counter invalid outside of SECTION\n");
+                     }
+                   else {
+                       unsigned long nextdot =result.value +
+                        current_section->bfd_section->vma;
+                       if (nextdot < dot) {
+                           einfo("%F%S cannot move location counter backwards");
+                         }
+                       else {
+                           *dotp = nextdot; 
+                         }
+                     }
                  }
-               }
              }
-           }
          }
-         else {
+       else {
            ldsym_type *sy = ldsym_get(tree->assign.dst);
 
            /* If this symbol has just been created then we'll place it into 
@@ -502,74 +507,89 @@ bfd_vma *dotp;
                                   current_section, allocation_done,
                                   dot, dotp);
            if (result.valid)
-               {
-                 asymbol *def;
-                 asymbol **def_ptr = (asymbol **)ldmalloc(sizeof(asymbol **));
-                 /* Add this definition to script file */
-                 def = (asymbol *)bfd_make_empty_symbol(script_file->the_bfd);
-                 *def_ptr = def;
-
-
-                 def->value = result.value;
-                 if (result.section !=
-                     (lang_output_section_statement_type  *)NULL) {
-                   if (current_section !=
-                       (lang_output_section_statement_type *)NULL) {
+           {
+             asymbol *def;
+             asymbol **def_ptr ;
+             /* Add this definition to script file */
+             if (sy->sdefs_chain) 
+             {
+               def_ptr = sy->sdefs_chain;
+               def = *def_ptr;
+                   
+             }
+             else 
+             {
+               def_ptr = (asymbol **)ldmalloc((bfd_size_type)(sizeof(asymbol **)));
+               def = (asymbol
+                      *)bfd_make_empty_symbol(script_file->the_bfd);
+
+                 
+                 
+               *def_ptr = def;
+             }
+
+             def->value = result.value;
+             if (result.section !=
+                 (lang_output_section_statement_type  *)NULL) {
+                 if (current_section !=
+                     (lang_output_section_statement_type *)NULL) {
                  
                      def->section = result.section->bfd_section;
                      def->flags = BSF_GLOBAL | BSF_EXPORT;
                    }
-                   else {
+                 else {
                      /* Force to absolute */
                      def->value += result.section->bfd_section->vma;
-                     def->section = (asection *)NULL;
-                     def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE;
+                     def->section = &bfd_abs_section;
+                     def->flags = BSF_GLOBAL | BSF_EXPORT ;
                    }
 
 
-                 }
-                 else {
-                   def->section = (asection *)NULL;
-                   def->flags = BSF_GLOBAL | BSF_EXPORT | BSF_ABSOLUTE;
-                 }
+               }
+             else {
+                 def->section = &bfd_abs_section;
+                 def->flags = BSF_GLOBAL | BSF_EXPORT ;
+               }
 
 
-                 def->udata = (PTR)NULL;
-                 def->name = sy->name;
-                 Q_enter_global_ref(def_ptr);
-               }
+             def->udata = (PTR)NULL;
+             def->name = sy->name;
+
+             if (sy->sdefs_chain == 0)           Q_enter_global_ref(def_ptr);
+           }
 
          }
 
   
-         break;
-       case etree_name:
-         result = fold_name(tree, current_section, allocation_done, dot);
-         break;
-       default:
-         info("%F%S Need more of these %d",tree->type.node_class );
+       break;
+      case etree_name:
+       result = fold_name(tree, current_section, allocation_done, dot);
+       break;
+      default:
+       einfo("%F%S Need more of these %d",tree->type.node_class );
 
-       }
-  }
+      }
+    }
 
   return result;
 }
 
 
-etree_value_type exp_fold_tree_no_dot(tree, current_section, allocation_done)
-etree_type *tree;
-lang_output_section_statement_type *current_section;
-lang_phase_type  allocation_done;
+etree_value_type 
+DEFUN(exp_fold_tree_no_dot,(tree, current_section, allocation_done),
+      etree_type *tree AND
+      lang_output_section_statement_type *current_section AND
+      lang_phase_type  allocation_done)
 {
 return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
                     0, (bfd_vma *)NULL);
 }
 
 etree_type *
-exp_binop(code, lhs, rhs)
-int code;
-etree_type *lhs;
-etree_type *rhs;
+DEFUN(exp_binop,(code, lhs, rhs),
+      int code AND
+      etree_type *lhs AND
+      etree_type *rhs)
 {
   etree_type value, *new;
   etree_value_type r;
@@ -584,17 +604,17 @@ etree_type *rhs;
     {
       return exp_intop(r.value);
     }
-  new = (etree_type *)ldmalloc(sizeof(new->binary));
+  new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->binary)));
   memcpy((char *)new, (char *)&value, sizeof(new->binary));
   return new;
 }
 
 etree_type *
-exp_trinop(code, cond, lhs, rhs)
-int code;
-etree_type *cond;
-etree_type *lhs;
-etree_type *rhs;
+DEFUN(exp_trinop,(code, cond, lhs, rhs),
+      int code AND
+      etree_type *cond AND
+      etree_type *lhs AND
+      etree_type *rhs)
 {
   etree_type value, *new;
   etree_value_type r;
@@ -608,16 +628,16 @@ etree_type *rhs;
   if (r.valid) {
     return exp_intop(r.value);
   }
-  new = (etree_type *)ldmalloc(sizeof(new->trinary));
+  new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->trinary)));
   memcpy((char *)new,(char *) &value, sizeof(new->trinary));
   return new;
 }
 
 
 etree_type *
-exp_unop(code, child)
-int code;
-etree_type *child;
+DEFUN(exp_unop,(code, child),
+      int code AND
+      etree_type *child)
 {
   etree_type value, *new;
 
@@ -625,21 +645,21 @@ etree_type *child;
   value.unary.type.node_code = code;
   value.unary.child = child;
   value.unary.type.node_class = etree_unary;
-r = exp_fold_tree_no_dot(&value,(lang_output_section_statement_type *)NULL,
-             lang_first_phase_enum);
-if (r.valid) {
+  r = exp_fold_tree_no_dot(&value,(lang_output_section_statement_type *)NULL,
+                          lang_first_phase_enum);
+  if (r.valid) {
     return exp_intop(r.value);
   }
-  new = (etree_type *)ldmalloc(sizeof(new->unary));
+  new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->unary)));
   memcpy((char *)new, (char *)&value, sizeof(new->unary));
   return new;
 }
 
 
 etree_type *
-exp_nameop(code, name)
-int code;
-char *name;
+DEFUN(exp_nameop,(code, name),
+      int code AND
+      CONST char *name)
 {
 
   etree_type value, *new;
@@ -655,7 +675,7 @@ char *name;
   if (r.valid) {
     return exp_intop(r.value);
   }
-  new = (etree_type *)ldmalloc(sizeof(new->name));
+  new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->name)));
   memcpy((char *)new, (char *)&value, sizeof(new->name));
   return new;
 
@@ -665,10 +685,10 @@ char *name;
 
 
 etree_type *
-exp_assop(code, dst, src)
-int code;
-char *dst;
-etree_type *src;
+DEFUN(exp_assop,(code, dst, src),
+      int code AND
+      CONST char *dst AND
+      etree_type *src)
 {
   etree_type value, *new;
 
@@ -684,20 +704,21 @@ etree_type *src;
     return exp_intop(result);
   }
 #endif
-  new = (etree_type*)ldmalloc(sizeof(new->assign));
+  new = (etree_type*)ldmalloc((bfd_size_type)(sizeof(new->assign)));
   memcpy((char *)new, (char *)&value, sizeof(new->assign));
   return new;
 }
 
 void 
-exp_print_tree(outfile, tree)
-FILE *outfile;
-etree_type *tree;
+DEFUN(exp_print_tree,(outfile, tree),
+      FILE *outfile AND
+      etree_type *tree)
 {
   switch (tree->type.node_class) {
   case etree_value:
-    fprintf(outfile,"0x%08lx",(bfd_vma)(tree->value.value));
+    print_address(tree->value.value);
     return;
+
   case etree_assign:
 #if 0
     if (tree->assign.dst->sdefs != (asymbol *)NULL){
@@ -752,11 +773,11 @@ etree_type *tree;
 
 
 bfd_vma
-exp_get_vma(tree, def, name, allocation_done)
-etree_type *tree;
-bfd_vma def;
-char *name;
-lang_phase_type allocation_done;
+DEFUN(exp_get_vma,(tree, def, name, allocation_done),
+      etree_type *tree AND
+      bfd_vma def AND
+      char *name AND
+      lang_phase_type allocation_done)
 {
   etree_value_type r;
 
@@ -765,7 +786,7 @@ lang_phase_type allocation_done;
                      (lang_output_section_statement_type *)NULL,
                      allocation_done);
     if (r.valid == false && name) {
-      info("%F%S Nonconstant expression for %s\n",name);
+      einfo("%F%S Nonconstant expression for %s\n",name);
     }
     return r.value;
   }
@@ -775,11 +796,11 @@ lang_phase_type allocation_done;
 }
 
 int 
-exp_get_value_int(tree,def,name, allocation_done)
-etree_type *tree;
-int def;
-char *name;
-lang_phase_type allocation_done;
+DEFUN(exp_get_value_int,(tree,def,name, allocation_done),
+      etree_type *tree AND
+      int def AND
+      char *name AND
+      lang_phase_type allocation_done)
 {
   return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done);
 }
index bd8d0b6..a5b1731 100644 (file)
@@ -1,18 +1,27 @@
-%{
-/*
- * $Id$ 
- *
- *
-*/
+/* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
+   Copyright (C) 1991 Free Software Foundation, Inc.
+   Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
 
-/* 
-   This is a YACC grammer intended to parse a superset of the AT&T
-   linker scripting languaue.
+This file is part of GNU ld.
 
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-   Written by Steve Chamberlain steve@cygnus.com
-*/
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
 
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+%{
+/*
+ * $Id$
+ */
 
 #define DONTDECLARE_MALLOC
 
@@ -33,7 +42,7 @@ boolean option_v;
 extern unsigned int lineno;
 extern boolean trace_files;
 extern boolean write_map;
-
+extern boolean option_longmap;
 boolean hex_mode;
 
 strip_symbols_type strip_symbols=STRIP_NONE;
@@ -127,8 +136,8 @@ boolean ldgram_had_equals = false;
 %token OPTION_format  OPTION_F OPTION_u OPTION_Bstatic OPTION_N
 %token <integer> SIZEOF NEXT ADDR 
 %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym
-%token OPTION_v OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT NOFLOAT 
-%token OPTION_n OPTION_r OPTION_o OPTION_b  OPTION_R
+%token OPTION_v OPTION_V OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT NOFLOAT 
+%token OPTION_n OPTION_r OPTION_o OPTION_b  OPTION_R OPTION_relax
 %token <name> OPTION_l OPTION_L  OPTION_T OPTION_Aarch OPTION_Tfile  OPTION_Texp
 %token OPTION_Ur 
 %token ORIGIN FILL OPTION_g
@@ -168,17 +177,26 @@ command_line_option:
                        ldversion();
                        option_v = true;
                        }
+       |       OPTION_V
+                       {       
+                       ldversion();
+                       option_v = true;
+                       }
        |       OPTION_t {
                        trace_files = true;
                        }
        |       OPTION_M {
+                       if (write_map) {
+                           option_longmap = true;
+                       }
                        write_map = true;
+
                        }
        |       OPTION_n {
                        config.magic_demand_paged = false;
-                       config.text_read_only = true;
                        }
         |       OPTION_N {
+                       config.text_read_only = false;
                        config.magic_demand_paged = false;
                        }
         |       OPTION_s {
@@ -195,11 +213,13 @@ command_line_option:
                        config.relocateable_output = true;
                        config.build_constructors = false;
                        config.magic_demand_paged = false;
+                       config.text_read_only = false;
                        }
         |       OPTION_Ur {
                        config.relocateable_output = true;
                        config.build_constructors = true;
                        config.magic_demand_paged = false;
+                       config.text_read_only = false;
                      }             
        |       OPTION_o filename
                        {
@@ -225,6 +245,10 @@ command_line_option:
        |      OPTION_d {
                          command_line.force_common_definition = true;
                        }
+
+       |      OPTION_relax {
+                         command_line.relax = true;
+                       }
        |      OPTION_dc
                         {
                          command_line.force_common_definition = true;
index c7ceba2..e974356 100644 (file)
@@ -33,6 +33,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "ldemul.h"
 #include "ldlex.h"
 #include "ldmisc.h"
+#include "ldindr.h"
+#include "ldctor.h"
 /* FORWARDS */
 PROTO(static void, print_statements,(void));
 PROTO(static void, print_statement,(lang_statement_union_type *,
@@ -47,8 +49,8 @@ static lang_statement_list_type input_file_chain;
    stuff to the data section without pain */
 static lang_statement_list_type end_of_data_section_statement_list;
 
-/* List of statements needed to handle consxtructors */
-static lang_statement_list_type constructor_list;
+/* List of statements needed to handle constructors */
+extern lang_statement_list_type constructor_list;
 
 static boolean placed_commons = false;
 static lang_output_section_statement_type *default_common_section;
@@ -63,6 +65,7 @@ static asection common_section;
 static section_userdata_type common_section_userdata;
 static lang_statement_list_type statement_list;
 /* EXPORTS */
+boolean relaxing;
 
 lang_statement_list_type *stat_ptr = &statement_list;
 lang_input_statement_type *script_file = 0;
@@ -186,7 +189,7 @@ DEFUN(lang_for_each_statement,(func),
                                 statement_list.head);
 }
 /*----------------------------------------------------------------------*/
-static void 
+void 
 DEFUN(lang_list_init,(list),
       lang_statement_list_type *list)
 {
@@ -492,17 +495,17 @@ static void
 DEFUN(init_os,(s),
       lang_output_section_statement_type *s)
 {
-  section_userdata_type *new =
-    (section_userdata_type *)
+    asection *section = bfd_get_section_by_name(output_bfd, s->name);
+    section_userdata_type *new =
+     (section_userdata_type *)
       ldmalloc((bfd_size_type)(sizeof(section_userdata_type)));
 
   s->bfd_section = bfd_get_section_by_name(output_bfd, s->name);
   if (s->bfd_section == (asection *)NULL)
     s->bfd_section = bfd_make_section(output_bfd, s->name);
   if (s->bfd_section == (asection *)NULL) {
-    info("%P%F output format %s cannot represent section called %s\n",
-        output_bfd->xvec->name,
-        s->name);
+    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;
 /* s->bfd_section->flags = s->flags;*/
@@ -511,6 +514,7 @@ DEFUN(init_os,(s),
   /* vma to allow us to output a section through itself */
   s->bfd_section->output_offset = 0;
   get_userdata( s->bfd_section) = (PTR)new;
+
 }
 
 /***********************************************************************
@@ -678,12 +682,12 @@ DEFUN(open_output,(name),
   if (output == (bfd *)NULL) 
       {
        if (bfd_error == invalid_target) {
-         info("%P%F target %s not found\n", output_target);
+         einfo("%P%F target %s not found\n", output_target);
        }
-       info("%P%F problem opening output file %s, %E", name);
+       einfo("%P%F problem opening output file %s, %E", name);
       }
   
-  output->flags |= D_PAGED;
+/*  output->flags |= D_PAGED;*/
   bfd_set_format(output, bfd_object);
   return output;
 }
@@ -701,7 +705,7 @@ DEFUN(ldlang_open_output,(statement),
        output_bfd = open_output(statement->output_statement.name);
        ldemul_set_output_arch();
        if (config.magic_demand_paged && !config.relocateable_output)
-         output_bfd->flags |=  ~D_PAGED;
+         output_bfd->flags |=  D_PAGED;
        else
          output_bfd->flags &=  ~D_PAGED;
        if (config.text_read_only)
@@ -809,8 +813,7 @@ DEFUN_VOID(lang_place_undefineds)
     def = (asymbol *)bfd_make_empty_symbol(script_file->the_bfd);
     *def_ptr= def;
     def->name = ptr->name;
-    def->flags = BSF_UNDEFINED;
-    def->section = (asection *)NULL;
+    def->section = &bfd_und_section;
     Q_enter_global_ref(def_ptr);
     ptr = ptr->next;
   }
@@ -901,8 +904,8 @@ DEFUN(map_input_to_output_sections,(s, target, output_section_statement),
              (s->address_statement.section_name);
          os->addr_tree = s->address_statement.address;
          if (os->bfd_section == (asection *)NULL) {
-           info("%P%F can't set the address of undefined section %s\n",
-                s->address_statement.section_name);
+           einfo("%P%F can't set the address of undefined section %s\n",
+                 s->address_statement.section_name);
          }
        }
        break;
@@ -933,7 +936,7 @@ DEFUN(print_output_section_statement,(output_section_statement),
     print_space();
     print_address(section->vma);
     print_space();
-    print_size(section->size);
+    print_size(bfd_get_section_size_before_reloc(section));
     print_space();
     print_alignment(section->alignment_power);
     print_space();
@@ -1017,8 +1020,12 @@ DEFUN(print_input_section,(in),
       lang_input_section_type *in)
 {
   asection *i = in->section;
+  int size = i->flags & SEC_HAS_CONTENTS ?
+   bfd_get_section_size_after_reloc(i) :
+    bfd_get_section_size_before_reloc(i);
+  
 
-  if(i->size != 0) {
+  if(size != 0) {
     print_section("");
     printf(" ");
     print_section(i->name);
@@ -1026,7 +1033,7 @@ DEFUN(print_input_section,(in),
     if (i->output_section) {
       print_address(i->output_section->vma + i->output_offset);
       printf(" ");
-      print_size(i->size);
+      print_size(size);
       printf(" ");
       print_alignment(i->alignment_power);
       printf(" ");
@@ -1065,7 +1072,7 @@ DEFUN(print_input_section,(in),
       }
 
 
-      print_dot = outside_section_address(i) + i->size;
+      print_dot = outside_section_address(i) + size;
     }
     else {
       printf("No output section allocated\n");
@@ -1160,65 +1167,64 @@ DEFUN(print_statement,(s, os),
       lang_statement_union_type *s AND
       lang_output_section_statement_type *os)
 {
-  while (s) {
-    switch (s->header.type) {
-    case lang_constructors_statement_enum:
-      printf("constructors:\n");
-print_statement(constructor_list.head, os);
-break; 
-
-    case lang_wild_statement_enum:
-      print_wild_statement(&s->wild_statement, os);
-      break;
-    default:
-      printf("Fail with %d\n",s->header.type);
-      FAIL();
-      break;
-    case lang_address_statement_enum:
-      printf("address\n");
-      break;
-      break;
-    case lang_object_symbols_statement_enum:
-      printf("object symbols\n");
-      break;
-    case lang_fill_statement_enum:
-      print_fill_statement(&s->fill_statement);
-      break;
-    case lang_data_statement_enum:
-      print_data_statement(&s->data_statement);
-      break;
-    case lang_input_section_enum:
-      print_input_section(&s->input_section);
-      break;
-    case lang_padding_statement_enum:
-      print_padding_statement(&s->padding_statement);
-      break;
-    case lang_output_section_statement_enum:
-      print_output_section_statement(&s->output_section_statement);
-      break;
-    case lang_assignment_statement_enum:
-      print_assignment(&s->assignment_statement,
-                      os);
-      break;
-
-
-    case lang_target_statement_enum:
-      printf("TARGET(%s)\n", s->target_statement.target);
-      break;
-    case lang_output_statement_enum:
-      printf("OUTPUT(%s %s)\n",
-            s->output_statement.name,
-            output_target);
-      break;
-    case lang_input_statement_enum:
-      print_input_statement(&s->input_statement);
-      break;
-    case lang_afile_asection_pair_statement_enum:
-      FAIL();
-      break;
+    while (s) 
+    {
+       switch (s->header.type) 
+       {
+          case lang_constructors_statement_enum:
+           printf("constructors:\n");
+           print_statement(constructor_list.head, os);
+           break;      
+          case lang_wild_statement_enum:
+           print_wild_statement(&s->wild_statement, os);
+           break;
+          default:
+           printf("Fail with %d\n",s->header.type);
+           FAIL();
+           break;
+          case lang_address_statement_enum:
+           printf("address\n");
+           break;
+           break;
+          case lang_object_symbols_statement_enum:
+           printf("object symbols\n");
+           break;
+          case lang_fill_statement_enum:
+           print_fill_statement(&s->fill_statement);
+           break;
+          case lang_data_statement_enum:
+           print_data_statement(&s->data_statement);
+           break;
+          case lang_input_section_enum:
+           print_input_section(&s->input_section);
+           break;
+          case lang_padding_statement_enum:
+           print_padding_statement(&s->padding_statement);
+           break;
+          case lang_output_section_statement_enum:
+           print_output_section_statement(&s->output_section_statement);
+           break;
+          case lang_assignment_statement_enum:
+           print_assignment(&s->assignment_statement,
+                            os);
+           break;
+          case lang_target_statement_enum:
+           printf("TARGET(%s)\n", s->target_statement.target);
+           break;
+          case lang_output_statement_enum:
+           printf("OUTPUT(%s %s)\n",
+                  s->output_statement.name,
+                  output_target);
+           break;
+          case lang_input_statement_enum:
+           print_input_statement(&s->input_statement);
+           break;
+          case lang_afile_asection_pair_statement_enum:
+           FAIL();
+           break;
+       }
+       s = s->next;
     }
-    s = s->next;
-  }
 }
 
 
@@ -1268,7 +1274,7 @@ DEFUN(insert_pad,(this_ptr, fill, power, output_section_statement, dot),
   if (power > output_section_statement->alignment_power) {
     output_section_statement->alignment_power = power;
   }
-  output_section_statement->size += alignment_needed;
+  output_section_statement->_raw_size += alignment_needed;
   return alignment_needed + dot;
 
 }
@@ -1293,8 +1299,8 @@ DEFUN(size_input_section, (this_ptr, output_section_statement, fill,  dot),
        which we will actually allocate  */
     if (((i->flags & 
         (SEC_HAS_CONTENTS | SEC_LOAD)) == (SEC_HAS_CONTENTS | SEC_LOAD))
-       && (i->size > largest_section)) {
-      largest_section = i->size;
+       && (bfd_get_section_size_before_reloc(i) > largest_section)) {
+      largest_section = bfd_get_section_size_before_reloc(i);
     }
 
     /* Remember where in the output section this input section goes */
@@ -1302,8 +1308,8 @@ DEFUN(size_input_section, (this_ptr, output_section_statement, fill,  dot),
     i->output_offset = dot - output_section_statement->bfd_section->vma;
 
     /* Mark how big the output section must be to contain this now */
-    dot += i->size;
-    output_section_statement->bfd_section->size =
+    dot += bfd_get_section_size_before_reloc(i);
+output_section_statement->bfd_section->_raw_size =
       dot - output_section_statement->bfd_section->vma;
   }
   else
@@ -1314,16 +1320,18 @@ DEFUN(size_input_section, (this_ptr, output_section_statement, fill,  dot),
   return dot ;
 }
 
-
+#if 0
 /* Work out the size of the output sections 
- from the sizes of the input sections */
  from the sizes of the input sections */
 static bfd_vma
-DEFUN(lang_size_sections,(s, output_section_statement, prev, fill, dot),
+DEFUN(lang_size_sections,(s, output_section_statement, prev, fill,
+                         dot),
       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)
+
 {
   /* Size up the sections from their constituent parts */
   for (; s != (lang_statement_union_type *)NULL ; s = s->next) 
@@ -1354,7 +1362,7 @@ DEFUN(lang_size_sections,(s, output_section_statement, prev, fill, dot),
                                  lang_allocating_phase_enum,
                                  dot, &dot);
                if (r.valid == false) {
-                 info("%F%S: non constant address expression for section %s\n",
+                 einfo("%F%S: non constant address expression for section %s\n",
                       os->name);
                }
                dot = r.value;
@@ -1399,7 +1407,7 @@ DEFUN(lang_size_sections,(s, output_section_statement, prev, fill, dot),
                                      
        case lang_data_statement_enum: 
            {
-             unsigned int size;
+             unsigned int size = 0;
              s->data_statement.output_vma = dot - output_section_statement->bfd_section->vma;
              s->data_statement.output_section =
                output_section_statement->bfd_section;
@@ -1492,7 +1500,200 @@ DEFUN(lang_size_sections,(s, output_section_statement, prev, fill, dot),
       }
   return dot;
 }
+#else
+/* 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;
+
+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)
+{
+  /* Size up the sections from their constituent parts */
+  for (; s != (lang_statement_union_type *)NULL ; s = s->next) 
+      {
+       switch (s->header.type) {
+         
+       case lang_output_section_statement_enum:
+           {
+             bfd_vma after;
+             lang_output_section_statement_type *os =
+               &(s->output_section_statement);
+             /* The start of a section */
+         
+             if (os->addr_tree == (etree_type *)NULL) {
+               /* No address specified for this section, get one
+                  from the region specification
+                  */
+               if (os->region == (lang_memory_region_type *)NULL) {
+                 os->region = lang_memory_region_lookup("*default*");
+               }
+               dot = os->region->current;
+             }
+             else {
+               etree_value_type r ;
+               r = exp_fold_tree(os->addr_tree,
+                                 (lang_output_section_statement_type *)NULL,
+                                 lang_allocating_phase_enum,
+                                 dot, &dot);
+               if (r.valid == false) {
+                 einfo("%F%S: non constant address expression for section %s\n",
+                      os->name);
+               }
+               dot = r.value;
+             }
+             /* The section starts here */
+             /* First, align to what the section needs */
+
+             dot = align_power(dot, os->bfd_section->alignment_power);
+             os->bfd_section->vma = dot;
+             os->bfd_section->output_offset = 0;
+
+             (void)  lang_size_sections(os->children.head, os, &os->children.head,
+                                        os->fill, dot, relax);
+             /* 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) ;
+
+
+             os->bfd_section->_raw_size = after - os->bfd_section->vma;
+             dot = os->bfd_section->vma + os->bfd_section->_raw_size;
+             os->processed = true;
+
+             /* Replace into region ? */
+             if (os->addr_tree == (etree_type *)NULL 
+                 && os->region !=(lang_memory_region_type*)NULL ) {
+               os->region->current = dot;
+             }
+           }
+
+         break;
+       case lang_constructors_statement_enum:
+           dot = lang_size_sections(constructor_list.head,
+                                     output_section_statement,
+                                     &s->wild_statement.children.head,
+                                     fill,
+                                     dot, relax);
+           break;
+                                     
+       case lang_data_statement_enum: 
+           {
+             unsigned int size = 0;
+             s->data_statement.output_vma = dot - output_section_statement->bfd_section->vma;
+             s->data_statement.output_section =
+               output_section_statement->bfd_section;
+
+             switch (s->data_statement.type) {
+             case LONG:
+               size = LONG_SIZE;
+               break;
+             case SHORT:
+               size = SHORT_SIZE;
+               break;
+             case BYTE:
+               size = BYTE_SIZE;
+               break;
+
+             }
+             dot += size;
+             output_section_statement->bfd_section->_raw_size += size;
+           }
+         break;
+
+       case lang_wild_statement_enum:
+
+         dot = lang_size_sections(s->wild_statement.children.head,
+                                  output_section_statement,
+                                  &s->wild_statement.children.head,
+
+                                  fill, dot, relax);
+
+         break;
+
+       case lang_object_symbols_statement_enum:
+         create_object_symbols = output_section_statement;
+         break;
+       case lang_output_statement_enum:
+       case lang_target_statement_enum:
+         break;
+       case lang_input_section_enum:
+if (relax)
+{
+  relaxing = true;
+  
+
+had_relax |=  relax_section(prev);
+  relaxing = false;
+  
+}
 
+         dot = size_input_section(prev,
+                                  output_section_statement,
+                                  output_section_statement->fill, dot);
+         break;
+       case lang_input_statement_enum:
+         break;
+       case lang_fill_statement_enum:
+         fill = s->fill_statement.fill;
+         break;
+       case lang_assignment_statement_enum:
+           {
+             bfd_vma newdot = dot;
+             exp_fold_tree(s->assignment_statement.exp,
+                           output_section_statement,
+                           lang_allocating_phase_enum,
+                           dot,
+                           &newdot);
+
+             if (newdot != dot) 
+               /* We've been moved ! so insert a pad */
+                 {
+                   lang_statement_union_type *new = 
+                     (lang_statement_union_type *)
+                       ldmalloc((bfd_size_type)(sizeof(lang_padding_statement_type)));
+                   /* Link into existing chain */
+                   new->header.next = *prev;
+                   *prev = new;
+                   new->header.type = lang_padding_statement_enum;
+                   new->padding_statement.output_section =
+                     output_section_statement->bfd_section;
+                   new->padding_statement.output_offset =
+                     dot - output_section_statement->bfd_section->vma;
+                   new->padding_statement.fill = fill;
+                   new->padding_statement.size = newdot - dot;
+                   output_section_statement->bfd_section->_raw_size +=
+                     new->padding_statement.size;
+                   dot =   newdot;
+                 }
+           }
+
+         break;
+       default:
+         FAIL();
+         break;
+/* This can only get here when relaxing is turned on */
+       case lang_padding_statement_enum:
+
+       case lang_address_statement_enum:
+         break;
+       }
+       prev = &s->header.next;      
+      }
+  return dot;
+}
+#endif
 
 static bfd_vma
 DEFUN(lang_do_assignments,(s, output_section_statement, fill, dot),
@@ -1518,7 +1719,7 @@ DEFUN(lang_do_assignments,(s, output_section_statement, fill, dot),
            &(s->output_section_statement);
          dot = os->bfd_section->vma;
          (void) lang_do_assignments(os->children.head, os, os->fill, dot);
-         dot = os->bfd_section->vma + os->bfd_section->size;
+         dot = os->bfd_section->vma + os->bfd_section->_raw_size;
        }
        break;
       case lang_wild_statement_enum:
@@ -1542,7 +1743,7 @@ DEFUN(lang_do_assignments,(s, output_section_statement, fill, dot),
          value =   exp_fold_tree(s->data_statement.exp,
                                  0, lang_final_phase_enum, dot, &dot);
          s->data_statement.value = value.value;
-         if (value.valid == false) info("%F%P: Invalid data statement\n");
+         if (value.valid == false) einfo("%F%P: Invalid data statement\n");
        }
        switch (s->data_statement.type) {
        case LONG:
@@ -1559,7 +1760,7 @@ DEFUN(lang_do_assignments,(s, output_section_statement, fill, dot),
       case lang_input_section_enum:
        {
          asection *in =    s->input_section.section;
-         dot += in->size;
+         dot += bfd_get_section_size_before_reloc(in);
        }
        break;
 
@@ -1787,7 +1988,9 @@ DEFUN_VOID(lang_common)
                ((lang_input_statement_type *)
                 (com->the_bfd->usrdata))->common_section;
              /*  Fix the size of the common section */
-             com->section->size = ALIGN(com->section->size, align);
+
+              com->section->_raw_size =
+               ALIGN(com->section->_raw_size, align);
 
              /* Remember if this is the biggest alignment ever seen */
              if (power_of_two > com->section->alignment_power) {
@@ -1798,7 +2001,7 @@ DEFUN_VOID(lang_common)
                 we remember that it was common once. */
 
              com->flags = BSF_EXPORT | BSF_GLOBAL | BSF_OLD_COMMON;
-             com->value = com->section->size;
+             com->value = com->section->_raw_size;
 
              if (write_map) 
                {
@@ -1809,7 +2012,7 @@ DEFUN_VOID(lang_common)
                          com->the_bfd->filename);
                }
 
-             com->section->size += size;
+             com->section->_raw_size += size;
 
            }
          }
@@ -1902,7 +2105,7 @@ DEFUN(lang_set_flags,(ptr, flags),
 /*       ptr->flag_loadable= state;*/
          break;
        default:
-         info("%P%F illegal syntax in flags\n");
+         einfo("%P%F illegal syntax in flags\n");
          break;
        }
        flags++;
@@ -2016,6 +2219,18 @@ DEFUN_VOID(lang_final)
 
 
 
+/* Reset the current counters in the regions */
+static void
+ DEFUN_VOID(reset_memory_regions) 
+{
+  lang_memory_region_type *p  = lang_memory_region_list;
+  for (p = lang_memory_region_list;
+       p != ( lang_memory_region_type *)NULL;
+       p = p->next) 
+  {
+    p->current = p->origin;
+  }
+}
 
 
 asymbol *
@@ -2038,95 +2253,14 @@ DEFUN(create_symbol,(name, flags, section),
   return def;
 }
 
-/* run through the symbol table, find all the symbols which are
-   constructors and for each one, create statements to do something
-   like..
-
-   for 
-   __CTOR_LIST__, foo
-
-   __CTOR_LIST__ = . ;
-   LONG(__CTOR_LIST_END - . / 4 - 2)
-   *(foo)
-   __CTOR_LIST_END= .
-
-   Put these statements onto a special list.
-
-*/
-
-typedef struct constructor_list 
-{
-ldsym_type *sym;
-  struct constructor_list *next;
-}  constructor_list_type;
-   
-static constructor_list_type *constructor_name_list;
-
-void
-DEFUN(ldlang_add_constructor,(name),
-ldsym_type *name)
-{
-
-  constructor_list_type *next   = constructor_name_list;
-
-  if (name->flags & SYM_CONSTRUCTOR) return;
-
-  next = (constructor_list_type *)  ldmalloc(sizeof(constructor_list_type));
-  next->next= constructor_name_list;
-  next->sym= name;
-  name->flags |= SYM_CONSTRUCTOR;
-  constructor_name_list = next;
-
-}
-
-void
-DEFUN_VOID(find_constructors)
-{
-  lang_statement_list_type *old = stat_ptr;
-  constructor_list_type *p = constructor_name_list;
-  stat_ptr = & constructor_list;
-  lang_list_init(stat_ptr);
-  while (p != (constructor_list_type *)NULL) 
-      {
-       /* Have we already done this one ? */
-       CONST char *name = p->sym->name;
-       int len = strlen(name);
-       char *end = ldmalloc(len+3);
-       strcpy(end, name);
-       strcat(end,"$e");
-
-       lang_add_assignment
-         ( exp_assop('=',name, exp_nameop(NAME,".")));
-
-       lang_add_data
-         (LONG, exp_binop('-',
-                          exp_binop ( '/',
-                                     exp_binop ( '-',
-                                                exp_nameop(NAME, end),
-                                                exp_nameop(NAME,".")),
-                                     exp_intop(4)),
-
-                          exp_intop(2)));
-
-                                     
-       lang_add_wild(name, (char *)NULL);
-       lang_add_data(LONG, exp_intop(0));
-       lang_add_assignment
-         (exp_assop('=', end, exp_nameop(NAME,".")));
-p = p->next;               
-      }
-
 
 
-
-  stat_ptr = old;
-}
 void
 DEFUN_VOID(lang_process)
 {               
   if (had_script == false) {
-    parse_line(ldemul_get_script());
-  }
+      parse_line(ldemul_get_script());
+    }
   lang_reasonable_defaults();
   current_target = default_target;
 
@@ -2164,10 +2298,42 @@ DEFUN_VOID(lang_process)
 
   ldemul_before_allocation();
 
+
   /* Size up the sections */
   lang_size_sections(statement_list.head,
                     (lang_output_section_statement_type *)NULL,
-                    &(statement_list.head), 0, (bfd_vma)0);
+                    &(statement_list.head), 0, (bfd_vma)0, false);
+
+
+  /* Move the global symbols around */
+  lang_relocate_globals();
+
+  /* Now run around and relax if we can */
+  if (command_line.relax) 
+  {
+    reset_memory_regions();
+    
+    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;
+      
+    }
+    
+    
+
+
+  }
+  
 
   /* See if anything special should be done now we know how big
      everything is */
@@ -2180,13 +2346,11 @@ DEFUN_VOID(lang_process)
                      (lang_output_section_statement_type *)NULL,
                      0, (bfd_vma)0);
 
+
   /* Make sure that we're not mixing architectures */
 
   lang_check();
 
-  /* Move the global symbols around */
-  lang_relocate_globals();
-
   /* Final stuffs */
   lang_finish();
 }
@@ -2301,7 +2465,7 @@ DEFUN(lang_startup,(name),
       CONST char *name)
 {
   if (startup_file != (char *)NULL) {
-   info("%P%FMultiple STARTUP files\n");
+   einfo("%P%FMultiple STARTUP files\n");
   }
   first_file->filename = name;
   first_file->local_sym_name = name;
@@ -2345,9 +2509,10 @@ DEFUN(lang_abs_symbol_at_beginning_of,(section, name),
   if (ldsym_undefined(name)) {
     asection *s = bfd_get_section_by_name(output_bfd, section);
     asymbol *def = create_symbol(name,
-                                BSF_GLOBAL | BSF_EXPORT |
-                                BSF_ABSOLUTE,
-                                (asection *)NULL);
+                                BSF_GLOBAL | BSF_EXPORT ,
+                                &bfd_abs_section);
+    
+
     if (s != (asection *)NULL) {
       def->value = s->vma;
     }
@@ -2372,11 +2537,11 @@ DEFUN(lang_abs_symbol_at_end_of,(section, name),
     asection *s = bfd_get_section_by_name(output_bfd, section);
     /* Add a symbol called _end */
     asymbol *def = create_symbol(name,
-                                BSF_GLOBAL | BSF_EXPORT |
-                                BSF_ABSOLUTE,
-                                (asection *)NULL);
+                                BSF_GLOBAL | BSF_EXPORT ,
+                                &bfd_abs_section);
+
     if (s != (asection *)NULL) {
-      def->value = s->vma + s->size;
+      def->value = s->vma + s->_raw_size;
     }
     else {
       def->value = 0;
index bfdc9cb..acd039d 100644 (file)
@@ -1,19 +1,19 @@
 /* ldlang.h -
-
+   
    Copyright (C) 1991 Free Software Foundation, Inc.
-
+   
    This file is part of GLD, the Gnu Linker.
-
+   
    GLD is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 1, or (at your option)
    any later version.
-
+   
    GLD is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
+   
    You should have received a copy of the GNU General Public License
    along with GLD; see the file COPYING.  If not, write to
    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
@@ -24,7 +24,7 @@ typedef enum {
   lang_input_file_is_symbols_only_enum,
   lang_input_file_is_marker_enum,
   lang_input_file_is_fake_enum,
-lang_input_file_is_search_file_enum,
+  lang_input_file_is_search_file_enum,
   lang_input_file_is_file_enum } lang_input_file_enum_type;
 
 typedef unsigned short fill_type;
@@ -34,12 +34,7 @@ typedef struct statement_list {
 } lang_statement_list_type;
 
 
-typedef struct {
-  boolean flag_read;
-  boolean flag_write;
-  boolean flag_executable;
-  boolean flag_loadable;
-} lang_section_flags_type;
+
 
 typedef struct memory_region_struct {
   char *name;
@@ -47,37 +42,38 @@ typedef struct memory_region_struct {
   bfd_vma origin;
   bfd_offset length;
   bfd_vma current;
-  lang_section_flags_type flags;
+  int flags;
 } lang_memory_region_type ;
 
 typedef struct lang_statement_header_struct 
-{
-union  lang_statement_union  *next;
-  enum statement_enum {
-    lang_output_section_statement_enum,
-    lang_assignment_statement_enum,
-    lang_input_statement_enum,
-    lang_address_statement_enum,
-    lang_wild_statement_enum,
-    lang_input_section_enum,
-    lang_object_symbols_statement_enum,
-    lang_fill_statement_enum,
-    lang_data_statement_enum,
-    lang_target_statement_enum,
-    lang_output_statement_enum,
-    lang_padding_statement_enum,
-
-    lang_afile_asection_pair_statement_enum
-  } type;
-
-} lang_statement_header_type;
+  {
+    union  lang_statement_union  *next;
+    enum statement_enum {
+      lang_output_section_statement_enum,
+      lang_assignment_statement_enum,
+      lang_input_statement_enum,
+      lang_address_statement_enum,
+      lang_wild_statement_enum,
+      lang_input_section_enum,
+      lang_object_symbols_statement_enum,
+      lang_fill_statement_enum,
+      lang_data_statement_enum,
+      lang_target_statement_enum,
+      lang_output_statement_enum,
+      lang_padding_statement_enum,
+      
+      lang_afile_asection_pair_statement_enum,
+       lang_constructors_statement_enum
+      } type;
+    
+  } lang_statement_header_type;
 
 
 typedef struct 
-{
-  lang_statement_header_type header;
-  union etree_union *exp;
-}  lang_assignment_statement_type;
+  {
+    lang_statement_header_type header;
+    union etree_union *exp;
+  }  lang_assignment_statement_type;
 
 
 typedef struct lang_target_statement_struct {
@@ -93,22 +89,22 @@ typedef struct lang_output_statement_struct {
 
 
 typedef struct lang_output_section_statement_struct 
-{
-  lang_statement_header_type header;
-  union etree_union *addr_tree;
-  lang_statement_list_type children;
-  CONST char *memspec;
-  union lang_statement_union *next;
-  CONST char *name;
-  unsigned long subsection_alignment;
-  boolean processed;
-
-  asection *bfd_section;
-  lang_section_flags_type flags;
-  struct memory_region_struct *region;
-  size_t block_value;
-  fill_type fill;
-} lang_output_section_statement_type;
+  {
+    lang_statement_header_type header;
+    union etree_union *addr_tree;
+    lang_statement_list_type children;
+    CONST char *memspec;
+    union lang_statement_union *next;
+    CONST char *name;
+    unsigned long subsection_alignment;
+    boolean processed;
+    
+    asection *bfd_section;
+   int flags;
+    struct memory_region_struct *region;
+    size_t block_value;
+    fill_type fill;
+  } lang_output_section_statement_type;
 
 
 typedef struct {
@@ -145,63 +141,54 @@ typedef struct lang_input_statement_struct
     /* Usually the same as filename, but for a file spec'd with -l
        this is the -l switch itself rather than the filename.  */
     CONST char *local_sym_name;
-
-    /* Describe the layout of the contents of the file */
-
-    /* The file's a.out header.  */
-    /*  struct exec header;*/
-    /* Offset in file of GDB symbol segment, or 0 if there is none.  */
-    int symseg_offset;
-
-    /* Describe data from the file loaded into core */
-
+    
     bfd *the_bfd;
-
+    
     boolean closed;
     file_ptr passive_position;
-
+    
     /* Symbol table of the file.  */
     asymbol **asymbols;
     unsigned int symbol_count;
-
+    
     /* For library members only */
-
+    
     /* For a library, points to chain of entries for the library members.  */
     struct lang_input_statement_struct *subfiles;
     /* For a library member, offset of the member within the archive.
        Zero for files that are not library members.  */
     /*  int starting_offset;*/
     /* Size of contents of this file, if library member.  */
-    int total_size;
+    bfd_size_type total_size;
     /* For library member, points to the library's own entry.  */
     struct lang_input_statement_struct *superfile;
     /* For library member, points to next entry for next member.  */
     struct lang_input_statement_struct *chain;
     /* Point to the next file - whatever it is, wanders up and down
        archives */
-
+    
     union lang_statement_union  *next;
     /* Point to the next file, but skips archive contents */
     union  lang_statement_union  *next_real_file;
-
+    
     boolean is_archive;
-
+    
     /* 1 means search a set of directories for this file.  */
     boolean search_dirs_flag;
-
+    
     /* 1 means this is base file of incremental load.
        Do not load this file's text or data.
        Also default text_start to after this file's bss. */
-
+    
     boolean just_syms_flag;
-
+    
     boolean loaded;
-
-
+    
+    
     /*    unsigned int globals_in_this_file;*/
     CONST char *target;
     boolean real;
-
+    
     asection *common_section;
     asection *common_output_section;
   } lang_input_statement_type;
@@ -210,7 +197,7 @@ typedef struct {
   lang_statement_header_type header;
   asection *section;
   lang_input_statement_type *ifile;
-
+  
 } lang_input_section_type;
 
 
@@ -222,8 +209,8 @@ typedef struct {
 
 typedef struct lang_wild_statement_struct {
   lang_statement_header_type header;
-CONST char *section_name;
-CONST char *filename;
+  CONST char *section_name;
+  CONST char *filename;
   lang_statement_list_type children;
 } lang_wild_statement_type;
 
@@ -242,24 +229,24 @@ typedef struct {
 } lang_padding_statement_type;
 
 typedef union lang_statement_union 
-{
-  lang_statement_header_type header;
-  union lang_statement_union *next;
-  lang_wild_statement_type wild_statement;
-  lang_data_statement_type data_statement;
-  lang_address_statement_type address_statement;
-  lang_output_section_statement_type output_section_statement;
-  lang_afile_asection_pair_statement_type afile_asection_pair_statement;
-  lang_assignment_statement_type assignment_statement;
-  lang_input_statement_type input_statement;
-  lang_target_statement_type target_statement;
-  lang_output_statement_type output_statement;
-  lang_input_section_type input_section;
-  lang_common_statement_type common_statement;
-  lang_object_symbols_statement_type object_symbols_statement;
-  lang_fill_statement_type fill_statement;
-  lang_padding_statement_type padding_statement;
-} lang_statement_union_type;
+  {
+    lang_statement_header_type header;
+    union lang_statement_union *next;
+    lang_wild_statement_type wild_statement;
+    lang_data_statement_type data_statement;
+    lang_address_statement_type address_statement;
+    lang_output_section_statement_type output_section_statement;
+    lang_afile_asection_pair_statement_type afile_asection_pair_statement;
+    lang_assignment_statement_type assignment_statement;
+    lang_input_statement_type input_statement;
+    lang_target_statement_type target_statement;
+    lang_output_statement_type output_statement;
+    lang_input_section_type input_section;
+    lang_common_statement_type common_statement;
+    lang_object_symbols_statement_type object_symbols_statement;
+    lang_fill_statement_type fill_statement;
+    lang_padding_statement_type padding_statement;
+  } lang_statement_union_type;
 
 
 
@@ -270,7 +257,7 @@ PROTO(struct memory_region_struct ,
 
 
 PROTO(void ,lang_map,(FILE *));
-PROTO(void,lang_set_flags,(lang_section_flags_type *, CONST char *));
+PROTO(void,lang_set_flags,(int  *, CONST char *));
 PROTO(void,lang_add_output,(CONST char *));
 
 PROTO(void,lang_final,(void));
@@ -285,47 +272,47 @@ PROTO(void,lang_add_fill,(int));
 PROTO(void,lang_add_assignment,(union etree_union *));
 PROTO(void,lang_add_attribute,(enum statement_enum));
 PROTO(void,lang_startup,(CONST char *));
-PROTO(void,lang_float,(enum boolean));
+PROTO(void,lang_float,(enum bfd_boolean));
 PROTO(void,lang_leave_output_section_statement,(bfd_vma, CONST char *));
 PROTO(void,lang_abs_symbol_at_end_of,(CONST char *, CONST char *));
 PROTO(void,lang_abs_symbol_at_beginning_of,(CONST char *, CONST char *));
 PROTO(void,lang_statement_append,(struct statement_list *, union lang_statement_union *, union lang_statement_union **));
 PROTO(void, lang_for_each_file,(void (*dothis)(lang_input_statement_type *)));
 
-     
+
 #define LANG_FOR_EACH_INPUT_STATEMENT(statement)               \
   extern lang_statement_list_type file_chain;                  \
   lang_input_statement_type *statement;                                \
   for (statement = (lang_input_statement_type *)file_chain.head;\
        statement != (lang_input_statement_type *)NULL;         \
        statement = (lang_input_statement_type *)statement->next)\
-
+  
 #define LANG_FOR_EACH_INPUT_SECTION(statement, abfd, section, x) \
-{ extern lang_statement_list_type file_chain;                  \
-  lang_input_statement_type *statement;                                \
-  for (statement = (lang_input_statement_type *)file_chain.head;\
-       statement != (lang_input_statement_type *)NULL;         \
-       statement = (lang_input_statement_type *)statement->next)\
-    {                                                          \
-      asection *section;                                       \
-      bfd *abfd = statement->the_bfd;                          \
+  { extern lang_statement_list_type file_chain;                        \
+      lang_input_statement_type *statement;                            \
+       for (statement = (lang_input_statement_type *)file_chain.head;\
+            statement != (lang_input_statement_type *)NULL;            \
+            statement = (lang_input_statement_type *)statement->next)\
+                {                                                              \
+         asection *section;                                    \
+    bfd *abfd = statement->the_bfd;                            \
       for (section = abfd->sections;                           \
           section != (asection *)NULL;                         \
           section = section->next) {                           \
-       x;                                                      \
-      }                                                                \
-    }                                                          \
+         x;                                                    \
+  }                                                            \
+  }                                                            \
  }             
 
 #define LANG_FOR_EACH_OUTPUT_SECTION(section, x)               \
{ extern bfd *output_bfd;                                     \
-   asection *section;                                          \
-   for (section = output_bfd->sections;                                \
-       section != (asection *)NULL;                            \
-       section = section->next)                                \
-       { x; }                                                  \
- }
-                                       
 { extern bfd *output_bfd;                                    \
+      asection *section;                                       \
+       for (section = output_bfd->sections;                            \
+            section != (asection *)NULL;                               \
+            section = section->next)                           \
+                { x; }                                                 \
               }
+
 
 PROTO(void, lang_process,(void));
 PROTO(void, ldlang_add_file,(lang_input_statement_type *));
@@ -334,11 +321,16 @@ PROTO(lang_output_section_statement_type
       *,lang_output_section_find,(CONST char * CONST));
 
 PROTO(lang_input_statement_type *,
-       lang_add_input_file,(char *name,
-                           lang_input_file_enum_type file_type,
-                           char *target));
+      lang_add_input_file,(char *name,
+                          lang_input_file_enum_type file_type,
+                          char *target));
 PROTO(lang_output_section_statement_type *,
-lang_output_section_statement_lookup,(CONST char * CONST name));
+      lang_output_section_statement_lookup,(CONST char * CONST name));
 
 PROTO(void, ldlang_add_undef,(CONST char *CONST name));
 PROTO(void, lang_add_output_format,(CONST char *));
+
+
+void EXFUN(lang_list_init,( lang_statement_list_type*));
+
+void EXFUN(lang_add_data,(int type, union etree_union *));
index 71ca4cf..99526a0 100644 (file)
@@ -35,7 +35,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "ldemul.h"
 #include "ldlex.h"
 #include "ldfile.h"
-
+#include "ldindr.h"
+#include "ldwarn.h"
+#include "ldctor.h"
 /* IMPORTS */
 extern boolean lang_has_input_file;
 extern boolean trace_files;
@@ -112,6 +114,7 @@ unsigned int total_symbols_seen;
  */
 unsigned int total_files_seen;
 
+
 /* IMPORTS */
 args_type command_line;
 ld_config_type config;
@@ -151,6 +154,8 @@ main (argc, argv)
   unix_relocate = 0;
   command_line.force_common_definition = false;
 
+  init_bfd_error_vector();
+  
   ldfile_add_arch("");
   ldfile_add_library_path("./");
   config.make_executable = true;
@@ -181,7 +186,7 @@ main (argc, argv)
     info("%P: mode %s\n", emulation);
   }
   if (lang_has_input_file == false) {
-    info("%P%F: No input files\n");
+    einfo("%P%F: No input files\n");
   }
 
   ldemul_after_parse();
@@ -190,35 +195,32 @@ main (argc, argv)
   /* Print error messages for any missing symbols, for any warning
      symbols, and possibly multiple definitions */
 
-  /* Print a map, if requested.  */
-
-  if (write_map) {
-    ldsym_print_symbol_table ();
-    lang_map(stdout);
-  }
 
   if (config.text_read_only) {
     /* Look for a text section and mark the readonly attribute in it */
     asection *found = bfd_get_section_by_name(output_bfd, ".text");
     if (found == (asection *)NULL) {
-      info("%P%F: text marked read only, but no text section present");
+      einfo("%P%F: text marked read only, but no text section present");
     }
     found->flags |= SEC_READONLY;
   }
 
   if (config.relocateable_output) {
     output_bfd->flags &= ~EXEC_P;
-    ldwrite();
+
+    ldwrite(write_map);
     bfd_close(output_bfd);
   }
   else {
     output_bfd->flags |= EXEC_P;
 
-    ldwrite();
-    bfd_close(output_bfd);
-    if (config.make_executable == false && force_make_executable == false) {
+    ldwrite(write_map);
+
+    if (config.make_executable == false && force_make_executable ==false) {
+
       unlink(output_filename);
     }
+    else {    bfd_close(output_bfd); };
     return (!config.make_executable);
   }
 
@@ -249,8 +251,8 @@ asymbol **nlist_p;
 {
   asymbol *sym = *nlist_p;
   sym->value = 0;
-  sym->flags = BSF_UNDEFINED;
-  sym->section = (asection *)NULL;
+  sym->flags = 0;
+  sym->section = &bfd_und_section;
   sym->udata =(PTR)( sp->srefs_chain);
   sp->srefs_chain = nlist_p;
 }
@@ -277,6 +279,7 @@ Whilst all this is going on we keep a count of the number of multiple
 definitions seen, undefined global symbols and pending commons.
 */
 
+extern boolean relaxing;
 
 void
 Q_enter_global_ref (nlist_p)
@@ -305,7 +308,7 @@ Q_enter_global_ref (nlist_p)
 
   }
   else {  
-    if (flag_is_common(this_symbol_flags)) {
+    if (sym->section == &bfd_com_section) {
       /* If we have a definition of this symbol already then
          this common turns into a reference. Also we only
          ever point to the largest common, so if we
@@ -351,7 +354,7 @@ Q_enter_global_ref (nlist_p)
       }
     }
 
-    else if (flag_is_defined(this_symbol_flags)) {
+    else if (sym->section != &bfd_und_section) {
       /* This is the definition of a symbol, add to def chain */
       if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section) {
        /* Multiple definition */
@@ -362,18 +365,11 @@ Q_enter_global_ref (nlist_p)
        asymbol ** stat_symbols = stat ? stat->asymbols:0;
       
        multiple_def_count++;
-       info("%C: multiple definition of `%T'\n",
-            sym->the_bfd,
-            sym->section,
-            stat1_symbols,
-            sym->value,
-            sym);
+       einfo("%C: multiple definition of `%T'\n",
+             sym->the_bfd, sym->section, stat1_symbols, sym->value, sym);
           
-       info("%C: first seen here\n",
-            sy->the_bfd,
-            sy->section,
-            stat_symbols,
-            sy->value);
+       einfo("%C: first seen here\n",
+             sy->the_bfd, sy->section, stat_symbols, sy->value);
       }
       else {
        sym->udata =(PTR)( sp->sdefs_chain);
@@ -385,7 +381,7 @@ Q_enter_global_ref (nlist_p)
        sp->scoms_chain = 0;
        commons_pending--;
       }
-      else if (sp->srefs_chain) {
+      else if (sp->srefs_chain && relaxing == false) {
        /* If previously was undefined, then remember as defined */
        undefined_global_sym_count--;
       }
@@ -414,8 +410,9 @@ Q_enter_file_symbols (entry)
 lang_input_statement_type *entry;
 {
   asymbol **q ;
+
   entry->common_section =
-    bfd_make_section(entry->the_bfd, "COMMON");
+    bfd_make_section_old_way(entry->the_bfd, "COMMON");
   
   ldlang_add_file(entry);
 
@@ -430,7 +427,10 @@ lang_input_statement_type *entry;
     {
       asymbol *p = *q;
 
-      if (flag_is_undefined_or_global_or_common_or_constructor(p->flags))
+      if (p->section == &bfd_und_section
+         || (p->flags & BSF_GLOBAL) 
+         || p->section == &bfd_com_section
+         || (p->flags & BSF_CONSTRUCTOR))
        {
          Q_enter_global_ref(q);
        }
@@ -441,7 +441,7 @@ lang_input_statement_type *entry;
       if (p->flags & BSF_WARNING) {
        add_warning(p);
       }
-      ASSERT(p->flags != 0);
+
     }
 }
 
@@ -533,8 +533,8 @@ struct lang_input_statement_struct *entry;
        }
       else 
        {
-         info("%F%B: malformed input file (not rel or archive) \n",
-                                               entry->the_bfd);
+         einfo("%F%B: malformed input file (not rel or archive) \n",
+               entry->the_bfd);
        }
     }
 
@@ -658,9 +658,8 @@ symdef_library (entry)
                                        }
 
                                        if (archive_member_lang_input_statement_struct == 0) {
-                                         info ("%F%I contains invalid archive member %s\n",
-                                               entry,
-                                               sp->name);
+                                         einfo ("%F%I contains invalid archive member %s\n",
+                                                entry, sp->name);
                                        }
 
                                        if (archive_member_lang_input_statement_struct->loaded == false)  
@@ -779,7 +778,7 @@ struct lang_input_statement_struct *entry;
        add_indirect(q);
       }
 
-      if (p->flags & BSF_FORT_COMM 
+      if (p->section == &bfd_com_section
          || p->flags & BSF_GLOBAL)
        {
          register ldsym_type *sp = ldsym_get_soft (p->name);
@@ -795,7 +794,7 @@ struct lang_input_statement_struct *entry;
                /* This is a symbol we are looking for.  It is either
                   not yet defined or common.  */
 
-               if (flag_is_common(p->flags))
+               if (p->section == &bfd_com_section)
                  {
 
                    /* If the symbol in the table is a constructor, we won't to
@@ -824,7 +823,9 @@ struct lang_input_statement_struct *entry;
                        (asymbol **)((*(sp->srefs_chain))->udata);
                      (*(sp->scoms_chain))->udata = (PTR)NULL;
 
-                     (*(  sp->scoms_chain))->flags = BSF_FORT_COMM;
+                     (*(  sp->scoms_chain))->section  =
+                      &bfd_com_section;
+                     (*(  sp->scoms_chain))->flags  = 0;
                      /* Remember the size of this item */
                      sp->scoms_chain[0]->value = p->value;
                      commons_pending++;
@@ -836,7 +837,7 @@ struct lang_input_statement_struct *entry;
                          (asection *)NULL) {
                        ((lang_input_statement_type *)
                         (com->the_bfd->usrdata))->common_section = 
-                          bfd_make_section(com->the_bfd, "COMMON");
+                          bfd_make_section_old_way(com->the_bfd, "COMMON");
                      }
                    }
                  }
@@ -858,3 +859,4 @@ struct lang_input_statement_struct *entry;
   return false;
 }
 
+
index 9ae7515..f67f235 100644 (file)
@@ -1,10 +1,13 @@
-/* Copyright (C) 1991 Free Software Foundation, Inc.
+/* ldmisc.c
+   Copyright (C) 1991 Free Software Foundation, Inc.
+
+   Written by Steve Chamberlain of Cygnus Support.
 
 This file is part of GLD, the Gnu Linker.
 
 GLD is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GLD is distributed in the hope that it will be useful,
@@ -17,17 +20,14 @@ along with GLD; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /*
- * $Id$ 
- */
+$Id$ 
 
-/*
-  ldmisc.c
 
-*/
+ */
 
+#include "bfd.h"
 #include "sysdep.h"
 #include <varargs.h>
-#include "bfd.h"
 
 #include "ld.h"
 #include "ldmisc.h"
@@ -45,7 +45,7 @@ void
 yyerror(arg) 
 char *arg;
 { 
-  info("%P%F: %S %s\n",arg);
+  einfo("%P%F: %S %s\n",arg);
 }
 
 extern int errno;
@@ -63,19 +63,19 @@ extern char *sys_errlist[];
  %X no object output, fail return
  %V hex bfd_vma
  %C Clever filename:linenumber 
+ %R info about a relent
  %
 */
-void info(va_alist)
-va_dcl
+static void
+vfinfo(fp, fmt, arg)
+     FILE *fp;
+     char *fmt;
+     va_list arg;
 {
-  char *fmt;
   boolean fatal = false;
-  va_list arg;
-  va_start(arg);
-  fmt = va_arg(arg, char *);
   while (*fmt) {
     while (*fmt != '%' && *fmt != '\0') {
-      fputc(*fmt, stderr);
+      putc(*fmt, fp);
       fmt++;
     }
     if (*fmt == '%') {
@@ -85,24 +85,23 @@ va_dcl
        config.make_executable = false;
        break;
       case 'V':
-       fprintf(stderr,"%08lx", va_arg(arg, bfd_vma));
+         {
+           bfd_vma value = va_arg(arg, bfd_vma);
+           fprintf_vma(fp, value);
+         }
        break;
       case 'T':
        {
          asymbol *symbol = va_arg(arg, asymbol *);
-         if (symbol) {
+         if (symbol) 
+         {
            asection *section = symbol->section;
-           if ((symbol->flags & BSF_UNDEFINED) == 0) {
-           CONST char *section_name = section == (asection *)NULL ?
-               "absolute" : section->name;
-             fprintf(stderr,"%s (%s)", symbol->name, section_name);
-           }
-           else {
-             fprintf(stderr,"%s", symbol->name);
-           }
+           CONST char *section_name =  section->name;
+           fprintf(fp,"%s (%s)", symbol->name, section_name);
          }
-         else {
-           fprintf(stderr,"no symbol");
+         else 
+         {
+           fprintf(fp,"no symbol");
          }
        }
        break;
@@ -110,11 +109,11 @@ va_dcl
        { 
          bfd *abfd = va_arg(arg, bfd *);
          if (abfd->my_archive) {
-           fprintf(stderr,"%s(%s)", abfd->my_archive->filename,
+           fprintf(fp,"%s(%s)", abfd->my_archive->filename,
                    abfd->filename);
          }
          else {
-           fprintf(stderr,"%s", abfd->filename);
+           fprintf(fp,"%s", abfd->filename);
 
          }
        }
@@ -123,13 +122,13 @@ va_dcl
        fatal = true;
        break;
       case 'P':
-       fprintf(stderr,"%s", program_name);
+       fprintf(fp,"%s", program_name);
        break;
       case 'E':
        /* Replace with the most recent errno explanation */
 
 
-       fprintf(stderr, bfd_errmsg(bfd_error));
+       fprintf(fp, bfd_errmsg(bfd_error));
 
 
        break;
@@ -138,7 +137,7 @@ va_dcl
          lang_input_statement_type *i =
            va_arg(arg,lang_input_statement_type *);
        
-         fprintf(stderr,"%s", i->local_sym_name);
+         fprintf(fp,"%s", i->local_sym_name);
        }
        break;
       case 'S':
@@ -147,26 +146,44 @@ va_dcl
        if (ldlex_input_stack) {
          extern unsigned int lineno;
          if (ldfile_input_filename == (char *)NULL) {
-           fprintf(stderr,"command line");
+           fprintf(fp,"command line");
          }
          else {
-           fprintf(stderr,"%s:%u", ldfile_input_filename, lineno );
+           fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
          }
        }
        else {
          int ch;
          int n = 0;
-         fprintf(stderr,"command (just before \"");
+         fprintf(fp,"command (just before \"");
          ch = lex_input();
          while (ch != 0 && n < 10) {
-           fprintf(stderr, "%c", ch);
+           fprintf(fp, "%c", ch);
            ch = lex_input();
            n++;
          }
-         fprintf(stderr,"\")");
+         fprintf(fp,"\")");
            
        }
        break;
+
+      case 'R':
+       /* Print all that's interesting about a relent */
+      {
+       arelent *relent = va_arg(arg, arelent *);
+       
+       fprintf(fp,"%s+0x%x (type %s)",
+               (*(relent->sym_ptr_ptr))->name,
+               relent->addend,
+               relent->howto->name);
+       
+
+      }
+       break;
+       
+
+
+       
       case 'C':
        {
         CONST char *filename;
@@ -188,27 +205,31 @@ va_dcl
                if (filename == (char *)NULL)   
                    filename = abfd->filename;
                if (functionname != (char *)NULL)
-                   fprintf(stderr,"%s:%u: (%s)", filename, linenumber,  functionname);
+                   fprintf(fp,"%s:%u: (%s)", filename, linenumber,  functionname);
                else if (linenumber != 0) 
-                   fprintf(stderr,"%s:%u", filename, linenumber);
+                   fprintf(fp,"%s:%u", filename, linenumber);
                else
-                   fprintf(stderr,"%s", filename);
+                   fprintf(fp,"%s(%s+%0x)", filename,
+                           section->name,
+                           offset);
 
            }
          else {
-           fprintf(stderr,"%s", abfd->filename);
+           fprintf(fp,"%s(%s+%0x)", abfd->filename,
+                   section->name,
+                   offset);
          }
        }
        break;
                
       case 's':
-       fprintf(stderr,"%s", va_arg(arg, char *));
+       fprintf(fp,"%s", va_arg(arg, char *));
        break;
       case 'd':
-       fprintf(stderr,"%d", va_arg(arg, int));
+       fprintf(fp,"%d", va_arg(arg, int));
        break;
       default:
-       fprintf(stderr,"%s", va_arg(arg, char *));
+       fprintf(fp,"%s", va_arg(arg, char *));
        break;
       }
     }
@@ -219,16 +240,40 @@ va_dcl
       unlink(output_filename);
     exit(1);
   }
+}
+
+/* Format info message and print on stdout. */
+
+void info(va_alist)
+va_dcl
+{
+  char *fmt;
+  va_list arg;
+  va_start(arg);
+  fmt = va_arg(arg, char *);
+  vfinfo(stdout, fmt, arg);
   va_end(arg);
 }
 
+/* ('e' for error.) Format info message and print on stderr. */
+
+void einfo(va_alist)
+va_dcl
+{
+  char *fmt;
+  va_list arg;
+  va_start(arg);
+  fmt = va_arg(arg, char *);
+  vfinfo(stderr, fmt, arg);
+  va_end(arg);
+}
 
 void 
 info_assert(file, line)
 char *file;
 unsigned int line;
 {
-  info("%F%P internal error %s %d\n", file,line);
+  einfo("%F%P internal error %s %d\n", file,line);
 }
 
 /* Return a newly-allocated string
@@ -240,9 +285,9 @@ DEFUN(concat, (s1, s2, s3),
       CONST char *s2 AND
       CONST char *s3)
 {
-  size_t len1 = strlen (s1);
-  size_t len2 = strlen (s2);
-  size_t len3 = strlen (s3);
+  bfd_size_type len1 = strlen (s1);
+  bfd_size_type len2 = strlen (s2);
+  bfd_size_type len3 = strlen (s3);
   char *result = ldmalloc (len1 + len2 + len3 + 1);
 
   if (len1 != 0)
@@ -258,13 +303,14 @@ DEFUN(concat, (s1, s2, s3),
 
 
 
-char  *ldmalloc (size)
-size_t size;
+PTR
+DEFUN(ldmalloc, (size),
+bfd_size_type size)
 {
-  char * result =  malloc (size);
+  PTR result =  malloc ((int)size);
 
   if (result == (char *)NULL && size != 0)
-    info("%F%P virtual memory exhausted\n");
+    einfo("%F%P virtual memory exhausted\n");
 
   return result;
 } 
@@ -274,8 +320,30 @@ size_t size;
 char *DEFUN(buystring,(x),
            CONST char *CONST x)
 {
-  size_t  l = strlen(x)+1;
+  bfd_size_type  l = strlen(x)+1;
   char *r = ldmalloc(l);
   memcpy(r, x,l);
   return r;
 }
+
+
+/*----------------------------------------------------------------------
+  Functions to print the link map 
+ */
+
+void 
+DEFUN_VOID(print_space)
+{
+  printf(" ");
+}
+void 
+DEFUN_VOID(print_nl)
+{
+  printf("\n");
+}
+void 
+DEFUN(print_address,(value),
+      bfd_vma value)
+{
+  printf_vma(value);
+}
index 4ad9476..5d75c69 100644 (file)
@@ -214,32 +214,46 @@ lang_input_statement_type *f;
 {
   fprintf (stdout, "  %s\n", f->filename);
   if (f->just_syms_flag) 
-      {
-       fprintf (stdout, " symbols only\n");
-      }
+  {
+    fprintf (stdout, " symbols only\n");
+  }
   else 
-      {
-       asection *s;
-       if (true || option_longmap) {
-         for (s = f->the_bfd->sections;
-              s != (asection *)NULL;
-              s = s->next) {
+  {
+    asection *s;
+    if (true || option_longmap) {
+       for (s = f->the_bfd->sections;
+            s != (asection *)NULL;
+            s = s->next) {
            print_address(s->output_offset);
-           printf (" %08x 2**%2ud %s\n",
-                   (unsigned)s->size, s->alignment_power, s->name);
+           if (s->flags & SEC_HAS_CONTENTS) 
+           {
+             printf (" %08x 2**%2ud %s\n",
+                     (unsigned)bfd_get_section_size_after_reloc(s),
+                     s->alignment_power, s->name);
+           }
+           
+           else 
+           {
+             printf (" %08x 2**%2ud %s\n",
+                     (unsigned)bfd_get_section_size_before_reloc(s),
+                     s->alignment_power, s->name);
+           }
+           
+
+             
          }
-       }
-       else {        
-         for (s = f->the_bfd->sections;
-              s != (asection *)NULL;
-              s = s->next) {
+      }
+    else {           
+       for (s = f->the_bfd->sections;
+            s != (asection *)NULL;
+            s = s->next) {
            printf("%s ", s->name);
            print_address(s->output_offset);
-           printf("(%x)", (unsigned)s->size);
+           printf("(%x)", (unsigned)bfd_get_section_size_after_reloc(s));
          }
-         printf("hex \n");
-       }
+       printf("hex \n");
       }
+  }
   fprintf (stdout, "\n");
 }
 
@@ -345,7 +359,7 @@ LANG_FOR_EACH_INPUT_STATEMENT(entry)
        {
          asymbol *p = entry->asymbols[i];
 
-         if (flag_is_global(p->flags) || flag_is_absolute(p->flags))
+         if (flag_is_global(p->flags) )
            {
              /* We are only interested in outputting 
                 globals at this stage in special circumstances */
@@ -376,10 +390,10 @@ LANG_FOR_EACH_INPUT_STATEMENT(entry)
                  *output_buffer++ = p;
                }
              }
-           else if (flag_is_undefined(p->flags)) 
+           else if (p->section == &bfd_und_section)
              { /* This must be global */
              }
-           else if (flag_is_common(p->flags)) {
+           else if (p->section == &bfd_com_section) {
           /* And so must this */
            } 
            else if (p->flags & BSF_CTOR) {