New lexer.

New targets for h8/300 simulator and DOS
This commit is contained in:
Steve Chamberlain 1992-04-05 01:47:16 +00:00
parent b2de19e3c6
commit 9d1fe8a410
17 changed files with 962 additions and 986 deletions

View File

@ -88,6 +88,7 @@ lnk960.em
lnk960.sh
m88kbcs.sc-sh
m88kbcs.sh
go32.sh
mkscript.c
news.sh
relax.c
@ -105,7 +106,12 @@ echo Done in `pwd`.
#
#
# $Log$
# Revision 1.32 1992/03/07 18:32:27 sac
# Revision 1.33 1992/04/05 01:46:05 sac
# New lexer.
#
# New targets for h8/300 simulator and DOS
#
# Revision 1.32 1992/03/07 18:32:27 sac
# *** empty log message ***
#
# Revision 1.31 1992/02/27 17:23:59 sac

View File

@ -1,3 +1,15 @@
Sat Apr 4 17:44:06 1992 Steve Chamberlain (sac@thepub.cygnus.com)
* ldlex.l, ldgram.y, ldlex.h: Rewrote lexer. Now it's much nicer.
* h8300*: fix bit rot and add support for h8300xray target
* go32.sh: target emulation for go32.
Mon Mar 16 14:53:29 1992 Steve Chamberlain (sac@rtl.cygnus.com)
* gld960.em, i960.sc-sh. Fix i960 bit rot
Fri Mar 13 19:47:22 1992 K. Richard Pixley (rich@cygnus.com)
* Makefile.in: install man page.

View File

@ -102,8 +102,8 @@ BFDLIB=./../bfd/libbfd.a
LIBIBERTY=./../libiberty/libiberty.a
ALL_EMULATIONS=ld__lnk960.o ld__sun3.o ld__i386aout.o \
ld__m88kbcs.o ld__a29k.o ld__news.o ld__hp300bsd.o ld__h8300hms.o ld__ebmon29k.o \
ld__sun4.o ld__gld960.o ld__vanilla.o
ld__go32.o ld__m88kbcs.o ld__a29k.o ld__news.o ld__hp300bsd.o ld__h8300hms.o ld__ebmon29k.o \
ld__sun4.o ld__gld960.o ld__vanilla.o ld__h8300xray.o
EMULATION_OFILES=${ALL_EMULATIONS}
#EMULATION_OFILES=ld__${EMUL}.o ${OTHER_EMULATIONS}
@ -119,7 +119,7 @@ HEADERS=config.h ldmain.h ldmain.h ldwarn.h ldmisc.h ldindr.h \
MANSOURCES=ld.tex
LDCSOURCES=ldlang.c lexsup.c ldctor.c ldindr.c ldmain.c ldwrite.c ldwarn.c ldlnk960.c \
ld__gld.c ld__sun3.c ld__m88k.c ld__ebmon29k.c \
ld__gld.c ld__sun3.c ld__go32.c ld__m88k.c ld__ebmon29k.c \
ldgld960.c ldemul.c ldver.c ldmisc.c ldexp.c ldsym.c ldfile.c \
relax.c lderror.c cplus-dem.c
@ -165,12 +165,9 @@ ldemul-list.h: Makefile
ldemul.o: ldemul-list.h
ldlex.c: ldlex.l
/lib/cpp -E -P $(INCLUDES) $(HDEFINES) $(TDEFINES) $(CDEFINES) $(VPATH)/ldlex.l >ldlex.p
lex -t ldlex.p >ldlex.q
sed -e "s/define input/define old_input/" \
-e "s/define unput/define old_unput/" \
-e "s/input/lex_input/" \
-e "s/unput/lex_unput/" <ldlex.q >ldlex.c
# /lib/cpp -E -P $(INCLUDES) $(HDEFINES) $(TDEFINES) $(CDEFINES) $(VPATH)/ldlex.l >ldlex.p
flex -Cem -t $(VPATH)/ldlex.l >ldlex.c
# cp ldlex.q ldlex.c
# These all start with ld__ so 'make clean' can find them.
@ -184,6 +181,9 @@ ld__sun4.c: $(srcdir)/sun4.sh \
ld__sun3.c: $(srcdir)/sun3.sh \
$(srcdir)/generic.em $(srcdir)/aout.sc-sh ${GEN_DEPENDS}
${GENSCRIPTS} sun3.sh
ld__go32.c: $(srcdir)/go32.sh \
$(srcdir)/generic.em $(srcdir)/aout.sc-sh ${GEN_DEPENDS}
${GENSCRIPTS} go32.sh
ld__news.c: $(srcdir)/news.sh \
$(srcdir)/generic.em $(srcdir)/aout.sc-sh ${GEN_DEPENDS}
${GENSCRIPTS} news.sh
@ -205,6 +205,9 @@ ld__m88kbcs.c: $(srcdir)/m88kbcs.sh \
ld__h8300hms.c: $(srcdir)/h8300hms.sh \
$(srcdir)/h8300hms.em $(srcdir)/h8300hms.sc-sh ${GEN_DEPENDS}
${GENSCRIPTS} h8300hms.sh
ld__h8300xray.c: $(srcdir)/h8300xray.sh \
$(srcdir)/h8300xray.em $(srcdir)/h8300xray.sc-sh ${GEN_DEPENDS}
${GENSCRIPTS} h8300xray.sh
ld__vanilla.c: $(srcdir)/vanilla.sh \
$(srcdir)/vanilla.em $(srcdir)/vanilla.sc-sh ${GEN_DEPENDS}
${GENSCRIPTS} vanilla.sh
@ -335,6 +338,7 @@ ldgram.o: ldgram.c
ldgram.c:ldgram.y
h8300hms.o:h8300hms.c
h8300xray.o:h8300xray.c
stage1: force
-mkdir stage1
@ -396,10 +400,13 @@ objdump:objdump.c
.PHONY: install
install: $(LD_PROG)
mv ld.new ld
-rm -f $(bindir)/$(program_prefix)ld
$(INSTALL_PROGRAM) ld.new $(bindir)/$(program_prefix)ld
$(INSTALL_PROGRAM) ld $(bindir)/$(program_prefix)ld
-rm -f $(tooldir)/ld
ln $(bindir)/$(program_prefix)ld $(tooldir)/ld
$(INSTALL_PROGRAM) ld $(tooldir)/$(program_prefix)ld
-rm -f $(man1dir)/$(program_prefix)ld.1
$(INSTALL_DATA) $(srcdir)/gld.1 $(man1dir)/$(program_prefix)ld.1
install-info: info
for i in ld.info* ; do \

1
ld/config/go32.mt Normal file
View File

@ -0,0 +1 @@
EMUL=go32

1
ld/config/ieee-h8300.mt Normal file
View File

@ -0,0 +1 @@
EMUL=h8300xray

View File

@ -56,6 +56,7 @@ i386)
case "${host_vendor}" in
*)
case "${host_os}" in
go32) my_host=go32 ;;
sysv) my_host=i386v ;;
mach) my_host=i386mach ;;
bsd) my_host=i386-aout ;;
@ -91,7 +92,7 @@ vax)
esac
# Set up to make a link between the host's include file and "sysdep.h".
files="../bfd/hosts/h-${my_host}.h"
files="../bfd/hosts/${my_host}.h"
links="sysdep.h"
if [ ! -f ${srcdir}/${files} ] ; then
@ -102,8 +103,8 @@ if [ ! -f ${srcdir}/${files} ] ; then
exit 1
fi
host_makefile_frag=
if [ -f ${srcdir}/config/mh-${my_host} ] ; then
host_makefile_frag=${srcdir}/config/mh-${my_host}
if [ -f ${srcdir}/config/${my_host}.mh ] ; then
host_makefile_frag=config/${my_host}.mh
fi
# per-target:
@ -116,19 +117,34 @@ sun)
m68k) my_target=sun3 ;;
esac
;;
wrs)
case ${target_cpu} in
i960) my_target=vxworks960 ;;
m68k) my_target=vxworks68;;
esac
;;
tandem)
my_target=sun3
;;
*)
case ${target_cpu} in
i386) my_target=go32 ;;
m88k) my_target=m88k-bcs ;;
a29k) case ${target_os} in
ebmon) my_target=ebmon29k ;;
*) my_target=coff-a29k ;;
esac
;;
h8300) my_target=coff-h8300 ;;
h8300) case ${target_os} in
hms) my_target=coff-h8300 ;;
xray) my_target=ieee-h8300 ;;
esac
;;
m68k)
case ${target_vendor} in
sony) my_target=news ;;
hp) my_target=hp300bsd ;;
wrs) my_target=sun3 ;;
*)
echo "Unknown m68k target vendor:" ${target_vendor}
@ -140,4 +156,4 @@ sun)
;;
esac
target_makefile_frag=${srcdir}/config/mt-${my_target}
target_makefile_frag=config/${my_target}.mt

9
ld/go32.sh Executable file
View File

@ -0,0 +1,9 @@
EMULATION_NAME=go32
SCRIPT_NAME=aout
OUTPUT_FORMAT="a.out-i386"
TEXT_START_ADDR=0x1020
PAGE_SIZE=0x1000
SEGMENT_SIZE=0x400000
NONPAGED_TEXT_START_ADDR=0x0
ARCH=i386

View File

@ -6,8 +6,8 @@ MEMORY {
rom : o = 0x0000, l = 0x7fe0
duart : o = 0x7fe0, l = 16
ram : o = 0x8000, l = 28k
topram: o = 0x8000+28k, l = 1k
hmsram: o = 0xfb80, l = 512
topram : o = 0x8000+28k, l = 1k
hmsram : o = 0xfb80, l = 512
}
SECTIONS
@ -32,6 +32,7 @@ SECTIONS
} ${RELOCATING+ >ram}
.stack :
{
_stack = .;
*(.stack)
} ${RELOCATING+ > topram}
}

88
ld/h8300xray.em Normal file
View File

@ -0,0 +1,88 @@
cat >ld__${EMULATION_NAME}.c <<EOF
/* 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. */
/*
Written by Steve Chamberlain steve@cygnus.com
The controller which tells the gnu linker how to behave like one for
the Hitach H8/300 with IEEE records.
*/
#include "bfd.h"
#include "sysdep.h"
#include "ld.h"
#include "config.h"
#include "ldemul.h"
#include "ldfile.h"
#include "ldmisc.h"
extern boolean lang_float_flag;
extern enum bfd_architecture ldfile_output_architecture;
extern unsigned long ldfile_output_machine;
extern char *ldfile_output_machine_name;
extern bfd *output_bfd;
static void h8300xray_before_parse()
{
ldfile_output_architecture = bfd_arch_h8300;
}
static char *h8300xray_script =
#include "h8300xray.x"
;
static char *h8300xray_script_option_Ur =
#include "h8300xray.x"
;
static char *h8300xray_script_option_r =
#include "h8300xray.x"
;
static char *h8300xray_get_script()
{
extern ld_config_type config;
if (config.relocateable_output == true &&
config.build_constructors == true) {
return h8300xray_script_option_Ur;
}
if (config.relocateable_output) {
return h8300xray_script_option_r;
}
return h8300xray_script;
}
struct ld_emulation_xfer_struct ld_h8300xray_emulation =
{
h8300xray_before_parse,
syslib_default,
hll_default,
after_parse_default,
after_allocation_default,
set_output_arch_default,
ldemul_default_target,
before_allocation_default,
h8300xray_get_script,
"h8300xray"
};
EOF

26
ld/h8300xray.sc-sh Executable file
View File

@ -0,0 +1,26 @@
cat <<EOF
OUTPUT_FORMAT("${OUTPUT_FORMAT}")
OUTPUT_ARCH(${ARCH})
SECTIONS
{
.text :
{
*(.text)
*(.strings)
_etext = .;
*(.data)
_edata = .;
*(.bss)
*(COMMON)
_end = .;
_stack = 0xe000;
}
}
EOF

8
ld/h8300xray.sh Executable file
View File

@ -0,0 +1,8 @@
EMULATION_NAME=h8300xray
SCRIPT_NAME=h8300xray
OUTPUT_FORMAT="ieee"
TEXT_START_ADDR=0x0
PAGE_SIZE=128
ARCH=h8300
TEMPLATE_NAME=h8300xray

View File

@ -100,7 +100,7 @@ struct sec *section;
}
%type <etree> exp opt_exp
%type <etree> exp opt_exp mustbe_exp
%type <integer> fill_opt opt_block opt_type
%type <name> memspec_opt
%token <integer> INT
@ -123,6 +123,7 @@ struct sec *section;
/*%token <token> '+' '-' '*' '/' '%'*/
%right UNARY
%token END
%left <token> '('
%token <token> ALIGN_K BLOCK LONG SHORT BYTE
%token SECTIONS
@ -155,8 +156,8 @@ ld_config_type config;
file: command_line { lang_final(); };
filename:
NAME;
filename: NAME;
command_line:
@ -165,12 +166,7 @@ command_line:
;
command_line_option:
'{'
{ ldgram_in_script = true; }
ifile_list
{ ldgram_in_script = false; }
'}'
| OPTION_Bstatic { }
OPTION_Bstatic { }
| OPTION_v
{
ldversion(0);
@ -189,7 +185,6 @@ command_line_option:
write_map = true;
config.map_filename = $2;
}
| OPTION_M {
config.map_filename = "-";
@ -269,12 +264,12 @@ command_line_option:
}
| OPTION_Texp
{
hex_mode =true;
hex_mode = 16;
}
INT
{
lang_section_start($1,exp_intop($3));
hex_mode = false;
hex_mode = 0;
}
| OPTION_Aarch
@ -297,12 +292,15 @@ command_line_option:
{ lang_add_input_file($1,lang_input_file_is_file_enum,
(char *)NULL); }
| OPTION_c filename
{ ldfile_open_command_file($2); } script_file
{ ldfile_open_command_file($2); } script_file END { ldlex_command()};
| OPTION_Tfile
{ ldfile_open_command_file($1); } script_file
END { ldlex_command();}
| OPTION_T filename
{ ldfile_open_command_file($2); } script_file
END { ldlex_command();}
| OPTION_l
{
@ -316,17 +314,16 @@ command_line_option:
lang_input_file_is_symbols_only_enum,
(char *)NULL);
}
| OPTION_defsym
{
| OPTION_defsym { ldlex_expression();
}
NAME '='
exp
{
NAME '=' mustbe_exp { ldlex_popstate();
lang_add_assignment(exp_assop($4,$3,$5));
}
| '-' NAME
{ info("%P%F Unrecognised option -%s\n", $2); }
| '{' script_file '}'
;
@ -336,11 +333,14 @@ command_line_option:
script_file:
{ ldgram_in_script = true; }
ifile_list '}'
{ ldgram_in_script = false; }
script_file:
{
ldlex_both();
}
ifile_list
{
ldlex_popstate();
}
;
@ -359,7 +359,7 @@ ifile_p1:
| low_level_library
| floating_point_support
| statement_anywhere
| ';'
| ';'
| TARGET_K '(' NAME ')'
{ lang_add_target($3); }
| SEARCH_DIR '(' filename ')'
@ -390,13 +390,12 @@ input_list:
;
sections:
SECTIONS '{'sec_or_group_p1 '}'
SECTIONS '{' sec_or_group_p1 '}'
;
sec_or_group_p1:
sec_or_group_p1 section
| sec_or_group_p1 statement_anywhere
| sec_or_group_p1
|
;
@ -438,11 +437,10 @@ input_section_spec:
statement:
statement assignment end
| statement ';'
| statement
| statement CREATE_OBJECT_SYMBOLS
{
lang_add_attribute(lang_object_symbols_statement_enum); }
| statement ';'
| statement CONSTRUCTORS
{
lang_add_attribute(lang_constructors_statement_enum); }
@ -474,7 +472,7 @@ length:
;
fill_opt:
'=' exp
'=' mustbe_exp
{
$$ = exp_get_value_int($2,
0,
@ -506,16 +504,16 @@ assign_op:
;
end: ';' | ','
end: ';' | ','
;
assignment:
NAME '=' exp
NAME '=' mustbe_exp
{
lang_add_assignment(exp_assop($2,$1,$3));
}
| NAME assign_op exp
| NAME assign_op mustbe_exp
{
lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3)));
}
@ -528,7 +526,7 @@ opt_comma:
memory:
MEMORY '{' memory_spec memory_spec_list '}'
MEMORY '{' memory_spec memory_spec_list '}'
;
memory_spec_list:
@ -541,21 +539,18 @@ memory_spec_list:
memory_spec:
NAME
{ region = lang_memory_region_lookup($1); }
attributes_opt ':' origin_spec opt_comma length_spec
attributes_opt ':'
origin_spec opt_comma length_spec
{
}
;
origin_spec:
ORIGIN '=' exp
ORIGIN '=' mustbe_exp
{ region->current =
region->origin =
exp_get_vma($3, 0L,"origin", lang_first_phase_enum); }
;
length_spec:
LENGTH '=' exp
LENGTH '=' mustbe_exp
{ region->length = exp_get_vma($3,
~((bfd_vma)0),
"length",
@ -608,12 +603,15 @@ floating_point_support:
;
mustbe_exp: { ldlex_expression(); }
exp
{ ldlex_popstate(); $$=$2;}
;
exp :
'-' exp %prec UNARY
{ $$ = exp_unop('-', $2); }
| '(' exp ')'
| '(' exp ')'
{ $$ = $2; }
| NEXT '(' exp ')' %prec UNARY
{ $$ = exp_unop($1,$3); }
@ -682,13 +680,15 @@ exp :
section: NAME opt_exp opt_type opt_block ':' opt_things'{'
section: NAME { ldlex_expression(); }
opt_exp { ldlex_popstate(); }
opt_type opt_block ':' opt_things'{'
{
lang_enter_output_section_statement($1,$2,$3,$4);
lang_enter_output_section_statement($1,$3,$5,$6);
}
statement '}' fill_opt memspec_opt
{
lang_leave_output_section_statement($11, $12);
lang_leave_output_section_statement($13, $14);
}
;
@ -702,7 +702,9 @@ opt_type:
| { $$ = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; }
;
opt_things: ;
opt_things:
{
};
opt_exp:
@ -712,7 +714,7 @@ opt_exp:
;
opt_block:
BLOCK '(' exp ')'
BLOCK '(' exp ')'
{ $$ = exp_get_value_int($3,
1L,
"block",
@ -722,7 +724,7 @@ opt_block:
;
memspec_opt:
'>' NAME
'>' NAME
{ $$ = $2; }
| { $$ = "*default*"; }
;

View File

@ -340,6 +340,10 @@ DEFUN_VOID(lang_init)
first_file = lang_add_input_file((char *)NULL,
lang_input_file_is_marker_enum,
(char *)NULL);
abs_output_section = lang_output_section_statement_lookup(BFD_ABS_SECTION_NAME);
abs_output_section->bfd_section = &bfd_abs_section;
}
@ -387,6 +391,8 @@ DEFUN(lang_memory_region_lookup,(name),
new->origin = 0;
new->length = ~0;
new->current = 0;
new->had_full_message = false;
return new;
}
}
@ -442,7 +448,7 @@ DEFUN(lang_output_section_statement_lookup,(name),
/*ARGSUSED*/
static void
DEFUN(print_flags, ( ignore_flags),
int *ignore_flags)
@ -494,20 +500,20 @@ static void
DEFUN(init_os,(s),
lang_output_section_statement_type *s)
{
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)));
/* 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);
s->bfd_section = bfd_make_section(output_bfd, s->name);
if (s->bfd_section == (asection *)NULL) {
einfo("%P%F output format %s cannot represent section called %s\n",
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;*/
/* s->bfd_section->flags = s->flags;*/
/* We initialize an output sections output offset to minus its own */
/* vma to allow us to output a section through itself */
@ -754,9 +760,6 @@ static void
lang_reasonable_defaults()
{
abs_output_section = lang_output_section_statement_lookup(BFD_ABS_SECTION_NAME);
abs_output_section->bfd_section = &bfd_abs_section;
#if 0
@ -853,6 +856,10 @@ DEFUN_VOID(lang_init_script_file)
script_file->the_bfd = bfd_create("script file", output_bfd);
script_file->symbol_count = 0;
script_file->the_bfd->sections = output_bfd->sections;
abs_output_section = lang_output_section_statement_lookup(BFD_ABS_SECTION_NAME);
abs_output_section->bfd_section = &bfd_abs_section;
}
@ -1330,187 +1337,7 @@ output_section_statement->bfd_section->_raw_size =
return dot ;
}
#if 0
/* Work out the size of the output sections
from the sizes of the input sections */
static bfd_vma
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)
{
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);
/* Ignore the size of the input sections, use the vma and size to */
/* align against */
after = ALIGN(os->bfd_section->vma +
os->bfd_section->size,
os->block_value) ;
os->bfd_section->size = after - os->bfd_section->vma;
dot = os->bfd_section->vma + os->bfd_section->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);
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->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);
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:
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->size +=
new->padding_statement.size;
dot = newdot;
}
}
break;
case lang_padding_statement_enum:
FAIL();
break;
default:
FAIL();
break;
case lang_address_statement_enum:
break;
}
prev = &s->header.next;
}
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
@ -1529,194 +1356,207 @@ DEFUN(lang_size_sections,(s, output_section_statement, prev, fill,
{
/* 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:
{
switch (s->header.type) {
case lang_output_section_statement_enum:
bfd_vma after;
lang_output_section_statement_type *os =&(s->output_section_statement);
if (os->bfd_section == &bfd_abs_section)
{
/* No matter what happens, an abs section starts at zero */
os->bfd_section->vma = 0;
}
else
{
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,
abs_output_section,
lang_allocating_phase_enum,
dot, &dot);
if (r.valid == false)
{
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,
abs_output_section,
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 */
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 */
after = ALIGN(os->bfd_section->vma +
os->bfd_section->_raw_size,
os->block_value) ;
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 */
os->bfd_section->_raw_size = after - os->bfd_section->vma;
dot = os->bfd_section->vma + os->bfd_section->_raw_size;
os->processed = true;
after = ALIGN(os->bfd_section->vma +
os->bfd_section->_raw_size,
os->block_value) ;
/* Replace into region ? */
if (os->addr_tree == (etree_type *)NULL
&& os->region !=(lang_memory_region_type*)NULL ) {
os->region->current = dot;
/* Make sure this isn't silly */
if (os->region->current >
os->region->origin +
os->region->length)
{
einfo("%X%P: Region %s is full (%B section %s)\n",
os->region->name,
os->bfd_section->owner,
os->bfd_section->name);
/* Reset the region pointer */
os->region->current = 0;
}
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;
/* Make sure this isn't silly */
if (os->region->current >
os->region->origin +
os->region->length)
{
einfo("%X%P: Region %s is full (%B section %s)\n",
os->region->name,
os->bfd_section->owner,
os->bfd_section->name);
/* Reset the region pointer */
os->region->current = 0;
}
}
}
}
}
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;
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;
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;
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;
}
dot += size;
output_section_statement->bfd_section->_raw_size += size;
}
break;
case lang_wild_statement_enum:
case lang_wild_statement_enum:
dot = lang_size_sections(s->wild_statement.children.head,
dot = lang_size_sections(s->wild_statement.children.head,
output_section_statement,
&s->wild_statement.children.head,
fill, dot, relax);
break;
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;
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;
had_relax |= relax_section(prev);
relaxing = false;
}
}
dot = size_input_section(prev,
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);
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 && !relax)
/* 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;
if (newdot != dot && !relax)
/* 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;
}
prev = &s->header.next;
}
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),
@ -1764,7 +1604,8 @@ DEFUN(lang_do_assignments,(s, output_section_statement, fill, dot),
{
etree_value_type value ;
value = exp_fold_tree(s->data_statement.exp,
0, lang_final_phase_enum, dot, &dot);
abs_output_section,
lang_final_phase_enum, dot, &dot);
s->data_statement.value = value.value;
if (value.valid == false) einfo("%F%P: Invalid data statement\n");
}
@ -2281,8 +2122,9 @@ DEFUN(create_symbol,(name, flags, section),
void
DEFUN_VOID(lang_process)
{
if (had_script == false) {
parse_line(ldemul_get_script());
parse_line(ldemul_get_script(),1);
}
lang_reasonable_defaults();
current_target = default_target;

View File

@ -18,521 +18,414 @@ along with GLD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* $Id$
*
This was written by steve chamberlain
sac@cygnus.com
*/
/*SUPPRESS 529*/
/*SUPPRESS 26*/
/*SUPPRESS 29*/
/*#define LEXDEBUG 0*/
#include "bfd.h"
#include "sysdep.h"
#include <ctype.h>
#include "ldlex.h"
#include "ld.h"
#include "ldexp.h"
typedef int bfd_vma;
#include <ansidecl.h>
#include "ldgram.h"
#include "ldmisc.h"
#undef input
#undef unput
#define input lex_input
#define unput lex_unput
int debug;
static boolean ldgram_in_defsym;
static boolean ldgram_had_equals;
extern boolean ldgram_in_script;
static char *command_line;
int ldgram_in_defsym;
int ldgram_had_equals;
int ldgram_in_script;
int hex_mode;
extern int fgetc();
extern int yyparse();
typedef struct {
char *name;
int value;
} keyword_type;
char *buystring();
int lineno = 1;
int old;
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) yy_input(buf, &result, max_size)
#undef YY_FATAL_ERROR
#define YY_FATAL_ERROR ;
#define MAX_INCLUDE_DEPTH 10
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
unsigned int include_stack_ptr = 0;
/* FOUR STATES
COMMAND on command line
COMMENT in a C comment
EXPRESSION definiatelyt in an expression
SCRIPT definately in a script
SOMEWHERE either EXPRESSION or SCRIPT
*/
#define RTOKEN(x) { yylval.token = x; return x; }
keyword_type keywords[] =
{
"/", '/',
"MEMORY",MEMORY,
"ORIGIN",ORIGIN,
"BLOCK",BLOCK,
"LENGTH",LENGTH,
"ALIGN",ALIGN_K,
"ADDR",ADDR,
"ENTRY",ENTRY,
"NEXT",NEXT,
"sizeof_headers",SIZEOF_HEADERS,
"SIZEOF_HEADERS",SIZEOF_HEADERS,
"MAP",MAP,
"SIZEOF",SIZEOF,
"TARGET",TARGET_K,
"SEARCH_DIR",SEARCH_DIR,
"OUTPUT",OUTPUT,
"INPUT",INPUT,
"DEFINED",DEFINED,
"CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
"CONSTRUCTORS", CONSTRUCTORS,
"FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
"SECTIONS",SECTIONS,
"FILL",FILL,
"STARTUP",STARTUP,
"OUTPUT_FORMAT",OUTPUT_FORMAT,
"OUTPUT_ARCH", OUTPUT_ARCH,
"HLL",HLL,
"SYSLIB",SYSLIB,
"FLOAT",FLOAT,
"LONG", LONG,
"SHORT", SHORT,
"BYTE", BYTE,
"NOFLOAT",NOFLOAT,
"NOLOAD",NOLOAD,
"DSECT",DSECT,
"COPY",COPY,
"INFO",INFO,
"OVERLAY",OVERLAY,
"o",ORIGIN,
"org",ORIGIN,
"l", LENGTH,
"len", LENGTH,
0,0};
unsigned int lineno;
extern boolean hex_mode;
FILE *ldlex_input_stack;
static unsigned int have_pushback;
#define NPUSHBACK 10
int pushback[NPUSHBACK];
int thischar;
extern char *ldfile_input_filename;
int donehash = 0;
int
lex_input()
{
if (have_pushback > 0)
{
have_pushback --;
return thischar = pushback[have_pushback];
}
if (ldlex_input_stack) {
thischar = fgetc(ldlex_input_stack);
if (thischar == EOF) {
fclose(ldlex_input_stack);
ldlex_input_stack = (FILE *)NULL;
ldfile_input_filename = (char *)NULL;
/* First char after script eof is a @ so that we can tell the grammer
that we've left */
thischar = '@';
}
}
else if (command_line && *command_line) {
thischar = *(command_line++);
}
else {
thischar = 0;
}
if(thischar == '\t') thischar = ' ';
if (thischar == '\n') { thischar = ' '; lineno++; }
return thischar ;
}
void
lex_unput(c)
int c;
{
if (have_pushback > NPUSHBACK) {
info("%F%P Too many pushbacks\n");
}
pushback[have_pushback] = c;
have_pushback ++;
}
int
yywrap()
{ return 1; }
/*VARARGS*/
void
allprint(x)
int x;
{
fprintf(yyout,"%d",x);
}
void
sprint(x)
char *x;
{
fprintf(yyout,"%s",x);
}
int thischar;
void parse_line(arg)
char *arg;
{
command_line = arg;
have_pushback = 0;
yyparse();
}
void
parse_args(ac, av)
int ac;
char **av;
{
char *p;
int i;
size_t size = 0;
char *dst;
debug = 1;
for (i= 1; i < ac; i++) {
size += strlen(av[i]) + 2;
}
dst = p = (char *)ldmalloc(size + 2);
/* Put a space arount each option */
for (i =1; i < ac; i++) {
unsigned int s = strlen(av[i]);
*dst++ = ' ';
memcpy(dst, av[i], s);
dst[s] = ' ';
dst += s + 1;
}
*dst = 0;
parse_line(p);
free(p);
}
static long
DEFUN(number,(default_if_zero,base),
int default_if_zero AND
int base)
{
unsigned long l = 0;
int ch = yytext[0];
if (ch == 0) {
base = default_if_zero;
}
while (1) {
switch (ch) {
case 'x':
base = 16;
break;
case 'k':
case 'K':
l =l * 1024;
break;
case 'm':
case 'M':
l =l * 1024 * 1024;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
l = l * base + ch - '0';
break;
case 'a': case 'b': case 'c' : case 'd' : case 'e': case 'f':
l =l *base + ch - 'a' + 10;
break;
case 'A': case 'B': case 'C' : case 'D' : case 'E': case 'F':
l =l *base + ch - 'A' + 10;
break;
default:
unput(ch);
yylval.integer = l;
return INT;
}
ch = input();
}
}
%}
%a 4000
%o 5000
FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=]
FILENAMECHAR1 [_a-zA-Z\/\.\\]
FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\]
FILENAME {FILENAMECHAR}+
WHITE [ \t]+
WHITE [ \t\n]+
%x COMMAND
%x SCRIPT
%x EXPRESSION
%x COMMENT
%x BOTH
%%
<COMMAND>"-defsym" { return OPTION_defsym; }
<COMMAND>"-noinhibit_exec" { return OPTION_noinhibit_exec; }
<COMMAND>"-noinhibit-exec" { return OPTION_noinhibit_exec; }
<COMMAND>"-sort_common" { return OPTION_sort_common;}
<COMMAND>"-sort-common" { return OPTION_sort_common;}
<COMMAND>"-format" { return OPTION_format; }
<COMMAND>"-n" { return OPTION_n; }
<COMMAND>"-N" { return OPTION_N; }
<COMMAND>"-r" { return OPTION_r; }
<COMMAND>"-relax" { return OPTION_relax; }
<COMMAND>"-i" { return OPTION_r; }
<COMMAND>"-Ur" { return OPTION_Ur; }
<COMMAND>"-o" { return OPTION_o; }
<COMMAND>"-g" { return OPTION_g; }
<COMMAND>"-e" { return OPTION_e; }
<COMMAND>"-b" { return OPTION_b; }
<COMMAND>"-dc" { return OPTION_dc; }
<COMMAND>"-dp" { return OPTION_dp; }
<COMMAND>"-d" { return OPTION_d; }
<COMMAND>"-v" { return OPTION_v; }
<COMMAND>"-V" { return OPTION_V; }
<COMMAND>"-M" { return OPTION_M; }
<COMMAND>"-Map" { return OPTION_Map;}
<COMMAND>"-t" { return OPTION_t; }
<COMMAND>"-X" { return OPTION_X; }
<COMMAND>"-x" { return OPTION_x; }
<COMMAND>"-c" { return OPTION_c; }
<COMMAND>"-R" { return OPTION_R; }
<COMMAND>"-u" { return OPTION_u; }
<COMMAND>"-s" { return OPTION_s; }
<COMMAND>"-S" { return OPTION_S; }
<COMMAND>"-Bstat" { return OPTION_Bstatic; }
<COMMAND>"-B"{FILENAME} { /* Ignored */ }
<COMMAND>"-l"{FILENAME} {
yylval.name = buystring(yytext+2);
return OPTION_l;
}
"@" { return '}'; }
"\ -defsym\ " { ldgram_in_defsym = true; return OPTION_defsym; }
"\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
"\ -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; }
"\ -g\ " { return OPTION_g; }
"\ -e\ " { return OPTION_e; }
"\ -b\ " { return OPTION_b; }
"\ -dc\ " { return OPTION_dc; }
"\ -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; }
"\ -c\ " { return OPTION_c; }
"\ -R\ " { return OPTION_R; }
"\ -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);
return OPTION_l;
}
<COMMAND>"-L"{FILENAME} {
yylval.name = buystring(yytext+2);
return OPTION_L;
}
<COMMAND>"-Ttext" {
yylval.name = ".text";
return OPTION_Texp;
}
<COMMAND>"-Tdata" {
yylval.name = ".data";
return OPTION_Texp;
}
<COMMAND>"-Tbss" {
yylval.name = ".bss";
return OPTION_Texp;
}
<COMMAND>"-O"{FILENAME} {
yylval.name = buystring(yytext+2);
return OPTION_Texp;
}
"\ -L"{FILENAME} {
yylval.name = buystring(yytext+3);
return OPTION_L;
}
"\ -Ttext\ " {
yylval.name = ".text";
return OPTION_Texp;
}
"\ -Tdata\ " {
yylval.name = ".data";
return OPTION_Texp;
}
"\ -Tbss\ " {
yylval.name = ".bss";
return OPTION_Texp;
}
"\ -O"{FILENAME} {
yylval.name = buystring(yytext+3);
return OPTION_Texp;
}
<COMMAND>"-T"{FILENAME} {
yylval.name = buystring(yytext+2);
return OPTION_Tfile;
}
<COMMAND>"-T" {
return OPTION_T;
}
"\ -T"{FILENAME} {
yylval.name = buystring(yytext+3);
return OPTION_Tfile;
}
"\ -T\ " {
return OPTION_T;
}
<COMMAND>"-F"{FILENAME} {
return OPTION_F;
}
<COMMAND>"-F" {
return OPTION_F;
}
"\ -F"{FILENAME} {
return OPTION_F;
}
"\ -F\ " {
return OPTION_F;
}
<COMMAND>"-A"{FILENAME} {
yylval.name = buystring(yytext+2);
return OPTION_Aarch;
}
<BOTH,EXPRESSION>"0x"?([0-9A-Fa-f])+(M|K|m|k)? {
yylval.integer = strtol(yytext,0,hex_mode);
if (yytext[yyleng-1]=='M'
|| yytext[yyleng-1] == 'm') {
yylval.integer *= 1024*1024;
}
if (yytext[yyleng-1]=='K'
|| yytext[yyleng-1]=='k') {
yylval.integer *= 1024;
}
return INT;
}
<BOTH,SCRIPT,EXPRESSION>"]" { RTOKEN(']');}
<BOTH,SCRIPT,EXPRESSION>"[" { RTOKEN('[');}
<BOTH,SCRIPT,EXPRESSION>"<<=" { RTOKEN(LSHIFTEQ);}
<BOTH,SCRIPT,EXPRESSION>">>=" { RTOKEN(RSHIFTEQ);}
<BOTH,SCRIPT,EXPRESSION>"||" { RTOKEN(OROR);}
<BOTH,SCRIPT,EXPRESSION>"==" { RTOKEN(EQ);}
<BOTH,SCRIPT,EXPRESSION>"!=" { RTOKEN(NE);}
<BOTH,SCRIPT,EXPRESSION>">=" { RTOKEN(GE);}
<BOTH,SCRIPT,EXPRESSION>"<=" { RTOKEN(LE);}
<BOTH,SCRIPT,EXPRESSION>"<<" { RTOKEN(LSHIFT);}
<BOTH,SCRIPT,EXPRESSION>">>" { RTOKEN(RSHIFT);}
<BOTH,SCRIPT,EXPRESSION>"+=" { RTOKEN(PLUSEQ);}
<BOTH,SCRIPT,EXPRESSION>"-=" { RTOKEN(MINUSEQ);}
<BOTH,SCRIPT,EXPRESSION>"*=" { RTOKEN(MULTEQ);}
<BOTH,SCRIPT,EXPRESSION>"/=" { RTOKEN(DIVEQ);}
<BOTH,SCRIPT,EXPRESSION>"&=" { RTOKEN(ANDEQ);}
<BOTH,SCRIPT,EXPRESSION>"|=" { RTOKEN(OREQ);}
<BOTH,SCRIPT,EXPRESSION>"&&" { RTOKEN(ANDAND);}
<BOTH,SCRIPT,EXPRESSION>">" { RTOKEN('>');}
<BOTH,SCRIPT,EXPRESSION>"," { RTOKEN(',');}
<BOTH,SCRIPT,EXPRESSION>"&" { RTOKEN('&');}
<BOTH,SCRIPT,EXPRESSION>"|" { RTOKEN('|');}
<BOTH,SCRIPT,EXPRESSION>"~" { RTOKEN('~');}
<BOTH,SCRIPT,EXPRESSION>"!" { RTOKEN('!');}
<BOTH,SCRIPT,EXPRESSION>"?" { RTOKEN('?');}
<BOTH,SCRIPT,EXPRESSION>"*" { RTOKEN('*');}
<BOTH,SCRIPT,EXPRESSION>"+" { RTOKEN('+');}
<BOTH,SCRIPT,EXPRESSION>"-" { RTOKEN('-');}
<BOTH,SCRIPT,EXPRESSION>"/" { RTOKEN('/');}
<BOTH,SCRIPT,EXPRESSION>"%" { RTOKEN('%');}
<BOTH,SCRIPT,EXPRESSION>"<" { RTOKEN('<');}
<BOTH,SCRIPT,EXPRESSION>">" { RTOKEN('>');}
<BOTH,SCRIPT,EXPRESSION>"=" { RTOKEN('=');}
<BOTH,SCRIPT,EXPRESSION>"}" { RTOKEN('}') ; }
<BOTH,SCRIPT,EXPRESSION>"{" { RTOKEN('{'); }
<BOTH,SCRIPT,EXPRESSION>")" { RTOKEN(')');}
<BOTH,SCRIPT,EXPRESSION>"(" { RTOKEN('(');}
<BOTH,SCRIPT,EXPRESSION>"]" { RTOKEN(']');}
<BOTH,SCRIPT,EXPRESSION>"[" { RTOKEN('[');}
<BOTH,SCRIPT,EXPRESSION>":" { RTOKEN(':'); }
<BOTH,SCRIPT,EXPRESSION>";" { RTOKEN(';');}
<BOTH,SCRIPT,EXPRESSION>"-" { RTOKEN('-');}
<BOTH,SCRIPT,EXPRESSION>"/" { RTOKEN('/');}
<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
<BOTH,SCRIPT>"ORIGIN" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);}
<BOTH,SCRIPT>"LENGTH" { RTOKEN(LENGTH);}
<EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);}
<EXPRESSION,BOTH,SCRIPT>"ADDR" { RTOKEN(ADDR);}
<BOTH,SCRIPT>"ENTRY" { RTOKEN(ENTRY);}
<EXPRESSION,BOTH,SCRIPT>"NEXT" { RTOKEN(NEXT);}
<EXPRESSION,BOTH,SCRIPT>"sizeof_headers" { RTOKEN(SIZEOF_HEADERS);}
<EXPRESSION,BOTH,SCRIPT>"SIZEOF_HEADERS" { RTOKEN(SIZEOF_HEADERS);}
<BOTH,SCRIPT>"MAP" { RTOKEN(MAP);}
<EXPRESSION,BOTH,SCRIPT>"SIZEOF" { RTOKEN(SIZEOF);}
<BOTH,SCRIPT>"TARGET" { RTOKEN(TARGET_K);}
<BOTH,SCRIPT>"SEARCH_DIR" { RTOKEN(SEARCH_DIR);}
<BOTH,SCRIPT>"OUTPUT" { RTOKEN(OUTPUT);}
<BOTH,SCRIPT>"INPUT" { RTOKEN(INPUT);}
<BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);}
<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);}
<BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);}
<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);}
<BOTH,SCRIPT>"SECTIONS" { RTOKEN(SECTIONS);}
<BOTH,SCRIPT>"FILL" { RTOKEN(FILL);}
<BOTH,SCRIPT>"STARTUP" { RTOKEN(STARTUP);}
<BOTH,SCRIPT>"OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT);}
<BOTH,SCRIPT>"OUTPUT_ARCH" { RTOKEN( OUTPUT_ARCH);}
<BOTH,SCRIPT>"HLL" { RTOKEN(HLL);}
<BOTH,SCRIPT>"SYSLIB" { RTOKEN(SYSLIB);}
<BOTH,SCRIPT>"FLOAT" { RTOKEN(FLOAT);}
<BOTH,SCRIPT>"LONG" { RTOKEN( LONG);}
<BOTH,SCRIPT>"SHORT" { RTOKEN( SHORT);}
<BOTH,SCRIPT>"BYTE" { RTOKEN( BYTE);}
<BOTH,SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT);}
<BOTH,SCRIPT>"NOLOAD" { RTOKEN(NOLOAD);}
<BOTH,SCRIPT>"DSECT" { RTOKEN(DSECT);}
<BOTH,SCRIPT>"COPY" { RTOKEN(COPY);}
<BOTH,SCRIPT>"INFO" { RTOKEN(INFO);}
<BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY);}
<BOTH,SCRIPT>"o" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"org" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"l" { RTOKEN( LENGTH);}
<BOTH,SCRIPT>"len" { RTOKEN( LENGTH);}
"\ -A"{FILENAME} {
yylval.name = buystring(yytext+3);
return OPTION_Aarch;
}
<BOTH,EXPRESSION>{FILENAMECHAR1}{FILENAMECHAR}* {
yylval.name = buystring(yytext);
return NAME;
}
<SCRIPT,COMMAND>{FILENAMECHAR}* { yylval.name = buystring(yytext);
return NAME;
}
" " {
if (ldgram_had_equals == true) {
ldgram_in_defsym = false;
ldgram_had_equals = false;
}
}
"<<=" { RTOKEN(LSHIFTEQ);}
">>=" { RTOKEN(RSHIFTEQ);}
"||" { RTOKEN(OROR);}
"==" { RTOKEN(EQ);}
"!=" { RTOKEN(NE);}
">=" { RTOKEN(GE);}
"<=" { RTOKEN(LE);}
"<<" { RTOKEN(LSHIFT);}
">>" { RTOKEN(RSHIFT);}
"+=" { RTOKEN(PLUSEQ);}
"-=" { RTOKEN(MINUSEQ);}
"*=" { RTOKEN(MULTEQ);}
"/=" { RTOKEN(DIVEQ);}
"&=" { RTOKEN(ANDEQ);}
"|=" { RTOKEN(OREQ);}
"&&" { RTOKEN(ANDAND);}
">" { RTOKEN('>');}
"," { RTOKEN(',');}
"&" { RTOKEN('&');}
"|" { RTOKEN('|');}
"~" { RTOKEN('~');}
"!" { RTOKEN('!');}
"?" { RTOKEN('?');}
"*" { RTOKEN('*');}
"%" { RTOKEN('%');}
"<" { RTOKEN('<');}
">" { RTOKEN('>');}
"}" { RTOKEN('}') ; }
"{" { RTOKEN('{'); }
")" { RTOKEN(')');}
"(" { RTOKEN('(');}
"]" { RTOKEN(']');}
"[" { RTOKEN('[');}
":" { RTOKEN(':'); }
";" { RTOKEN(';');}
"-" { RTOKEN('-');}
<EXPRESSION,BOTH,COMMAND,SCRIPT>"\""[^\"]*"\"" {
/* No matter the state, quotes
give what's inside */
yylval.name = buystring(yytext+1);
yylval.name[yyleng-2] = 0;
return NAME;
}
<BOTH,SCRIPT,EXPRESSION>"\n" { lineno++;}
<COMMAND,BOTH,SCRIPT,EXPRESSION>[ \t]
"/*" { old = INITIAL; BEGIN(COMMENT); }
<COMMAND>"/*" { old = COMMAND; BEGIN(COMMENT); }
<BOTH>"/*" { old =BOTH; BEGIN(COMMENT); }
<SCRIPT>"/*" { old = EXPRESSION; BEGIN(COMMENT); }
<EXPRESSION>"/*" { old = SCRIPT; BEGIN(COMMENT); }
"/*" { old = INITIAL; BEGIN(COMMENT); }
<COMMENT>[^*\\n]*
<COMMENT>"*"+[^*/\\n]*
<COMMENT>\\n { ++lineno;}
<COMMENT>"*"+"/" { BEGIN(old); }
"/*" {
while (1) {
int ch;
ch = input();
while (ch != '*') {
ch = input();
<<EOF>> {
include_stack_ptr--;
if (include_stack_ptr == 0)
{
yyterminate();
}
if (input() == '/') {
break;
else
{
yy_switch_to_buffer(include_stack[include_stack_ptr]);
}
unput(yytext[yyleng-1]);
}
}
"\""[^\"]*"\"" {
yylval.name = buystring(yytext+1);
yylval.name[yyleng-2] = 0; /* Fry final quote */
return NAME;
}
{FILENAMECHAR} {
boolean loop = false;
int ch;
keyword_type *k;
/* If we're in hex mode (only after a -T) then all we can see are numbers
hex digit we see will be a number. */
if (hex_mode) {
return number(16, 16);
}
/* If we're in a defsym then all things starting with a digit are in
hex */
if (isdigit(yytext[0]) && ldgram_in_defsym) {
return number(16,16);
BEGIN(COMMAND);
return END;
}
/* Otherwise if we're in a script we will parse the numbers
normally */
if (ldgram_in_script == true && isdigit(yytext[0])) {
return number(8,10);
}
/* Anywhere not in a script or defsym, an opertor is part of a
filename, except / and, which is an operator when on its own */
if (ldgram_in_script == true|| ldgram_in_defsym == true) {
switch (yytext[0]) {
case '*': RTOKEN('*');
case '=': {
ldgram_had_equals = true;
RTOKEN('=');
}
break;
case '/': {
if (ldgram_in_defsym) RTOKEN('/');
}
break;
case '+': RTOKEN('+');
case '-': RTOKEN('-');
case '!': RTOKEN('!');
case '~': RTOKEN('~');
}
}
/* Otherwise this must be a file or a symbol name, and it will continue to be a
filename until we get to something strange. In scripts operator looking
things are taken to be operators, except /, which will be left
*/
ch = input();
while (true)
{
if (ldgram_in_defsym == true) {
switch (ch) {
case '*':
case '=':
case '+':
case '/':
case '-':
case '!':
case '~':
goto quit;
}
}
if(ldgram_in_script == true) {
switch (ch) {
case '*':
case '=':
case '+':
case '-':
case '!':
case '~':
goto quit;
}
}
if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ||
ch == '/' || ch == '.' || ch == '+' || ch == '-' || ch =='=') {
yytext[yyleng++] = ch;
}
else
break;
ch = input();
}
quit:;
yytext[yyleng] = 0;
unput(ch);
for(k = keywords; k ->name != (char *)NULL; k++) {
if (strcmp(k->name, yytext)==0) {
yylval.token = k->value;
return k->value;
}
}
yylval.name = buystring(yytext);
return NAME;
}
%%
void
DEFUN(lex_push_file,(file),
FILE *file)
{
if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
{
einfo("%F:includes nested too deeply");
}
include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
yyin = file;
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
BEGIN(SCRIPT);
}
YY_BUFFER_STATE
DEFUN(yy_create_string_buffer,(string, size),
CONST char *string AND
int size )
{
YY_BUFFER_STATE b;
b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) );
b->yy_input_file = 0;
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 3) );
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_ch_buf[0] = '\n';
strcpy(b->yy_ch_buf+1, string);
b->yy_ch_buf[size+1] = YY_END_OF_BUFFER_CHAR;
b->yy_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR;
b->yy_n_chars = size+1;
b->yy_buf_pos = &b->yy_ch_buf[1];
b->yy_eof_status = EOF_NOT_SEEN;
return ( b );
}
void
DEFUN(lex_redirect,( string),
CONST char *string)
{
YY_BUFFER_STATE tmp;
int len = strlen(string);
yy_init = 0 ;
if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
{
einfo("%F: macros nested too deeply");
}
include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
tmp = yy_create_string_buffer(string, len);
yy_switch_to_buffer(tmp);
BEGIN(COMMAND);
yyout = stdout;
}
int state_stack[20];
int *state_stack_p = state_stack;
void
DEFUN_VOID(ldlex_script)
{
*(state_stack_p)++ = yy_start;
BEGIN(SCRIPT);
}
void
DEFUN_VOID(ldlex_expression)
{
*(state_stack_p)++ = yy_start;
BEGIN(EXPRESSION);
}
void
DEFUN_VOID(ldlex_both)
{
*(state_stack_p)++ = yy_start;
BEGIN(BOTH);
}
void
DEFUN_VOID(ldlex_command)
{
*(state_stack_p)++ = yy_start;
BEGIN(COMMAND);
}
void
DEFUN_VOID(ldlex_popstate)
{
yy_start = *(--state_stack_p);
}
yy_input(buf, result, max_size)
char *buf;
int *result;
int max_size;
{
*result = 0;
if (yy_current_buffer->yy_input_file)
{
if (yyin)
if ( (*result = read( fileno(yyin), (char *) buf, max_size )) < 0 )
YY_FATAL_ERROR( "read() in flex scanner failed" );
}
}

View File

@ -38,6 +38,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "ldindr.h"
#include "ldwarn.h"
#include "ldctor.h"
#include "lderror.h"
/* IMPORTS */
extern boolean lang_has_input_file;
extern boolean trace_files;
@ -118,7 +120,7 @@ unsigned int total_files_seen;
/* IMPORTS */
args_type command_line;
ld_config_type config;
int
void
main (argc, argv)
char **argv;
int argc;
@ -148,6 +150,7 @@ main (argc, argv)
/* Initialize the data about options. */
trace_files = false;
write_map = false;
config.relocateable_output = false;
@ -182,8 +185,11 @@ main (argc, argv)
lang_has_input_file = false;
parse_args(argc, argv);
lang_final();
if (trace_files) {
info("%P: mode %s\n", emulation);
}
if (lang_has_input_file == false) {
einfo("%P%F: No input files\n");
@ -191,6 +197,7 @@ main (argc, argv)
ldemul_after_parse();
if (config.map_filename)
{
if (strcmp(config.map_filename, "-") == 0)
@ -800,7 +807,8 @@ struct lang_input_statement_struct *entry;
}
if (p->section == &bfd_com_section
|| p->flags & BSF_GLOBAL)
|| (p->flags & BSF_GLOBAL)
|| (p->flags & BSF_INDIRECT))
{
register ldsym_type *sp = ldsym_get_soft (p->name);

View File

@ -72,51 +72,73 @@ vfinfo(fp, fmt, arg)
char *fmt;
va_list arg;
{
extern char *cplus_demangle();
boolean fatal = false;
while (*fmt) {
while (*fmt != '%' && *fmt != '\0') {
while (*fmt)
{
while (*fmt != '%' && *fmt != '\0')
{
putc(*fmt, fp);
fmt++;
}
if (*fmt == '%') {
if (*fmt == '%')
{
fmt ++;
switch (*fmt++) {
switch (*fmt++)
{
case 'X':
config.make_executable = false;
break;
case 'V':
{
bfd_vma value = va_arg(arg, bfd_vma);
fprintf_vma(fp, value);
}
{
bfd_vma value = va_arg(arg, bfd_vma);
fprintf_vma(fp, value);
}
break;
case 'T':
{
asymbol *symbol = va_arg(arg, asymbol *);
if (symbol)
{
asymbol *symbol = va_arg(arg, asymbol *);
if (symbol)
asection *section = symbol->section;
char *cplusname = cplus_demangle(symbol->name, 1);
CONST char *section_name = section->name;
if (section != &bfd_und_section)
{
asection *section = symbol->section;
CONST char *section_name = section->name;
fprintf(fp,"%s (%s)", symbol->name, section_name);
fprintf(fp,"%s (%s)", cplusname ? cplusname :
symbol->name, section_name);
}
else
{
fprintf(fp,"no symbol");
fprintf(fp,"%s", cplusname ? cplusname : symbol->name);
}
if (cplusname)
{
free(cplusname);
}
}
else
{
fprintf(fp,"no symbol");
}
}
break;
case 'B':
{
bfd *abfd = va_arg(arg, bfd *);
if (abfd->my_archive) {
{
bfd *abfd = va_arg(arg, bfd *);
if (abfd->my_archive) {
fprintf(fp,"%s(%s)", abfd->my_archive->filename,
abfd->filename);
}
else {
else {
fprintf(fp,"%s", abfd->filename);
}
}
}
break;
case 'F':
fatal = true;
@ -133,38 +155,28 @@ vfinfo(fp, fmt, arg)
break;
case 'I':
{
lang_input_statement_type *i =
va_arg(arg,lang_input_statement_type *);
{
lang_input_statement_type *i =
va_arg(arg,lang_input_statement_type *);
fprintf(fp,"%s", i->local_sym_name);
}
fprintf(fp,"%s", i->local_sym_name);
}
break;
case 'S':
/* Print source script file and line number */
if (ldlex_input_stack) {
extern unsigned int lineno;
if (ldfile_input_filename == (char *)NULL) {
fprintf(fp,"command line");
{
extern unsigned int lineno;
if (ldfile_input_filename == (char *)NULL) {
fprintf(fp,"command line");
}
else {
fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
}
}
else {
fprintf(fp,"%s:%u", ldfile_input_filename, lineno );
}
}
else {
int ch;
int n = 0;
fprintf(fp,"command (just before \"");
ch = lex_input();
while (ch != 0 && n < 10) {
fprintf(fp, "%c", ch);
ch = lex_input();
n++;
}
fprintf(fp,"\")");
}
break;
case 'R':
@ -185,41 +197,52 @@ vfinfo(fp, fmt, arg)
case 'C':
{
CONST char *filename;
CONST char *functionname;
unsigned int linenumber;
bfd *abfd = va_arg(arg, bfd *);
asection *section = va_arg(arg, asection *);
asymbol **symbols = va_arg(arg, asymbol **);
bfd_vma offset = va_arg(arg, bfd_vma);
{
CONST char *filename;
CONST char *functionname;
char *cplus_name;
if (bfd_find_nearest_line(abfd,
section,
symbols,
offset,
&filename,
&functionname,
&linenumber))
{
if (filename == (char *)NULL)
filename = abfd->filename;
if (functionname != (char *)NULL)
fprintf(fp,"%s:%u: (%s)", filename, linenumber, functionname);
else if (linenumber != 0)
fprintf(fp,"%s:%u", filename, linenumber);
else
fprintf(fp,"%s(%s+%0x)", filename,
section->name,
offset);
unsigned int linenumber;
bfd *abfd = va_arg(arg, bfd *);
asection *section = va_arg(arg, asection *);
asymbol **symbols = va_arg(arg, asymbol **);
bfd_vma offset = va_arg(arg, bfd_vma);
if (bfd_find_nearest_line(abfd,
section,
symbols,
offset,
&filename,
&functionname,
&linenumber))
{
if (filename == (char *)NULL)
filename = abfd->filename;
if (functionname != (char *)NULL)
{
cplus_name = cplus_demangle(functionname, 1);
fprintf(fp,"%s:%u: (%s)", filename, linenumber,
cplus_name? cplus_name: functionname);
if (cplus_name)
free(cplus_name);
}
else {
}
else if (linenumber != 0)
fprintf(fp,"%s:%u", filename, linenumber);
else
fprintf(fp,"%s(%s+%0x)", filename,
section->name,
offset);
}
else {
fprintf(fp,"%s(%s+%0x)", abfd->filename,
section->name,
offset);
}
}
}
break;
case 's':
@ -235,11 +258,11 @@ vfinfo(fp, fmt, arg)
}
}
if (fatal == true) {
extern char *output_filename;
if (output_filename)
unlink(output_filename);
exit(1);
}
extern char *output_filename;
if (output_filename)
unlink(output_filename);
exit(1);
}
}
/* Format info message and print on stdout. */
@ -316,6 +339,20 @@ bfd_size_type size)
}
PTR
DEFUN(ldrealloc, (ptr, size),
PTR ptr AND
bfd_size_type size)
{
PTR result = realloc (ptr, (int)size);
if (result == (char *)NULL && size != 0)
einfo("%F%P virtual memory exhausted\n");
return result;
}
char *DEFUN(buystring,(x),
CONST char *CONST x)
@ -327,6 +364,24 @@ char *DEFUN(buystring,(x),
}
/* ('m' for map) Format info message and print on map. */
void minfo(va_alist)
va_dcl
{
char *fmt;
va_list arg;
va_start(arg);
fmt = va_arg(arg, char *);
vfinfo(config.map_file, fmt, arg);
va_end(arg);
}
/*----------------------------------------------------------------------
Functions to print the link map
*/
@ -334,16 +389,16 @@ char *DEFUN(buystring,(x),
void
DEFUN_VOID(print_space)
{
printf(" ");
fprintf(config.map_file, " ");
}
void
DEFUN_VOID(print_nl)
{
printf("\n");
fprintf(config.map_file, "\n");
}
void
DEFUN(print_address,(value),
bfd_vma value)
{
printf_vma(value);
fprintf_vma(config.map_file, value);
}

View File

@ -23,9 +23,10 @@ int
main()
{
int ch;
ch = getchar();
printf("/* Generated through mkscript */\n");
printf("\"{ \\\n");
printf("\"{");
while (ch != EOF) {
if (ch == '\"' || ch == '\\' || ch == '\'') {
putchar('\\');