* Makefile.in: added relax, also made three stage go through a
authorSteve Chamberlain <sac@cygnus>
Fri, 24 Jan 1992 22:34:34 +0000 (22:34 +0000)
committerSteve Chamberlain <sac@cygnus>
Fri, 24 Jan 1992 22:34:34 +0000 (22:34 +0000)
partial link stage.
* relax.c : added
* config.h: if GNU960 defined, then default emulation mode is
GLD960
* ldexp.h, ldexp.c: map to file hooks
* ldlang.c: map to file hooks
* ldgram.y: added -Map -relax
* ldlex.l: added -relax, -Map
* ldmain.c: open map file
* ldmisc.c: support for map file
* ldwrite.c: new relax magic

ld/ChangeLog
ld/Makefile.in
ld/config.h
ld/ldexp.c
ld/ldgram.y
ld/ldlex.l
ld/ldmain.c
ld/ldwrite.c
ld/relax.c [new file with mode: 0644]

index d2154ff0dcbc03e0180ecb8ed9ab4a4fc0822037..8a0ee1de69b0764a20bbcbe7ae0c571c4f756a30 100644 (file)
@@ -1,3 +1,31 @@
+Fri Jan 24 14:23:46 1992  Steve Chamberlain  (sac at rtl.cygnus.com)
+
+       * Makefile.in: added relax, also made three stage go through a
+       partial link stage.
+       * relax.c : added
+       * config.h: if GNU960 defined, then default emulation mode is
+       GLD960
+       * ldexp.h, ldexp.c: map to file hooks
+       * ldlang.c: map to file hooks
+       * ldgram.y: added -Map -relax
+       * ldlex.l: added -relax, -Map
+       * ldmain.c: open map file
+       * ldmisc.c: support for map file
+       * ldwrite.c: new relax magic
+
+Thu Dec 19 18:49:51 1991  John Gilmore  (gnu at cygnus.com)
+
+       * Makefile.in, config/tm-*.h:  Clean up make output, only
+       pass DEFAULT_EMULATION to ldmain.c.
+
+Wed Dec 18 15:02:47 1991  Per Bothner  (bothner at cygnus.com)
+
+       * ldver.c:  Bump to version 1.94.
+
+Tue Dec 10 04:07:23 1991  K. Richard Pixley  (rich at rtl.cygnus.com)
+
+       * Makefile.in: infodir belongs in datadir.
+
 Mon Dec  9 16:26:43 1991  Per Bothner  (bothner at cygnus.com)
 
        * Makefile.in:  Pass -y to bison.  (Again;
index 62db9e20c13fddd224646a16c22c832e7aa05be8..d82aa44335ca8afb5e866644c0189ade35813116 100644 (file)
@@ -17,9 +17,6 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-#
-# $Id$
-#
 
 srcdir = .
 
@@ -166,7 +163,9 @@ LIBIBERTY=$(unsubdir)/../libiberty$(subdir)/libiberty.a
 OFILES= ldgram.o ldlex.o ldlang.o ldctor.o ldmain.o ldindr.o \
        ldwarn.o ldwrite.o ldexp.o ldlnk960.o ld__gld68k.o ld__i386aout.o \
        ld__m88k.o ld__glda29k.o ld__news.o h8300hds.o ld__ebmon29k.o \
-       ld__gld.o ldgld960.o ldemul.o ldver.o ldmisc.o ldsym.o ldvanilla.o ldfile.o
+       ld__gld.o ldgld960.o ldemul.o ldver.o ldmisc.o ldsym.o \
+       ldvanilla.o ldfile.o \
+       relax.o  lderror.o
 
 HEADERS=config.h ldmain.h ldmain.h ldwarn.h ldmisc.h ldindr.h \
        ldsym.h ldctor.h ldlang.h ldexp.h \
@@ -176,7 +175,8 @@ MANSOURCES=ld.tex
 
 LDCSOURCES=ldlang.c ldctor.c ldindr.c ldmain.c ldwrite.c ldwarn.c ldlnk960.c \
        ld__gld.c ld__gld68k.c ld__m88k.c ld__ebmon29k.c \
-       ldgld960.c ldemul.c ldver.c ldmisc.c ldexp.c ldsym.c ldfile.c ldvanilla.c
+       ldgld960.c ldemul.c ldver.c ldmisc.c ldexp.c ldsym.c ldfile.c \
+       ldvanilla.c relax.c  lderror.c
 
 GENERATED_SOURCES=ldgram.c ldlex.c ldgram.h ld__*.c
 GENERATED_HEADERS=ldgram.h
@@ -202,10 +202,6 @@ ldgram.h ldgram.c: ldgram.y
 ldlex.c: ldlex.l
        lex -t $(VPATH)/ldlex.l >ldlex.c 
 
-# Main needs to know the default emulation type, too.
-ldmain.o: ldmain.c
-       $(CC) $(CFLAGS) -DDEFAULT_EMULATION=$(EMUL) -c $<
-
 # These all start with ld__ so 'make clean' can find them.
 
 ld__gld.c: $(srcdir)/ldtemplate
@@ -269,7 +265,9 @@ ld1: ld.new
        $(HOSTING_EMU); ./ld.new -o ld1 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
 
 ld2: ld1
-       $(HOSTING_EMU); ./ld1 -o ld2 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
+       #try and make life a bit harder
+       $(HOSTING_EMU); ./ld1 -o foo.o -r $(OFILES)
+       $(HOSTING_EMU); ./ld1 -o ld2 $(HOSTING_CRT0) foo.o $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
 
 ld3: ld2
        $(HOSTING_EMU); ./ld2 -o ld3 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
index 50cc3ca470237a53b1c02517970e870d53d6c167..b1281567b1a6e2a49d6094f76a2a28b94d3ef8cb 100644 (file)
 #define EBMON29K_EMULATION_NAME "ebmon29k"
 #define GLDI386AOUT_EMULATION_NAME "gldi386aout"
 /* Otherwise default to this emulation */
+/* 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 */
index 849f2353af1a1395fe5831d654b40c60784b33a2..247de62be17f154698fee302cb3f657dfc8107a1 100644 (file)
@@ -55,8 +55,7 @@ extern bfd_vma print_dot;
 
 
 static void
-DEFUN(exp_print_token,(outfile, code),
-      FILE *outfile AND
+DEFUN(exp_print_token,( code),
       token_code_type code)
 {
   static struct  {
@@ -110,12 +109,12 @@ DEFUN(exp_print_token,(outfile, code),
   unsigned int idx;
   for (idx = 0; table[idx].name != (char*)NULL; idx++) {
     if (table[idx].code == code) {
-      fprintf(outfile, "%s", table[idx].name);
+      fprintf(config.map_file, "%s", table[idx].name);
       return;
     }
   }
   /* Not in table, just print it alone */
-  fprintf(outfile, "%c",code);
+  fprintf(config.map_file, "%c",code);
 }
 
 static void 
@@ -710,8 +709,7 @@ DEFUN(exp_assop,(code, dst, src),
 }
 
 void 
-DEFUN(exp_print_tree,(outfile, tree),
-      FILE *outfile AND
+DEFUN(exp_print_tree,(tree),
       etree_type *tree)
 {
   switch (tree->type.node_class) {
@@ -722,45 +720,45 @@ DEFUN(exp_print_tree,(outfile, tree),
   case etree_assign:
 #if 0
     if (tree->assign.dst->sdefs != (asymbol *)NULL){
-      fprintf(outfile,"%s (%x) ",tree->assign.dst->name,
+      fprintf(config.map_file,"%s (%x) ",tree->assign.dst->name,
              tree->assign.dst->sdefs->value);
     }
     else {
-      fprintf(outfile,"%s (UNDEFINED)",tree->assign.dst->name);
+      fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name);
     }
 #endif
-    fprintf(outfile,"%s ",tree->assign.dst);
-    exp_print_token(outfile,tree->type.node_code);
-    exp_print_tree(outfile,tree->assign.src);
+    fprintf(config.map_file,"%s ",tree->assign.dst);
+    exp_print_token(tree->type.node_code);
+    exp_print_tree(tree->assign.src);
     break;
   case etree_binary:
-    exp_print_tree(outfile,tree->binary.lhs);
-    exp_print_token(outfile,tree->type.node_code);
-    exp_print_tree(outfile,tree->binary.rhs);
+    exp_print_tree(tree->binary.lhs);
+    exp_print_token(tree->type.node_code);
+    exp_print_tree(tree->binary.rhs);
     break;
   case etree_trinary:
-    exp_print_tree(outfile,tree->trinary.cond);
-    fprintf(outfile,"?");
-    exp_print_tree(outfile,tree->trinary.lhs);
-    fprintf(outfile,":");
-    exp_print_tree(outfile,tree->trinary.rhs);
+    exp_print_tree(tree->trinary.cond);
+    fprintf(config.map_file,"?");
+    exp_print_tree(tree->trinary.lhs);
+    fprintf(config.map_file,":");
+    exp_print_tree(tree->trinary.rhs);
     break;
   case etree_unary:
-    exp_print_token(outfile,tree->unary.type.node_code);
-    fprintf(outfile,"(");
-    exp_print_tree(outfile,tree->unary.child);
-    fprintf(outfile,")");
+    exp_print_token(tree->unary.type.node_code);
+    fprintf(config.map_file,"(");
+    exp_print_tree(tree->unary.child);
+    fprintf(config.map_file,")");
     break;
   case etree_undef:
-    fprintf(outfile,"????????");
+    fprintf(config.map_file,"????????");
     break;
   case etree_name:
     if (tree->type.node_code == NAME) {
-      fprintf(outfile,"%s", tree->name.name);
+      fprintf(config.map_file,"%s", tree->name.name);
     }
     else {
-      exp_print_token(outfile,tree->type.node_code);
-      fprintf(outfile,"(%s)", tree->name.name);
+      exp_print_token(tree->type.node_code);
+      fprintf(config.map_file,"(%s)", tree->name.name);
     }
     break;
   default:
index a5b1731c1b50c510f3748301ad54299f9d8a0c74..d342da1d74003fd8a554aa3768c79c9d14af3ca2 100644 (file)
@@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 %{
 /*
- * $Id$
+
  */
 
 #define DONTDECLARE_MALLOC
@@ -136,7 +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_V OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT NOFLOAT 
+%token OPTION_v OPTION_V OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT  NOFLOAT 
+%token OPTION_Map
 %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 
@@ -185,6 +186,12 @@ command_line_option:
        |       OPTION_t {
                        trace_files = true;
                        }
+       |     OPTION_Map  NAME
+               {
+               write_map = true;
+               config.map_filename = $2;
+               }
+
        |       OPTION_M {
                        if (write_map) {
                            option_longmap = true;
index 9967b69a18981d067bf5a703f992facddce22dc1..cf7fd47a88c5e91a42b909d7dbee6d254f750f75 100644 (file)
@@ -5,7 +5,7 @@ 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,
@@ -28,22 +28,23 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /*SUPPRESS 529*/
 /*SUPPRESS 26*/
 /*SUPPRESS 29*/
-#define LEXDEBUG 0
-#include "sysdep.h"
+/*#define LEXDEBUG 0*/
 #include "bfd.h"
+#include "sysdep.h"
 
 #include <ctype.h>
 #include "ldlex.h"
 
 #include "ld.h"
 #include "ldexp.h"
-#include "ldgramtb.h"
+#include "ldgram.h"
 #include "ldmisc.h"
 
 #undef input
 #undef unput
 #define input lex_input
 #define unput lex_unput
+
 int debug;
 
 
@@ -81,6 +82,7 @@ keyword_type keywords[] =
 "INPUT",INPUT,
 "DEFINED",DEFINED,
 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
+"CONSTRUCTORS", CONSTRUCTORS,
 "FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
 "SECTIONS",SECTIONS,
 "FILL",FILL,
@@ -94,6 +96,13 @@ keyword_type keywords[] =
 "SHORT", SHORT,
 "BYTE", BYTE,
 "NOFLOAT",NOFLOAT,
+
+"NOLOAD",NOLOAD,
+"DSECT",DSECT,
+"COPY",COPY,
+"INFO",INFO,
+"OVERLAY",OVERLAY,
+
 "o",ORIGIN,
 "org",ORIGIN,
 "l", LENGTH,
@@ -275,7 +284,9 @@ WHITE               [ \t]+
 "\ -sort_common\ " { return OPTION_sort_common;}
 "\ -format\ " { return OPTION_format; }
 "\ -n\ "               { return OPTION_n; }
+"\ -N\ "               { return OPTION_N; }
 "\ -r\ "               { return OPTION_r; }
+"\ -relax\ "           { return OPTION_relax; }
 "\ -i\ "               { return OPTION_r; }
 "\ -Ur\ "              { return OPTION_Ur; }
 "\ -o\ "               { return OPTION_o; }
@@ -286,7 +297,9 @@ WHITE               [ \t]+
 "\ -dp\ "              { return OPTION_dp; }
 "\ -d\ "               { return OPTION_d; }
 "\ -v\ "               { return OPTION_v; }
+"\ -V\ "               { return OPTION_V; }
 "\ -M\ "               { return OPTION_M; }
+"\ -Map\ "              { return OPTION_Map;}
 "\ -t\ "               { return OPTION_t; }
 "\ -X\ "               { return OPTION_X; }
 "\ -x\ "               { return OPTION_x; }
@@ -295,6 +308,7 @@ WHITE               [ \t]+
 "\ -u\ "               { return OPTION_u; }
 "\ -s\ "            { return OPTION_s; }
 "\ -S\ "            { return OPTION_S; }
+"\ -Bstatic"  { return OPTION_Bstatic; }
 "\ -B{FILENAME}\ "    { /* Ignored */ }
 "\ -l"{FILENAME} {
                yylval.name = buystring(yytext+3);
@@ -382,7 +396,7 @@ WHITE               [ \t]+
 "]"            { RTOKEN(']');}
 "["            { RTOKEN('[');}
 ":"            { RTOKEN(':'); }
-";"            { RTOKEN('\;');}
+";"            { RTOKEN(';');}
 "-"            { RTOKEN('-');}
 
 
index 99526a006f3ce7d5774684d1dd5aa19b0b4432f9..a83385e690b0e6339efbc7b034ca299ff5bd2f77 100644 (file)
@@ -190,6 +190,17 @@ main (argc, argv)
   }
 
   ldemul_after_parse();
+      if (config.map_filename) 
+      {
+       config.map_file = fopen(config.map_filename, FOPEN_WT);
+       if (config.map_file == (FILE *)NULL) 
+       {
+         einfo("%P%F: can't open map file %s\n",
+               config.map_filename);
+       }
+      }
+      else config.map_file = stdout;   
+
   lang_process();
 
   /* Print error messages for any missing symbols, for any warning
index 6e1603a246753f4e8209044c02f498456f965511..0f545d09d1995255508fb22bf1715c53b15809b0 100644 (file)
@@ -2,19 +2,19 @@
    
 This file is part of GLD, the Gnu Linker.
 
-GLD is free software; you can redistribute it and/or modify
+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 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-GLD is distributed in the hope that it will be useful,
+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 GLD; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /*
  * $Id$ 
@@ -40,19 +40,19 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 */
 
 
-#include "sysdep.h"
 #include "bfd.h"
+#include "sysdep.h"
 
 #include "ldlang.h"
 #include "ld.h"
 #include "ldwrite.h"
 #include "ldmisc.h"
 #include "ldsym.h"
-#include "ldgram.tab.h"
+#include "ldgram.h"
+
 
 
 
-char *ldmalloc();
 /* Static vars for do_warnings and subroutines of it */
 int list_unresolved_refs;      /* List unresolved refs */
 int list_warning_symbols;      /* List warning syms */
@@ -74,26 +74,27 @@ void lang_for_each_statement(void (*func)());
 void lang_for_each_statement();
 #endif /* __STDC__ */
 
-extern size_t largest_section;
+extern bfd_size_type largest_section;
 ld_config_type config;
 
 extern unsigned int global_symbol_count;
 
 boolean trace_files;
 
-static void perform_relocation(input_bfd,
-                              input_section,
-                              data,
-                              symbols)
-bfd *input_bfd;
-asection *input_section;
-PTR data;
-asymbol **symbols;
+static void 
+DEFUN(perform_relocation,(input_bfd,
+                         input_section,
+                         data,
+                         symbols),
+      bfd *input_bfd AND
+      asection *input_section AND
+      PTR data AND
+      asymbol **symbols)
 {
   static asymbol *error_symbol = (asymbol *)NULL;
   static unsigned int error_count = 0;
 #define MAX_ERRORS_IN_A_ROW 5
-  size_t reloc_size = get_reloc_upper_bound(input_bfd, input_section);
+  bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd, input_section);
 
   arelent **reloc_vector = (arelent **)ldmalloc(reloc_size);
   arelent **parent;
@@ -101,6 +102,9 @@ asymbol **symbols;
   asection *os = input_section->output_section;
   if (config.relocateable_output == false) ob = (bfd *)NULL;
 
+  input_section->_cooked_size = input_section->_raw_size;
+  input_section->reloc_done = 1;
+  
   if (bfd_canonicalize_reloc(input_bfd, 
                             input_section,
                             reloc_vector,
@@ -109,7 +113,7 @@ asymbol **symbols;
       for (parent = reloc_vector; *parent; parent++) 
        {
 
-         bfd_reloc_status_enum_type r=
+         bfd_reloc_status_type r=
            bfd_perform_relocation(input_bfd,
                                   *parent,
                                   data,
@@ -119,6 +123,11 @@ asymbol **symbols;
          if (r == bfd_reloc_ok) {
            if (ob != (bfd *)NULL) {
              /* A parital link, so keep the relocs */
+
+             /* Add to each relocation the offset of where it lives
+                in the output section */
+/*           (*parent)->address += input_section->output_offset;*/
+
              os->orelocation[os->reloc_count] = *parent;
              os->reloc_count++;
            }
@@ -153,49 +162,35 @@ asymbol **symbols;
                    error_symbol = s;
                  }
                  if (error_count < MAX_ERRORS_IN_A_ROW) {
-                   info("%C: undefined reference to `%T'\n",
-                        input_bfd,
-                        input_section,
-                        symbols,
-                        (*parent)->address,
-                        s);
+                   einfo("%C: undefined reference to `%T'\n",
+                         input_bfd, input_section, symbols,
+                         (*parent)->address, s);
                    config.make_executable = false;
                  }
                  else if (error_count == MAX_ERRORS_IN_A_ROW) {
-                   info("%C: more undefined references to `%T' follow\n",
-                        input_bfd,
-                        input_section,
-                        symbols,
-                        (*parent)->address,
-                        s);
+                   einfo("%C: more undefined references to `%T' follow\n",
+                         input_bfd, input_section,
+                         symbols, (*parent)->address, s);
                  }                 
                  else {
                    /* Don't print any more */
                  }
                  break;
                case bfd_reloc_dangerous: 
-                 info("%B: relocation may be wrong `%T'\n",
-                      input_bfd,
-                      s);
+                 einfo("%B: relocation may be wrong `%T'\n",
+                       input_bfd, s);
                  break;
                case bfd_reloc_outofrange:
-                 info("%B:%s relocation address out of range %T (%V)\n",
-                      input_bfd,
-                      input_section->name,
-                      s,
-                      p->address); 
+                 einfo("%B:%s relocation address out of range %T (%V)\n",
+                       input_bfd, input_section->name, s, p->address); 
                  break;
                case bfd_reloc_overflow:
-                 info("%B:%s relocation overflow in %T reloc type %d\n",
-                      input_bfd,
-                      input_section->name,
-                      s,
-                      p->howto->type);
+                 einfo("%B:%s relocation overflow in %T reloc type %d\n",
+                       input_bfd, input_section->name, s, p->howto->type);
                  break;
                default:
-                 info("%F%B: relocation error, symbol `%T'\n",
-                      input_bfd,
-                      s);
+                 einfo("%F%B: relocation error, symbol `%T'\n",
+                       input_bfd, s);
                  break;
                }
            }
@@ -212,8 +207,8 @@ asymbol **symbols;
 PTR data_area;
 
 static void
-copy_and_relocate(statement)
-lang_statement_union_type *statement;
+DEFUN(copy_and_relocate,(statement),
+      lang_statement_union_type *statement)
 {
   switch (statement->header.type) {
   case lang_fill_statement_enum: 
@@ -252,18 +247,18 @@ lang_statement_union_type *statement;
     {
       bfd_vma value = statement->data_statement.value;
       bfd_byte play_area[LONG_SIZE];
-      unsigned int size;
+      unsigned int size = 0;
       switch (statement->data_statement.type) {
       case LONG:
-       bfd_putlong(output_bfd, value,  play_area);
+       bfd_put_32(output_bfd, value,  play_area);
        size = LONG_SIZE;
        break;
       case SHORT:
-       bfd_putshort(output_bfd, value,  play_area);
+       bfd_put_16(output_bfd, value,  play_area);
        size = SHORT_SIZE;
        break;
       case BYTE:
-       bfd_putchar(output_bfd, value,  play_area);
+       bfd_put_8(output_bfd, value,  play_area);
        size = BYTE_SIZE;
        break;
       }
@@ -289,17 +284,19 @@ lang_statement_union_type *statement;
        if (ifile->just_syms_flag == false) {
          bfd *inbfd = ifile->the_bfd;
 
-         if (output_section->flags & SEC_LOAD && i->size != 0) 
+         if (output_section->flags & SEC_LOAD &&
+             output_section->flags & SEC_ALLOC
+             && bfd_get_section_size_before_reloc(i) != 0) 
              {
                if(bfd_get_section_contents(inbfd,
                                            i,
                                            data_area,
-                                           0L,
-                                           i->size) == false) 
+                                           (file_ptr)0,
+                                           bfd_get_section_size_before_reloc(i)) == false) 
                    {
-                     info("%F%B error reading section contents %E\n",
-                          inbfd);
+                     einfo("%F%B error reading section contents %E\n", inbfd);
                    }
+               /* Set the reloc bit */
                perform_relocation (inbfd,  i,  data_area, ifile->asymbols);
 
 
@@ -307,10 +304,10 @@ lang_statement_union_type *statement;
                                            output_section,
                                            data_area,
                                            (file_ptr)i->output_offset,
-                                           i->size) == false) 
+                                           bfd_get_section_size_after_reloc(i)) == false) 
                    {
-                     info("%F%B error writing section contents of %E\n",
-                          output_bfd);
+                     einfo("%F%B error writing section contents of %E\n",
+                           output_bfd);
                    }
 
              }
@@ -327,22 +324,23 @@ lang_statement_union_type *statement;
 }
 
 void
-write_norel()
+DEFUN_VOID(write_norel)
 {
   /* Output the text and data segments, relocating as we go.  */
   lang_for_each_statement(copy_and_relocate);
 }
 
 
-static void read_relocs(abfd, section, symbols)
-bfd *abfd;
-asection *section;
-asymbol **symbols;
+static void 
+DEFUN(read_relocs,(abfd, section, symbols),
+      bfd *abfd AND
+      asection *section AND
+      asymbol **symbols)
 {
   /* Work out the output section ascociated with this input section */
   asection *output_section = section->output_section;
 
-  size_t reloc_size = get_reloc_upper_bound(abfd, section);
+  bfd_size_type reloc_size = bfd_get_reloc_upper_bound(abfd, section);
   arelent **reloc_vector = (arelent **)ldmalloc(reloc_size);
 
   if (bfd_canonicalize_reloc(abfd, 
@@ -354,8 +352,8 @@ asymbol **symbols;
 }
 
 
-static void
-write_rel()
+static  void
+DEFUN_VOID(write_rel)
 {
   /*
      Run through each section of each file and work work out the total
@@ -376,7 +374,7 @@ write_rel()
   LANG_FOR_EACH_OUTPUT_SECTION
     (section, 
      (section->orelocation =
-      (arelent **)ldmalloc((size_t)(sizeof(arelent **)*
+      (arelent **)ldmalloc((bfd_size_type)(sizeof(arelent **)*
                                    section->reloc_count)),
       section->reloc_count = 0,
      section->flags |= SEC_HAS_CONTENTS));
@@ -389,19 +387,28 @@ write_rel()
 }
 
 void
-ldwrite ()
+DEFUN(ldwrite, (write_map),
+      boolean write_map)
 {
   data_area = (PTR) ldmalloc(largest_section);
   if (config.relocateable_output == true)
-    {
-      write_rel();
-    }
+      {
+       write_rel();
+      }
   else 
-    {
-    write_norel();
-  }
+      {
+       write_relaxnorel(output_bfd);
+      }
   free(data_area);
   /* Output the symbol table (both globals and locals).  */
+
+  /* Print a map, if requested.  */
+
+  if (write_map) {
+    ldsym_print_symbol_table ();
+    lang_map(stdout);
+  }
+
   ldsym_write ();
 
 }
diff --git a/ld/relax.c b/ld/relax.c
new file mode 100644 (file)
index 0000000..6db5590
--- /dev/null
@@ -0,0 +1,299 @@
+
+
+/* 
+new age linking
+
+
+Tie together all the interseting blocks 
+
+*/
+
+
+#include "bfd.h"
+#include "../bfd/seclet.h"
+#include "coff/internal.h"
+#include "sysdep.h"
+
+#include "ldlang.h"
+#include "ld.h"
+#include "ldwrite.h"
+#include "ldmisc.h"
+#include "ldsym.h"
+#include "ldgram.h"
+
+static void
+DEFUN(build_it,(statement),
+      lang_statement_union_type *statement)
+{
+  switch (statement->header.type) {
+  case lang_fill_statement_enum: 
+      {
+#if 0
+      bfd_byte play_area[SHORT_SIZE];
+      unsigned int i;
+      bfd_putshort(output_bfd, statement->fill_statement.fill, play_area);
+      /* Write out all entire shorts */
+      for (i = 0;
+          i < statement->fill_statement.size - SHORT_SIZE + 1;
+          i+= SHORT_SIZE)
+       {
+         bfd_set_section_contents(output_bfd,
+                                  statement->fill_statement.output_section,
+                                  play_area,
+                                  statement->data_statement.output_offset +i,
+                                  SHORT_SIZE);
+
+       }
+
+      /* Now write any remaining byte */
+      if (i < statement->fill_statement.size) 
+       {
+         bfd_set_section_contents(output_bfd,
+                                  statement->fill_statement.output_section,
+                                  play_area,
+                                  statement->data_statement.output_offset +i,
+                                  1);
+
+       }
+#endif
+    }
+    break;
+  case lang_data_statement_enum:
+    {
+abort();
+      
+#if 0
+      bfd_vma value = statement->data_statement.value;
+      bfd_byte play_area[LONG_SIZE];
+      unsigned int size = 0;
+      switch (statement->data_statement.type) {
+      case LONG:
+       bfd_put_32(output_bfd, value,  play_area);
+       size = LONG_SIZE;
+       break;
+      case SHORT:
+       bfd_put_16(output_bfd, value,  play_area);
+       size = SHORT_SIZE;
+       break;
+      case BYTE:
+       bfd_put_8(output_bfd, value,  play_area);
+       size = BYTE_SIZE;
+       break;
+      }
+      
+      bfd_set_section_contents(output_bfd,
+                              statement->data_statement.output_section,
+                              play_area,
+                              statement->data_statement.output_vma,
+                              size);
+                              
+                              
+#endif
+
+    }
+    break;
+  case lang_input_section_enum:
+      {
+       /* Create a new seclet in the output section with this
+          attached */
+
+       asection *i  = statement->input_section.section;
+
+       asection *output_section = i->output_section;
+       
+       bfd_seclet_type *seclet  = bfd_new_seclet(output_section->owner,output_section);
+       
+       seclet->type = bfd_indirect_seclet;
+       seclet->u.indirect.section = i;
+       seclet->u.indirect.symbols = statement->input_section.ifile->asymbols;
+       seclet->size = bfd_get_section_size_before_reloc(i);
+       seclet->offset = i->output_offset;
+       seclet->next = 0;
+       
+      }
+    break;
+
+  default:
+    /* All the other ones fall through */
+    ;
+
+  }
+
+
+
+}
+
+
+void 
+DEFUN(write_relaxnorel,(output_bfd),
+      bfd *output_bfd)
+{
+/* Tie up all the statements to generate an output bfd structure which
+   bfd can mull over */
+
+
+  lang_for_each_statement(build_it);
+
+  seclet_dump(output_bfd);
+
+}
+
+
+    
+static void
+DEFUN(perform_slip,(s, slip, input_section, value),
+      asymbol **s AND
+      unsigned int slip AND
+      asection *input_section AND
+      bfd_vma value)
+{
+  
+  /* Find all symbols past this point, and make them know
+     what's happened */
+  while (*s) 
+  {
+    asymbol *p = *s;
+    if (p->section == input_section) 
+    {
+      /* This was pointing into this section, so mangle it */
+      if (p->value > value)
+      {
+       p->value -=2;
+      }
+    }
+    s++;
+       
+  }    
+}
+static int 
+DEFUN(movb1,(input_section, symbols, r, shrink),
+      asection *input_section AND
+      asymbol **symbols AND
+      arelent *r AND
+      unsigned int shrink) 
+{
+
+
+  bfd_vma value = get_value(r, input_section);
+       
+  if (value >= 0xff00)
+  { 
+
+    /* Change the reloc type from 16bit, possible 8 to 8bit
+       possible 16 */
+    r->howto = r->howto + 1;     
+    /* The place to relc moves back by one */
+    r->address -=1;
+         
+    /* This will be two bytes smaller in the long run */
+    shrink +=2 ;
+    perform_slip(symbols, 2, input_section, r->address - shrink +1);
+
+         
+  }      
+  return shrink;      
+}
+
+static int 
+DEFUN(jmp1,(input_section, symbols, r, shrink),
+      asection *input_section AND
+      asymbol **symbols AND
+      arelent *r AND
+      unsigned int shrink) 
+{
+
+  
+  bfd_vma value = get_value(r, 0);
+       
+  bfd_vma dot = input_section->output_section->vma +
+   input_section->output_offset + r->address;  
+  bfd_vma gap;
+  
+    /* See if the address we're looking at within 127 bytes of where
+       we are, if so then we can use a small branch rather than the
+       jump we were going to */
+
+  gap = value - (dot - shrink);
+  
+
+  if (-120 < (long)gap && (long)gap < 120 )
+  { 
+
+    /* Change the reloc type from 16bit, possible 8 to 8bit
+       possible 16 */
+    r->howto = r->howto + 1;     
+    /* The place to relc moves back by one */
+    r->address -=1;
+         
+    /* This will be two bytes smaller in the long run */
+    shrink +=2 ;
+    perform_slip(symbols, 2, input_section, r->address-shrink +1);
+
+         
+  }      
+  return shrink;      
+}
+
+
+/* See if we can change the size of this section by shrinking the
+   relocations in it. If this happens, then we'll have to renumber the
+   symbols in it, and shift around the data too.
+ */
+boolean
+DEFUN(relax_section,(this_ptr),
+      lang_statement_union_type **this_ptr)
+{
+
+  lang_input_section_type *is = &((*this_ptr)->input_section);
+  asection *i = is->section;
+
+  
+  /* Get enough memory to hold the stuff */
+  bfd *input_bfd = i->owner;
+  asection *input_section = i;
+  int shrink = 0 ;
+  int new = 0;
+  
+  bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
+                                                      input_section);
+  arelent **reloc_vector = (arelent **)ldmalloc(reloc_size);
+
+  /* Get the relocs and think about them */
+  if (bfd_canonicalize_reloc(input_bfd, 
+                            input_section,
+                            reloc_vector,
+                            is->ifile->asymbols) )
+  {
+    arelent **parent;
+    asymbol **symbols =   is->ifile->asymbols; 
+    for (parent = reloc_vector; *parent; parent++) 
+    {
+      arelent *r = *parent;
+      switch (r->howto->type) {
+       case R_MOVB2:
+       case R_JMP2:
+         
+         shrink+=2;
+         break;
+         
+       case R_MOVB1:
+         shrink = movb1(input_section, symbols, r, shrink);
+         new = 1;
+         
+         break;
+       case R_JMP1:
+         shrink = jmp1(input_section, symbols, r, shrink);
+         new = 1;
+         
+         break;
+       }
+    }
+
+  }
+  input_section->_cooked_size -= shrink;  
+  free((char *)reloc_vector);
+  return new;
+  
+}
+