diff options
-rw-r--r-- | ld/.Sanitize | 8 | ||||
-rw-r--r-- | ld/ChangeLog | 12 | ||||
-rw-r--r-- | ld/Makefile.in | 29 | ||||
-rw-r--r-- | ld/config/go32.mt | 1 | ||||
-rw-r--r-- | ld/config/ieee-h8300.mt | 1 | ||||
-rw-r--r-- | ld/configure.in | 26 | ||||
-rwxr-xr-x | ld/go32.sh | 9 | ||||
-rwxr-xr-x | ld/h8300hms.sc-sh | 5 | ||||
-rw-r--r-- | ld/h8300xray.em | 88 | ||||
-rwxr-xr-x | ld/h8300xray.sc-sh | 26 | ||||
-rwxr-xr-x | ld/h8300xray.sh | 8 | ||||
-rw-r--r-- | ld/ldgram.y | 98 | ||||
-rw-r--r-- | ld/ldlang.c | 544 | ||||
-rw-r--r-- | ld/ldlex.l | 817 | ||||
-rw-r--r-- | ld/ldmain.c | 12 | ||||
-rw-r--r-- | ld/ldmisc.c | 221 | ||||
-rw-r--r-- | ld/mkscript.c | 3 |
17 files changed, 942 insertions, 966 deletions
diff --git a/ld/.Sanitize b/ld/.Sanitize index 9641d6a..e59fde9 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 c80ff4e..68b65dd 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 80ba99f..62898e7 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.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 \ diff --git a/ld/config/go32.mt b/ld/config/go32.mt new file mode 100644 index 0000000..d5f86db --- /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 0000000..575ff47 --- /dev/null +++ b/ld/config/ieee-h8300.mt @@ -0,0 +1 @@ +EMUL=h8300xray diff --git a/ld/configure.in b/ld/configure.in index 5632173..8e24810 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 0000000..cd548d8 --- /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 2c66850..ca19afb 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 0000000..463deb9 --- /dev/null +++ b/ld/h8300xray.em @@ -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 diff --git a/ld/h8300xray.sc-sh b/ld/h8300xray.sc-sh new file mode 100755 index 0000000..b0a4622 --- /dev/null +++ b/ld/h8300xray.sc-sh @@ -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 + + + + diff --git a/ld/h8300xray.sh b/ld/h8300xray.sh new file mode 100755 index 0000000..ee84e70 --- /dev/null +++ b/ld/h8300xray.sh @@ -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 + diff --git a/ld/ldgram.y b/ld/ldgram.y index ce0f4a1..c4c5603 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -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*"; } ; diff --git a/ld/ldlang.c b/ld/ldlang.c index f44cd18..9483a77 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; @@ -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 <ansidecl.h> +#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 <ctype.h> -#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 +%% + +<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; + } + +<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; + } + +<COMMAND>"-T"{FILENAME} { + yylval.name = buystring(yytext+2); + return OPTION_Tfile; + } +<COMMAND>"-T" { + return OPTION_T; + } + +<COMMAND>"-F"{FILENAME} { + return OPTION_F; + } +<COMMAND>"-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);} + +<BOTH,EXPRESSION>{FILENAMECHAR1}{FILENAMECHAR}* { + yylval.name = buystring(yytext); + return NAME; + } +<SCRIPT,COMMAND>{FILENAMECHAR}* { yylval.name = buystring(yytext); + return NAME; + } + +<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); } + +<<EOF>> { + include_stack_ptr--; + + if (include_stack_ptr == 0) + { + yyterminate(); + } + else + { + yy_switch_to_buffer(include_stack[include_stack_ptr]); + } + BEGIN(COMMAND); + return END; } + - 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; +DEFUN(lex_push_file,(file), + FILE *file) { - 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; + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) + { + einfo("%F:includes nested too deeply"); } - *dst = 0; - parse_line(p); - - free(p); - + include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; + yyin = file; + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + BEGIN(SCRIPT); } -static long -DEFUN(number,(default_if_zero,base), - int default_if_zero AND - int base) +YY_BUFFER_STATE +DEFUN(yy_create_string_buffer,(string, size), + CONST char *string AND + int size ) { - 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(); - } -} -%} + YY_BUFFER_STATE b; -%a 4000 -%o 5000 -FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=] -FILENAME {FILENAMECHAR}+ -WHITE [ \t]+ + 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; -"@" { 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; - } - -"\ -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; - } - -"\ -T"{FILENAME} { - yylval.name = buystring(yytext+3); - return OPTION_Tfile; - } -"\ -T\ " { - return OPTION_T; - } - -"\ -F"{FILENAME} { - return OPTION_F; - } -"\ -F\ " { - return OPTION_F; - } - -"\ -A"{FILENAME} { - yylval.name = buystring(yytext+3); - return OPTION_Aarch; - } - -" " { - 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('-');} - - - -"/*" { - while (1) { - int ch; - ch = input(); - while (ch != '*') { - ch = input(); - } + /* 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()" ); - if (input() == '/') { - break; - } - unput(yytext[yyleng-1]); - } -} + 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; - yylval.name = buystring(yytext+1); - yylval.name[yyleng-2] = 0; /* Fry final quote */ - return NAME; + return ( b ); } -{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. */ +void +DEFUN(lex_redirect,( string), + CONST char *string) +{ + YY_BUFFER_STATE tmp; - if (hex_mode) { - return number(16, 16); + 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; - /* 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); - } + 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; - /* Otherwise if we're in a script we will parse the numbers - normally */ +void +DEFUN_VOID(ldlex_script) +{ +*(state_stack_p)++ = yy_start; - if (ldgram_in_script == true && isdigit(yytext[0])) { - return number(8,10); - } +BEGIN(SCRIPT); +} - /* 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('~'); - } - } +void +DEFUN_VOID(ldlex_expression) +{ +*(state_stack_p)++ = yy_start; +BEGIN(EXPRESSION); -/* 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_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" ); + } +} - - -%% diff --git a/ld/ldmain.c b/ld/ldmain.c index c42c208..8903936 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -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); diff --git a/ld/ldmisc.c b/ld/ldmisc.c index f67f235..87a91c9 100644 --- a/ld/ldmisc.c +++ b/ld/ldmisc.c @@ -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"); - } - 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++; + { + + + extern unsigned int lineno; + if (ldfile_input_filename == (char *)NULL) { + fprintf(fp,"command line"); + } + else { + fprintf(fp,"%s:%u", ldfile_input_filename, lineno ); + } } - 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; + + 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) - 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); - - } - else { + 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 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); } diff --git a/ld/mkscript.c b/ld/mkscript.c index e0f66ee..66ddfc2 100644 --- a/ld/mkscript.c +++ b/ld/mkscript.c @@ -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('\\'); |