* 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
This commit is contained in:
parent
2cbe4c5f9e
commit
2e2bf962db
9 changed files with 492 additions and 123 deletions
28
ld/ChangeLog
28
ld/ChangeLog
|
@ -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)
|
Mon Dec 9 16:26:43 1991 Per Bothner (bothner at cygnus.com)
|
||||||
|
|
||||||
* Makefile.in: Pass -y to bison. (Again;
|
* Makefile.in: Pass -y to bison. (Again;
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
srcdir = .
|
srcdir = .
|
||||||
|
|
||||||
|
@ -166,7 +163,9 @@ LIBIBERTY=$(unsubdir)/../libiberty$(subdir)/libiberty.a
|
||||||
OFILES= ldgram.o ldlex.o ldlang.o ldctor.o ldmain.o ldindr.o \
|
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 \
|
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__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 \
|
HEADERS=config.h ldmain.h ldmain.h ldwarn.h ldmisc.h ldindr.h \
|
||||||
ldsym.h ldctor.h ldlang.h ldexp.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 \
|
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 \
|
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_SOURCES=ldgram.c ldlex.c ldgram.h ld__*.c
|
||||||
GENERATED_HEADERS=ldgram.h
|
GENERATED_HEADERS=ldgram.h
|
||||||
|
@ -202,10 +202,6 @@ ldgram.h ldgram.c: ldgram.y
|
||||||
ldlex.c: ldlex.l
|
ldlex.c: ldlex.l
|
||||||
lex -t $(VPATH)/ldlex.l >ldlex.c
|
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.
|
# These all start with ld__ so 'make clean' can find them.
|
||||||
|
|
||||||
ld__gld.c: $(srcdir)/ldtemplate
|
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)
|
$(HOSTING_EMU); ./ld.new -o ld1 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
|
||||||
|
|
||||||
ld2: ld1
|
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
|
ld3: ld2
|
||||||
$(HOSTING_EMU); ./ld2 -o ld3 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
|
$(HOSTING_EMU); ./ld2 -o ld3 $(HOSTING_CRT0) $(OFILES) $(BFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
|
||||||
|
|
|
@ -33,8 +33,15 @@
|
||||||
#define EBMON29K_EMULATION_NAME "ebmon29k"
|
#define EBMON29K_EMULATION_NAME "ebmon29k"
|
||||||
#define GLDI386AOUT_EMULATION_NAME "gldi386aout"
|
#define GLDI386AOUT_EMULATION_NAME "gldi386aout"
|
||||||
/* Otherwise default to this emulation */
|
/* 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 */
|
/* Look in this variable for a target format */
|
||||||
|
|
52
ld/ldexp.c
52
ld/ldexp.c
|
@ -55,8 +55,7 @@ extern bfd_vma print_dot;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
DEFUN(exp_print_token,(outfile, code),
|
DEFUN(exp_print_token,( code),
|
||||||
FILE *outfile AND
|
|
||||||
token_code_type code)
|
token_code_type code)
|
||||||
{
|
{
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -110,12 +109,12 @@ DEFUN(exp_print_token,(outfile, code),
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
for (idx = 0; table[idx].name != (char*)NULL; idx++) {
|
for (idx = 0; table[idx].name != (char*)NULL; idx++) {
|
||||||
if (table[idx].code == code) {
|
if (table[idx].code == code) {
|
||||||
fprintf(outfile, "%s", table[idx].name);
|
fprintf(config.map_file, "%s", table[idx].name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Not in table, just print it alone */
|
/* Not in table, just print it alone */
|
||||||
fprintf(outfile, "%c",code);
|
fprintf(config.map_file, "%c",code);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -710,8 +709,7 @@ DEFUN(exp_assop,(code, dst, src),
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DEFUN(exp_print_tree,(outfile, tree),
|
DEFUN(exp_print_tree,(tree),
|
||||||
FILE *outfile AND
|
|
||||||
etree_type *tree)
|
etree_type *tree)
|
||||||
{
|
{
|
||||||
switch (tree->type.node_class) {
|
switch (tree->type.node_class) {
|
||||||
|
@ -722,45 +720,45 @@ DEFUN(exp_print_tree,(outfile, tree),
|
||||||
case etree_assign:
|
case etree_assign:
|
||||||
#if 0
|
#if 0
|
||||||
if (tree->assign.dst->sdefs != (asymbol *)NULL){
|
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);
|
tree->assign.dst->sdefs->value);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(outfile,"%s (UNDEFINED)",tree->assign.dst->name);
|
fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
fprintf(outfile,"%s ",tree->assign.dst);
|
fprintf(config.map_file,"%s ",tree->assign.dst);
|
||||||
exp_print_token(outfile,tree->type.node_code);
|
exp_print_token(tree->type.node_code);
|
||||||
exp_print_tree(outfile,tree->assign.src);
|
exp_print_tree(tree->assign.src);
|
||||||
break;
|
break;
|
||||||
case etree_binary:
|
case etree_binary:
|
||||||
exp_print_tree(outfile,tree->binary.lhs);
|
exp_print_tree(tree->binary.lhs);
|
||||||
exp_print_token(outfile,tree->type.node_code);
|
exp_print_token(tree->type.node_code);
|
||||||
exp_print_tree(outfile,tree->binary.rhs);
|
exp_print_tree(tree->binary.rhs);
|
||||||
break;
|
break;
|
||||||
case etree_trinary:
|
case etree_trinary:
|
||||||
exp_print_tree(outfile,tree->trinary.cond);
|
exp_print_tree(tree->trinary.cond);
|
||||||
fprintf(outfile,"?");
|
fprintf(config.map_file,"?");
|
||||||
exp_print_tree(outfile,tree->trinary.lhs);
|
exp_print_tree(tree->trinary.lhs);
|
||||||
fprintf(outfile,":");
|
fprintf(config.map_file,":");
|
||||||
exp_print_tree(outfile,tree->trinary.rhs);
|
exp_print_tree(tree->trinary.rhs);
|
||||||
break;
|
break;
|
||||||
case etree_unary:
|
case etree_unary:
|
||||||
exp_print_token(outfile,tree->unary.type.node_code);
|
exp_print_token(tree->unary.type.node_code);
|
||||||
fprintf(outfile,"(");
|
fprintf(config.map_file,"(");
|
||||||
exp_print_tree(outfile,tree->unary.child);
|
exp_print_tree(tree->unary.child);
|
||||||
fprintf(outfile,")");
|
fprintf(config.map_file,")");
|
||||||
break;
|
break;
|
||||||
case etree_undef:
|
case etree_undef:
|
||||||
fprintf(outfile,"????????");
|
fprintf(config.map_file,"????????");
|
||||||
break;
|
break;
|
||||||
case etree_name:
|
case etree_name:
|
||||||
if (tree->type.node_code == NAME) {
|
if (tree->type.node_code == NAME) {
|
||||||
fprintf(outfile,"%s", tree->name.name);
|
fprintf(config.map_file,"%s", tree->name.name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exp_print_token(outfile,tree->type.node_code);
|
exp_print_token(tree->type.node_code);
|
||||||
fprintf(outfile,"(%s)", tree->name.name);
|
fprintf(config.map_file,"(%s)", tree->name.name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
%{
|
%{
|
||||||
/*
|
/*
|
||||||
* $Id$
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DONTDECLARE_MALLOC
|
#define DONTDECLARE_MALLOC
|
||||||
|
@ -137,6 +137,7 @@ boolean ldgram_had_equals = false;
|
||||||
%token <integer> SIZEOF NEXT ADDR
|
%token <integer> SIZEOF NEXT ADDR
|
||||||
%token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym
|
%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 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 <name> OPTION_l OPTION_L OPTION_T OPTION_Aarch OPTION_Tfile OPTION_Texp
|
||||||
%token OPTION_Ur
|
%token OPTION_Ur
|
||||||
|
@ -185,6 +186,12 @@ command_line_option:
|
||||||
| OPTION_t {
|
| OPTION_t {
|
||||||
trace_files = true;
|
trace_files = true;
|
||||||
}
|
}
|
||||||
|
| OPTION_Map NAME
|
||||||
|
{
|
||||||
|
write_map = true;
|
||||||
|
config.map_filename = $2;
|
||||||
|
}
|
||||||
|
|
||||||
| OPTION_M {
|
| OPTION_M {
|
||||||
if (write_map) {
|
if (write_map) {
|
||||||
option_longmap = true;
|
option_longmap = true;
|
||||||
|
|
24
ld/ldlex.l
24
ld/ldlex.l
|
@ -5,7 +5,7 @@ This file is part of GLD, the Gnu Linker.
|
||||||
|
|
||||||
GLD is free software; you can redistribute it and/or modify
|
GLD is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
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.
|
any later version.
|
||||||
|
|
||||||
GLD is distributed in the hope that it will be useful,
|
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 529*/
|
||||||
/*SUPPRESS 26*/
|
/*SUPPRESS 26*/
|
||||||
/*SUPPRESS 29*/
|
/*SUPPRESS 29*/
|
||||||
#define LEXDEBUG 0
|
/*#define LEXDEBUG 0*/
|
||||||
#include "sysdep.h"
|
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "ldlex.h"
|
#include "ldlex.h"
|
||||||
|
|
||||||
#include "ld.h"
|
#include "ld.h"
|
||||||
#include "ldexp.h"
|
#include "ldexp.h"
|
||||||
#include "ldgramtb.h"
|
#include "ldgram.h"
|
||||||
#include "ldmisc.h"
|
#include "ldmisc.h"
|
||||||
|
|
||||||
#undef input
|
#undef input
|
||||||
#undef unput
|
#undef unput
|
||||||
#define input lex_input
|
#define input lex_input
|
||||||
#define unput lex_unput
|
#define unput lex_unput
|
||||||
|
|
||||||
int debug;
|
int debug;
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,6 +82,7 @@ keyword_type keywords[] =
|
||||||
"INPUT",INPUT,
|
"INPUT",INPUT,
|
||||||
"DEFINED",DEFINED,
|
"DEFINED",DEFINED,
|
||||||
"CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
|
"CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
|
||||||
|
"CONSTRUCTORS", CONSTRUCTORS,
|
||||||
"FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
|
"FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
|
||||||
"SECTIONS",SECTIONS,
|
"SECTIONS",SECTIONS,
|
||||||
"FILL",FILL,
|
"FILL",FILL,
|
||||||
|
@ -94,6 +96,13 @@ keyword_type keywords[] =
|
||||||
"SHORT", SHORT,
|
"SHORT", SHORT,
|
||||||
"BYTE", BYTE,
|
"BYTE", BYTE,
|
||||||
"NOFLOAT",NOFLOAT,
|
"NOFLOAT",NOFLOAT,
|
||||||
|
|
||||||
|
"NOLOAD",NOLOAD,
|
||||||
|
"DSECT",DSECT,
|
||||||
|
"COPY",COPY,
|
||||||
|
"INFO",INFO,
|
||||||
|
"OVERLAY",OVERLAY,
|
||||||
|
|
||||||
"o",ORIGIN,
|
"o",ORIGIN,
|
||||||
"org",ORIGIN,
|
"org",ORIGIN,
|
||||||
"l", LENGTH,
|
"l", LENGTH,
|
||||||
|
@ -275,7 +284,9 @@ WHITE [ \t]+
|
||||||
"\ -sort_common\ " { return OPTION_sort_common;}
|
"\ -sort_common\ " { return OPTION_sort_common;}
|
||||||
"\ -format\ " { return OPTION_format; }
|
"\ -format\ " { return OPTION_format; }
|
||||||
"\ -n\ " { return OPTION_n; }
|
"\ -n\ " { return OPTION_n; }
|
||||||
|
"\ -N\ " { return OPTION_N; }
|
||||||
"\ -r\ " { return OPTION_r; }
|
"\ -r\ " { return OPTION_r; }
|
||||||
|
"\ -relax\ " { return OPTION_relax; }
|
||||||
"\ -i\ " { return OPTION_r; }
|
"\ -i\ " { return OPTION_r; }
|
||||||
"\ -Ur\ " { return OPTION_Ur; }
|
"\ -Ur\ " { return OPTION_Ur; }
|
||||||
"\ -o\ " { return OPTION_o; }
|
"\ -o\ " { return OPTION_o; }
|
||||||
|
@ -286,7 +297,9 @@ WHITE [ \t]+
|
||||||
"\ -dp\ " { return OPTION_dp; }
|
"\ -dp\ " { return OPTION_dp; }
|
||||||
"\ -d\ " { return OPTION_d; }
|
"\ -d\ " { return OPTION_d; }
|
||||||
"\ -v\ " { return OPTION_v; }
|
"\ -v\ " { return OPTION_v; }
|
||||||
|
"\ -V\ " { return OPTION_V; }
|
||||||
"\ -M\ " { return OPTION_M; }
|
"\ -M\ " { return OPTION_M; }
|
||||||
|
"\ -Map\ " { return OPTION_Map;}
|
||||||
"\ -t\ " { return OPTION_t; }
|
"\ -t\ " { return OPTION_t; }
|
||||||
"\ -X\ " { return OPTION_X; }
|
"\ -X\ " { return OPTION_X; }
|
||||||
"\ -x\ " { return OPTION_x; }
|
"\ -x\ " { return OPTION_x; }
|
||||||
|
@ -295,6 +308,7 @@ WHITE [ \t]+
|
||||||
"\ -u\ " { return OPTION_u; }
|
"\ -u\ " { return OPTION_u; }
|
||||||
"\ -s\ " { return OPTION_s; }
|
"\ -s\ " { return OPTION_s; }
|
||||||
"\ -S\ " { return OPTION_S; }
|
"\ -S\ " { return OPTION_S; }
|
||||||
|
"\ -Bstatic" { return OPTION_Bstatic; }
|
||||||
"\ -B{FILENAME}\ " { /* Ignored */ }
|
"\ -B{FILENAME}\ " { /* Ignored */ }
|
||||||
"\ -l"{FILENAME} {
|
"\ -l"{FILENAME} {
|
||||||
yylval.name = buystring(yytext+3);
|
yylval.name = buystring(yytext+3);
|
||||||
|
@ -382,7 +396,7 @@ WHITE [ \t]+
|
||||||
"]" { RTOKEN(']');}
|
"]" { RTOKEN(']');}
|
||||||
"[" { RTOKEN('[');}
|
"[" { RTOKEN('[');}
|
||||||
":" { RTOKEN(':'); }
|
":" { RTOKEN(':'); }
|
||||||
";" { RTOKEN('\;');}
|
";" { RTOKEN(';');}
|
||||||
"-" { RTOKEN('-');}
|
"-" { RTOKEN('-');}
|
||||||
|
|
||||||
|
|
||||||
|
|
11
ld/ldmain.c
11
ld/ldmain.c
|
@ -190,6 +190,17 @@ main (argc, argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
ldemul_after_parse();
|
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();
|
lang_process();
|
||||||
|
|
||||||
/* Print error messages for any missing symbols, for any warning
|
/* Print error messages for any missing symbols, for any warning
|
||||||
|
|
145
ld/ldwrite.c
145
ld/ldwrite.c
|
@ -2,19 +2,19 @@
|
||||||
|
|
||||||
This file is part of GLD, the Gnu Linker.
|
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
|
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 of the License, or
|
||||||
any later version.
|
(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
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with GLD; see the file COPYING. If not, write to
|
along with this program; if not, write to the Free Software
|
||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
|
@ -40,19 +40,19 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "sysdep.h"
|
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
#include "ldlang.h"
|
#include "ldlang.h"
|
||||||
#include "ld.h"
|
#include "ld.h"
|
||||||
#include "ldwrite.h"
|
#include "ldwrite.h"
|
||||||
#include "ldmisc.h"
|
#include "ldmisc.h"
|
||||||
#include "ldsym.h"
|
#include "ldsym.h"
|
||||||
#include "ldgram.tab.h"
|
#include "ldgram.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *ldmalloc();
|
|
||||||
/* Static vars for do_warnings and subroutines of it */
|
/* Static vars for do_warnings and subroutines of it */
|
||||||
int list_unresolved_refs; /* List unresolved refs */
|
int list_unresolved_refs; /* List unresolved refs */
|
||||||
int list_warning_symbols; /* List warning syms */
|
int list_warning_symbols; /* List warning syms */
|
||||||
|
@ -74,26 +74,27 @@ void lang_for_each_statement(void (*func)());
|
||||||
void lang_for_each_statement();
|
void lang_for_each_statement();
|
||||||
#endif /* __STDC__ */
|
#endif /* __STDC__ */
|
||||||
|
|
||||||
extern size_t largest_section;
|
extern bfd_size_type largest_section;
|
||||||
ld_config_type config;
|
ld_config_type config;
|
||||||
|
|
||||||
extern unsigned int global_symbol_count;
|
extern unsigned int global_symbol_count;
|
||||||
|
|
||||||
boolean trace_files;
|
boolean trace_files;
|
||||||
|
|
||||||
static void perform_relocation(input_bfd,
|
static void
|
||||||
|
DEFUN(perform_relocation,(input_bfd,
|
||||||
input_section,
|
input_section,
|
||||||
data,
|
data,
|
||||||
symbols)
|
symbols),
|
||||||
bfd *input_bfd;
|
bfd *input_bfd AND
|
||||||
asection *input_section;
|
asection *input_section AND
|
||||||
PTR data;
|
PTR data AND
|
||||||
asymbol **symbols;
|
asymbol **symbols)
|
||||||
{
|
{
|
||||||
static asymbol *error_symbol = (asymbol *)NULL;
|
static asymbol *error_symbol = (asymbol *)NULL;
|
||||||
static unsigned int error_count = 0;
|
static unsigned int error_count = 0;
|
||||||
#define MAX_ERRORS_IN_A_ROW 5
|
#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 **reloc_vector = (arelent **)ldmalloc(reloc_size);
|
||||||
arelent **parent;
|
arelent **parent;
|
||||||
|
@ -101,6 +102,9 @@ asymbol **symbols;
|
||||||
asection *os = input_section->output_section;
|
asection *os = input_section->output_section;
|
||||||
if (config.relocateable_output == false) ob = (bfd *)NULL;
|
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,
|
if (bfd_canonicalize_reloc(input_bfd,
|
||||||
input_section,
|
input_section,
|
||||||
reloc_vector,
|
reloc_vector,
|
||||||
|
@ -109,7 +113,7 @@ asymbol **symbols;
|
||||||
for (parent = reloc_vector; *parent; parent++)
|
for (parent = reloc_vector; *parent; parent++)
|
||||||
{
|
{
|
||||||
|
|
||||||
bfd_reloc_status_enum_type r=
|
bfd_reloc_status_type r=
|
||||||
bfd_perform_relocation(input_bfd,
|
bfd_perform_relocation(input_bfd,
|
||||||
*parent,
|
*parent,
|
||||||
data,
|
data,
|
||||||
|
@ -119,6 +123,11 @@ asymbol **symbols;
|
||||||
if (r == bfd_reloc_ok) {
|
if (r == bfd_reloc_ok) {
|
||||||
if (ob != (bfd *)NULL) {
|
if (ob != (bfd *)NULL) {
|
||||||
/* A parital link, so keep the relocs */
|
/* 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->orelocation[os->reloc_count] = *parent;
|
||||||
os->reloc_count++;
|
os->reloc_count++;
|
||||||
}
|
}
|
||||||
|
@ -153,49 +162,35 @@ asymbol **symbols;
|
||||||
error_symbol = s;
|
error_symbol = s;
|
||||||
}
|
}
|
||||||
if (error_count < MAX_ERRORS_IN_A_ROW) {
|
if (error_count < MAX_ERRORS_IN_A_ROW) {
|
||||||
info("%C: undefined reference to `%T'\n",
|
einfo("%C: undefined reference to `%T'\n",
|
||||||
input_bfd,
|
input_bfd, input_section, symbols,
|
||||||
input_section,
|
(*parent)->address, s);
|
||||||
symbols,
|
|
||||||
(*parent)->address,
|
|
||||||
s);
|
|
||||||
config.make_executable = false;
|
config.make_executable = false;
|
||||||
}
|
}
|
||||||
else if (error_count == MAX_ERRORS_IN_A_ROW) {
|
else if (error_count == MAX_ERRORS_IN_A_ROW) {
|
||||||
info("%C: more undefined references to `%T' follow\n",
|
einfo("%C: more undefined references to `%T' follow\n",
|
||||||
input_bfd,
|
input_bfd, input_section,
|
||||||
input_section,
|
symbols, (*parent)->address, s);
|
||||||
symbols,
|
|
||||||
(*parent)->address,
|
|
||||||
s);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Don't print any more */
|
/* Don't print any more */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case bfd_reloc_dangerous:
|
case bfd_reloc_dangerous:
|
||||||
info("%B: relocation may be wrong `%T'\n",
|
einfo("%B: relocation may be wrong `%T'\n",
|
||||||
input_bfd,
|
input_bfd, s);
|
||||||
s);
|
|
||||||
break;
|
break;
|
||||||
case bfd_reloc_outofrange:
|
case bfd_reloc_outofrange:
|
||||||
info("%B:%s relocation address out of range %T (%V)\n",
|
einfo("%B:%s relocation address out of range %T (%V)\n",
|
||||||
input_bfd,
|
input_bfd, input_section->name, s, p->address);
|
||||||
input_section->name,
|
|
||||||
s,
|
|
||||||
p->address);
|
|
||||||
break;
|
break;
|
||||||
case bfd_reloc_overflow:
|
case bfd_reloc_overflow:
|
||||||
info("%B:%s relocation overflow in %T reloc type %d\n",
|
einfo("%B:%s relocation overflow in %T reloc type %d\n",
|
||||||
input_bfd,
|
input_bfd, input_section->name, s, p->howto->type);
|
||||||
input_section->name,
|
|
||||||
s,
|
|
||||||
p->howto->type);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
info("%F%B: relocation error, symbol `%T'\n",
|
einfo("%F%B: relocation error, symbol `%T'\n",
|
||||||
input_bfd,
|
input_bfd, s);
|
||||||
s);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,8 +207,8 @@ asymbol **symbols;
|
||||||
PTR data_area;
|
PTR data_area;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copy_and_relocate(statement)
|
DEFUN(copy_and_relocate,(statement),
|
||||||
lang_statement_union_type *statement;
|
lang_statement_union_type *statement)
|
||||||
{
|
{
|
||||||
switch (statement->header.type) {
|
switch (statement->header.type) {
|
||||||
case lang_fill_statement_enum:
|
case lang_fill_statement_enum:
|
||||||
|
@ -252,18 +247,18 @@ lang_statement_union_type *statement;
|
||||||
{
|
{
|
||||||
bfd_vma value = statement->data_statement.value;
|
bfd_vma value = statement->data_statement.value;
|
||||||
bfd_byte play_area[LONG_SIZE];
|
bfd_byte play_area[LONG_SIZE];
|
||||||
unsigned int size;
|
unsigned int size = 0;
|
||||||
switch (statement->data_statement.type) {
|
switch (statement->data_statement.type) {
|
||||||
case LONG:
|
case LONG:
|
||||||
bfd_putlong(output_bfd, value, play_area);
|
bfd_put_32(output_bfd, value, play_area);
|
||||||
size = LONG_SIZE;
|
size = LONG_SIZE;
|
||||||
break;
|
break;
|
||||||
case SHORT:
|
case SHORT:
|
||||||
bfd_putshort(output_bfd, value, play_area);
|
bfd_put_16(output_bfd, value, play_area);
|
||||||
size = SHORT_SIZE;
|
size = SHORT_SIZE;
|
||||||
break;
|
break;
|
||||||
case BYTE:
|
case BYTE:
|
||||||
bfd_putchar(output_bfd, value, play_area);
|
bfd_put_8(output_bfd, value, play_area);
|
||||||
size = BYTE_SIZE;
|
size = BYTE_SIZE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -289,17 +284,19 @@ lang_statement_union_type *statement;
|
||||||
if (ifile->just_syms_flag == false) {
|
if (ifile->just_syms_flag == false) {
|
||||||
bfd *inbfd = ifile->the_bfd;
|
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,
|
if(bfd_get_section_contents(inbfd,
|
||||||
i,
|
i,
|
||||||
data_area,
|
data_area,
|
||||||
0L,
|
(file_ptr)0,
|
||||||
i->size) == false)
|
bfd_get_section_size_before_reloc(i)) == false)
|
||||||
{
|
{
|
||||||
info("%F%B error reading section contents %E\n",
|
einfo("%F%B error reading section contents %E\n", inbfd);
|
||||||
inbfd);
|
|
||||||
}
|
}
|
||||||
|
/* Set the reloc bit */
|
||||||
perform_relocation (inbfd, i, data_area, ifile->asymbols);
|
perform_relocation (inbfd, i, data_area, ifile->asymbols);
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,9 +304,9 @@ lang_statement_union_type *statement;
|
||||||
output_section,
|
output_section,
|
||||||
data_area,
|
data_area,
|
||||||
(file_ptr)i->output_offset,
|
(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",
|
einfo("%F%B error writing section contents of %E\n",
|
||||||
output_bfd);
|
output_bfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,22 +324,23 @@ lang_statement_union_type *statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
write_norel()
|
DEFUN_VOID(write_norel)
|
||||||
{
|
{
|
||||||
/* Output the text and data segments, relocating as we go. */
|
/* Output the text and data segments, relocating as we go. */
|
||||||
lang_for_each_statement(copy_and_relocate);
|
lang_for_each_statement(copy_and_relocate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void read_relocs(abfd, section, symbols)
|
static void
|
||||||
bfd *abfd;
|
DEFUN(read_relocs,(abfd, section, symbols),
|
||||||
asection *section;
|
bfd *abfd AND
|
||||||
asymbol **symbols;
|
asection *section AND
|
||||||
|
asymbol **symbols)
|
||||||
{
|
{
|
||||||
/* Work out the output section ascociated with this input section */
|
/* Work out the output section ascociated with this input section */
|
||||||
asection *output_section = section->output_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);
|
arelent **reloc_vector = (arelent **)ldmalloc(reloc_size);
|
||||||
|
|
||||||
if (bfd_canonicalize_reloc(abfd,
|
if (bfd_canonicalize_reloc(abfd,
|
||||||
|
@ -355,7 +353,7 @@ asymbol **symbols;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_rel()
|
DEFUN_VOID(write_rel)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Run through each section of each file and work work out the total
|
Run through each section of each file and work work out the total
|
||||||
|
@ -376,7 +374,7 @@ write_rel()
|
||||||
LANG_FOR_EACH_OUTPUT_SECTION
|
LANG_FOR_EACH_OUTPUT_SECTION
|
||||||
(section,
|
(section,
|
||||||
(section->orelocation =
|
(section->orelocation =
|
||||||
(arelent **)ldmalloc((size_t)(sizeof(arelent **)*
|
(arelent **)ldmalloc((bfd_size_type)(sizeof(arelent **)*
|
||||||
section->reloc_count)),
|
section->reloc_count)),
|
||||||
section->reloc_count = 0,
|
section->reloc_count = 0,
|
||||||
section->flags |= SEC_HAS_CONTENTS));
|
section->flags |= SEC_HAS_CONTENTS));
|
||||||
|
@ -389,7 +387,8 @@ write_rel()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ldwrite ()
|
DEFUN(ldwrite, (write_map),
|
||||||
|
boolean write_map)
|
||||||
{
|
{
|
||||||
data_area = (PTR) ldmalloc(largest_section);
|
data_area = (PTR) ldmalloc(largest_section);
|
||||||
if (config.relocateable_output == true)
|
if (config.relocateable_output == true)
|
||||||
|
@ -398,10 +397,18 @@ ldwrite ()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
write_norel();
|
write_relaxnorel(output_bfd);
|
||||||
}
|
}
|
||||||
free(data_area);
|
free(data_area);
|
||||||
/* Output the symbol table (both globals and locals). */
|
/* 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 ();
|
ldsym_write ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
299
ld/relax.c
Normal file
299
ld/relax.c
Normal file
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue