From: Steve Chamberlain Date: Sun, 5 Apr 1992 01:47:16 +0000 (+0000) Subject: New lexer. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9d1fe8a4103b93f4de17d0f80b3b80c687811754;p=binutils-gdb.git New lexer. New targets for h8/300 simulator and DOS --- diff --git a/ld/.Sanitize b/ld/.Sanitize index 9641d6a9742..e59fde99f12 100644 --- a/ld/.Sanitize +++ b/ld/.Sanitize @@ -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 diff --git a/ld/ChangeLog b/ld/ChangeLog index c80ff4ecd6c..68b65dd1674 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -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. diff --git a/ld/Makefile.in b/ld/Makefile.in index 80ba99f3734..62898e7c5e5 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -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.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 \ diff --git a/ld/config/go32.mt b/ld/config/go32.mt new file mode 100644 index 00000000000..d5f86db9390 --- /dev/null +++ b/ld/config/go32.mt @@ -0,0 +1 @@ +EMUL=go32 diff --git a/ld/config/ieee-h8300.mt b/ld/config/ieee-h8300.mt new file mode 100644 index 00000000000..575ff471b13 --- /dev/null +++ b/ld/config/ieee-h8300.mt @@ -0,0 +1 @@ +EMUL=h8300xray diff --git a/ld/configure.in b/ld/configure.in index 56321730d4c..8e24810441b 100644 --- a/ld/configure.in +++ b/ld/configure.in @@ -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 diff --git a/ld/go32.sh b/ld/go32.sh new file mode 100755 index 00000000000..cd548d8c793 --- /dev/null +++ b/ld/go32.sh @@ -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 + diff --git a/ld/h8300hms.sc-sh b/ld/h8300hms.sc-sh index 2c668500035..ca19afbba9f 100755 --- a/ld/h8300hms.sc-sh +++ b/ld/h8300hms.sc-sh @@ -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} } diff --git a/ld/h8300xray.em b/ld/h8300xray.em new file mode 100644 index 00000000000..463deb92a95 --- /dev/null +++ b/ld/h8300xray.em @@ -0,0 +1,88 @@ +cat >ld__${EMULATION_NAME}.c < exp opt_exp +%type exp opt_exp mustbe_exp %type fill_opt opt_block opt_type %type memspec_opt %token INT @@ -123,6 +123,7 @@ struct sec *section; /*%token '+' '-' '*' '/' '%'*/ %right UNARY +%token END %left '(' %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*"; } ; diff --git a/ld/ldlang.c b/ld/ldlang.c index f44cd18a2b8..9483a774ab1 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -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: - { - bfd_vma after; - lang_output_section_statement_type *os = - &(s->output_section_statement); - /* The start of a section */ + { + switch (s->header.type) { - 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; + 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*"); } - /* The section starts here */ - /* First, align to what the section needs */ + 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 */ + dot = align_power(dot, os->bfd_section->alignment_power); + os->bfd_section->vma = dot; + } + + + os->bfd_section->output_offset = 0; + (void) lang_size_sections(os->children.head, os, &os->children.head, + os->fill, dot, relax); + /* Ignore the size of the input sections, use the vma and size to */ + /* align against */ - after = ALIGN(os->bfd_section->vma + - os->bfd_section->_raw_size, - os->block_value) ; + after = ALIGN(os->bfd_section->vma + + os->bfd_section->_raw_size, + os->block_value) ; - os->bfd_section->_raw_size = after - os->bfd_section->vma; - dot = os->bfd_section->vma + os->bfd_section->_raw_size; - os->processed = true; - /* Replace into region ? */ - if (os->addr_tree == (etree_type *)NULL - && os->region !=(lang_memory_region_type*)NULL ) { - os->region->current = dot; - /* 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; - 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: + /* 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) { - 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; + 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; - } - dot += size; - output_section_statement->bfd_section->_raw_size += size; } - break; + + } + } - case lang_wild_statement_enum: + break; + case lang_constructors_statement_enum: + dot = lang_size_sections(constructor_list.head, + output_section_statement, + &s->wild_statement.children.head, + fill, + dot, relax); + break; + + case lang_data_statement_enum: + { + unsigned int size = 0; + s->data_statement.output_vma = dot - output_section_statement->bfd_section->vma; + s->data_statement.output_section = + output_section_statement->bfd_section; + + switch (s->data_statement.type) { + case LONG: + size = LONG_SIZE; + break; + case SHORT: + size = SHORT_SIZE; + break; + case BYTE: + size = BYTE_SIZE; + break; + + } + dot += size; + output_section_statement->bfd_section->_raw_size += size; + } + break; + + case lang_wild_statement_enum: - dot = lang_size_sections(s->wild_statement.children.head, + 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); - - 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; + 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: + 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; + 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; diff --git a/ld/ldlex.l b/ld/ldlex.l index cf7fd47a88c..147db3e4f2a 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -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 */ +typedef int bfd_vma; +#include +#include "ldgram.h" -/*SUPPRESS 529*/ -/*SUPPRESS 26*/ -/*SUPPRESS 29*/ -/*#define LEXDEBUG 0*/ -#include "bfd.h" -#include "sysdep.h" +int ldgram_in_defsym; +int ldgram_had_equals; +int ldgram_in_script; -#include -#include "ldlex.h" +int hex_mode; +extern int fgetc(); +extern int yyparse(); -#include "ld.h" -#include "ldexp.h" -#include "ldgram.h" -#include "ldmisc.h" -#undef input -#undef unput -#define input lex_input -#define unput lex_unput -int debug; +char *buystring(); +int lineno = 1; +int old; -static boolean ldgram_in_defsym; -static boolean ldgram_had_equals; -extern boolean ldgram_in_script; -static char *command_line; +#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; -extern int fgetc(); -extern int yyparse(); -typedef struct { - char *name; -int value; -} keyword_type; +/* 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 ; -} +%a 4000 +%o 5000 +FILENAMECHAR1 [_a-zA-Z\/\.\\] +FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\] +FILENAME {FILENAMECHAR}+ +WHITE [ \t\n]+ -void -lex_unput(c) -int c; -{ - if (have_pushback > NPUSHBACK) { - info("%F%P Too many pushbacks\n"); +%x COMMAND +%x SCRIPT +%x EXPRESSION +%x COMMENT +%x BOTH +%% + +"-defsym" { return OPTION_defsym; } +"-noinhibit_exec" { return OPTION_noinhibit_exec; } +"-noinhibit-exec" { return OPTION_noinhibit_exec; } +"-sort_common" { return OPTION_sort_common;} +"-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; } +"-Bstat" { return OPTION_Bstatic; } +"-B"{FILENAME} { /* Ignored */ } +"-l"{FILENAME} { + yylval.name = buystring(yytext+2); + return OPTION_l; + } + +"-L"{FILENAME} { + yylval.name = buystring(yytext+2); + 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+2); + return OPTION_Texp; + } + +"-T"{FILENAME} { + yylval.name = buystring(yytext+2); + return OPTION_Tfile; + } +"-T" { + return OPTION_T; + } + +"-F"{FILENAME} { + return OPTION_F; + } +"-F" { + return OPTION_F; + } + +"-A"{FILENAME} { + yylval.name = buystring(yytext+2); + return OPTION_Aarch; + } +"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; + } +"]" { RTOKEN(']');} +"[" { RTOKEN('[');} +"<<=" { 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(']');} +"[" { RTOKEN('[');} +":" { RTOKEN(':'); } +";" { RTOKEN(';');} +"-" { RTOKEN('-');} +"/" { RTOKEN('/');} +"MEMORY" { RTOKEN(MEMORY);} +"ORIGIN" { RTOKEN(ORIGIN);} +"BLOCK" { RTOKEN(BLOCK);} +"LENGTH" { RTOKEN(LENGTH);} +"ALIGN" { RTOKEN(ALIGN_K);} +"ADDR" { RTOKEN(ADDR);} +"ENTRY" { RTOKEN(ENTRY);} +"NEXT" { RTOKEN(NEXT);} +"sizeof_headers" { RTOKEN(SIZEOF_HEADERS);} +"SIZEOF_HEADERS" { RTOKEN(SIZEOF_HEADERS);} +"MAP" { RTOKEN(MAP);} +"SIZEOF" { RTOKEN(SIZEOF);} +"TARGET" { RTOKEN(TARGET_K);} +"SEARCH_DIR" { RTOKEN(SEARCH_DIR);} +"OUTPUT" { RTOKEN(OUTPUT);} +"INPUT" { RTOKEN(INPUT);} +"DEFINED" { RTOKEN(DEFINED);} +"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);} +"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);} +"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);} +"SECTIONS" { RTOKEN(SECTIONS);} +"FILL" { RTOKEN(FILL);} +"STARTUP" { RTOKEN(STARTUP);} +"OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT);} +"OUTPUT_ARCH" { RTOKEN( OUTPUT_ARCH);} +"HLL" { RTOKEN(HLL);} +"SYSLIB" { RTOKEN(SYSLIB);} +"FLOAT" { RTOKEN(FLOAT);} +"LONG" { RTOKEN( LONG);} +"SHORT" { RTOKEN( SHORT);} +"BYTE" { RTOKEN( BYTE);} +"NOFLOAT" { RTOKEN(NOFLOAT);} +"NOLOAD" { RTOKEN(NOLOAD);} +"DSECT" { RTOKEN(DSECT);} +"COPY" { RTOKEN(COPY);} +"INFO" { RTOKEN(INFO);} +"OVERLAY" { RTOKEN(OVERLAY);} +"o" { RTOKEN(ORIGIN);} +"org" { RTOKEN(ORIGIN);} +"l" { RTOKEN( LENGTH);} +"len" { RTOKEN( LENGTH);} + +{FILENAMECHAR1}{FILENAMECHAR}* { + yylval.name = buystring(yytext); + return NAME; + } +{FILENAMECHAR}* { yylval.name = buystring(yytext); + return NAME; + } + +"\""[^\"]*"\"" { + /* No matter the state, quotes + give what's inside */ + yylval.name = buystring(yytext+1); + yylval.name[yyleng-2] = 0; + return NAME; + } +"\n" { lineno++;} +[ \t] + +"/*" { old = INITIAL; BEGIN(COMMENT); } +"/*" { old = COMMAND; BEGIN(COMMENT); } +"/*" { old =BOTH; BEGIN(COMMENT); } +