diff options
-rw-r--r-- | ld/config/st2000.mt | 2 | ||||
-rw-r--r-- | ld/gld960.em | 11 | ||||
-rw-r--r-- | ld/ldgram.y | 203 | ||||
-rw-r--r-- | ld/ldlex.l | 56 | ||||
-rw-r--r-- | ld/mri.c | 69 | ||||
-rw-r--r-- | ld/st2000.em | 86 | ||||
-rwxr-xr-x | ld/st2000.sc-sh | 26 | ||||
-rwxr-xr-x | ld/st2000.sh | 8 |
8 files changed, 383 insertions, 78 deletions
diff --git a/ld/config/st2000.mt b/ld/config/st2000.mt new file mode 100644 index 0000000..2c63001 --- /dev/null +++ b/ld/config/st2000.mt @@ -0,0 +1,2 @@ +EMUL=st2000 + diff --git a/ld/gld960.em b/ld/gld960.em index 23db7ea..e70580d 100644 --- a/ld/gld960.em +++ b/ld/gld960.em @@ -113,11 +113,20 @@ static char *script = #include "gld960.x" ; + +static char *script_reloc = +#include "gld960.xr" + ; + static char * gld960_get_script() { -return script; + extern ld_config_type config; + if (config.relocateable_output) + return script_reloc; + return script; + } struct ld_emulation_xfer_struct ld_gld960_emulation = diff --git a/ld/ldgram.y b/ld/ldgram.y index c4c5603..d6a4830 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -34,7 +34,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ldemul.h" #include "ldfile.h" #include "ldmisc.h" - +#include "mri.h" #define YYDEBUG 1 @@ -78,8 +78,11 @@ boolean ldgram_had_equals = false; /* LOCALS */ - - +#define ERROR_NAME_MAX 20 +static char *error_names[ERROR_NAME_MAX]; +static int error_index; +#define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++; +#define POP_ERROR() error_index--; %} %union { bfd_vma integer; @@ -148,6 +151,9 @@ struct sec *section; %type <name> filename + +%token CHIP LIST SECT ABSOLUTE LOAD + %{ ld_config_type config; %} @@ -187,7 +193,7 @@ command_line_option: } | OPTION_M { config.map_filename = "-"; - + } | OPTION_n { config.magic_demand_paged = false; @@ -292,11 +298,11 @@ 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 END { ldlex_command()}; + { ldfile_open_command_file($2); } mri_script_file END { ldlex_command()}; | OPTION_Tfile { ldfile_open_command_file($1); } script_file -END { ldlex_command();} + END { ldlex_command();} | OPTION_T filename { ldfile_open_command_file($2); } script_file @@ -327,17 +333,61 @@ END { ldlex_command();} ; - +/* SYNTAX WITHIN AN MRI SCRIPT FILE */ +mri_script_file: + { ldlex_mri_script(); + PUSH_ERROR("MRI style script"); + } + mri_script_lines + { ldlex_popstate(); + POP_ERROR(); + } + ; +mri_script_lines: + mri_script_lines mri_script_line + | + ; +mri_script_line: + CHIP exp + | CHIP exp ',' exp + | NAME { + einfo("%P%F: unrecognised keyword in MRI style script '%s'\n", + $1); + } + | LIST { + write_map = true; + config.map_filename = "-"; + } + | SECT NAME ',' exp + { mri_output_section($2, $4);} + | SECT NAME exp + { mri_output_section($2, $3);} + | SECT NAME '=' exp + { mri_output_section($2, $4);} + | ABSOLUTE mri_abs_name_list + | LOAD mri_load_name_list + ; +mri_load_name_list: + NAME + { mri_load($1); } + | mri_load_name_list ',' NAME { mri_load($3); } + ; +mri_abs_name_list: + NAME + { mri_only_load($1); } + | mri_abs_name_list ',' NAME + { mri_only_load($3); } + ; -script_file: +script_file: { ldlex_both(); } - ifile_list + ifile_list { ldlex_popstate(); } @@ -345,7 +395,7 @@ script_file: ifile_list: - ifile_list ifile_p1 + ifile_list ifile_p1 | ; @@ -366,9 +416,9 @@ ifile_p1: { ldfile_add_library_path($3); } | OUTPUT '(' filename ')' { lang_add_output($3); } - | OUTPUT_FORMAT '(' NAME ')' + | OUTPUT_FORMAT '(' NAME ')' { lang_add_output_format($3); } - | OUTPUT_ARCH '(' NAME ')' + | OUTPUT_ARCH '(' NAME ')' { ldfile_set_output_arch($3); } | FORCE_COMMON_ALLOCATION { command_line.force_common_definition = true ; } @@ -384,13 +434,14 @@ input_list: | input_list ',' NAME { lang_add_input_file($3,lang_input_file_is_file_enum, (char *)NULL); } - | input_list NAME - { lang_add_input_file($2, lang_input_file_is_file_enum, + | input_list NAME + { lang_add_input_file($2, +lang_input_file_is_file_enum, (char *)NULL); } ; sections: - SECTIONS '{' sec_or_group_p1 '}' + SECTIONS '{' sec_or_group_p1 '}' ; sec_or_group_p1: @@ -408,7 +459,7 @@ statement_anywhere: file_NAME_list: NAME { lang_add_wild($1, current_file); } - | file_NAME_list opt_comma NAME + | file_NAME_list opt_comma NAME { lang_add_wild($3, current_file); } ; @@ -417,21 +468,21 @@ input_section_spec: { lang_add_wild((char *)NULL, $1); } - | '[' + | '[' { current_file = (char *)NULL; } - file_NAME_list - ']' + file_NAME_list + ']' | NAME { - current_file =$1; - } + current_file =$1; + } '(' file_NAME_list ')' - | '*' - { + | '*' + { current_file = (char *)NULL; - } + } '(' file_NAME_list ')' ; @@ -439,14 +490,16 @@ statement: statement assignment end | statement CREATE_OBJECT_SYMBOLS { - lang_add_attribute(lang_object_symbols_statement_enum); } + +lang_add_attribute(lang_object_symbols_statement_enum); } | statement ';' | statement CONSTRUCTORS { - lang_add_attribute(lang_constructors_statement_enum); } + +lang_add_attribute(lang_constructors_statement_enum); } | statement input_section_spec - | statement length '(' exp ')' + | statement length '(' exp ')' { lang_add_data($2,$4); } @@ -457,17 +510,18 @@ statement: (exp_get_value_int($4, 0, "fill value", - lang_first_phase_enum)); + +lang_first_phase_enum)); } | ; length: - LONG + LONG { $$ = $1; } - | SHORT + | SHORT { $$ = $1; } - | BYTE + | BYTE { $$ = $1; } ; @@ -477,9 +531,9 @@ fill_opt: $$ = exp_get_value_int($2, 0, "fill value", - lang_first_phase_enum); + lang_first_phase_enum); } - | { $$ = 0; } + | { $$ = 0; } ; @@ -487,7 +541,7 @@ fill_opt: assign_op: PLUSEQ { $$ = '+'; } - | MINUSEQ + | MINUSEQ { $$ = '-'; } | MULTEQ { $$ = '*'; } @@ -509,13 +563,14 @@ end: ';' | ',' assignment: - NAME '=' mustbe_exp + NAME '=' mustbe_exp { lang_add_assignment(exp_assop($2,$1,$3)); } - | NAME assign_op mustbe_exp + | NAME assign_op mustbe_exp { - lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3))); + +lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3))); } ; @@ -526,32 +581,30 @@ opt_comma: memory: - MEMORY '{' memory_spec memory_spec_list '}' + MEMORY '{' memory_spec memory_spec_list '}' ; memory_spec_list: - memory_spec_list memory_spec + memory_spec_list memory_spec | memory_spec_list ',' memory_spec | ; -memory_spec: - NAME +memory_spec: NAME { region = lang_memory_region_lookup($1); } - attributes_opt ':' + attributes_opt ':' origin_spec opt_comma length_spec - ; -origin_spec: + ; origin_spec: ORIGIN '=' mustbe_exp { region->current = region->origin = - exp_get_vma($3, 0L,"origin", lang_first_phase_enum); } - ; -length_spec: - LENGTH '=' mustbe_exp - { region->length = exp_get_vma($3, + exp_get_vma($3, 0L,"origin", lang_first_phase_enum); +} + ; length_spec: + LENGTH '=' mustbe_exp + { region->length = exp_get_vma($3, ~((bfd_vma)0), "length", lang_first_phase_enum); @@ -573,13 +626,13 @@ startup: ; high_level_library: - HLL '(' high_level_library_NAME_list ')' - | HLL '(' ')' + HLL '(' high_level_library_NAME_list ')' + | HLL '(' ')' { ldemul_hll((char *)NULL); } ; high_level_library_NAME_list: - high_level_library_NAME_list opt_comma filename + high_level_library_NAME_list opt_comma filename { ldemul_hll($3); } | filename { ldemul_hll($1); } @@ -588,10 +641,9 @@ high_level_library_NAME_list: low_level_library: SYSLIB '(' low_level_library_NAME_list ')' - ; -low_level_library_NAME_list: + ; low_level_library_NAME_list: low_level_library_NAME_list opt_comma filename - { ldemul_syslib($3); } + { ldemul_syslib($3); } | ; @@ -599,27 +651,27 @@ floating_point_support: FLOAT { lang_float(true); } | NOFLOAT - { lang_float(false); } + { lang_float(false); } ; -mustbe_exp: { ldlex_expression(); } +mustbe_exp: { ldlex_expression(); } exp { ldlex_popstate(); $$=$2;} ; exp : - '-' exp %prec UNARY + '-' exp %prec UNARY { $$ = exp_unop('-', $2); } | '(' exp ')' { $$ = $2; } | NEXT '(' exp ')' %prec UNARY { $$ = exp_unop($1,$3); } - | '!' exp %prec UNARY + | '!' exp %prec UNARY { $$ = exp_unop('!', $2); } - | '+' exp %prec UNARY + | '+' exp %prec UNARY { $$ = $2; } - | '~' exp %prec UNARY + | '~' exp %prec UNARY { $$ = exp_unop('~', $2);} | exp '*' exp @@ -631,7 +683,7 @@ exp : | exp '+' exp { $$ = exp_binop('+', $1, $3); } | exp '-' exp - { $$ = exp_binop('-' , $1, $3); } + { $$ = exp_binop('-' , $1, $3); } | exp LSHIFT exp { $$ = exp_binop(LSHIFT , $1, $3); } | exp RSHIFT exp @@ -642,7 +694,7 @@ exp : { $$ = exp_binop(NE , $1, $3); } | exp LE exp { $$ = exp_binop(LE , $1, $3); } - | exp GE exp + | exp GE exp { $$ = exp_binop(GE , $1, $3); } | exp '<' exp { $$ = exp_binop('<' , $1, $3); } @@ -664,10 +716,10 @@ exp : { $$ = exp_nameop(DEFINED, $3); } | INT { $$ = exp_intop($1); } - | SIZEOF_HEADERS + | SIZEOF_HEADERS { $$ = exp_nameop(SIZEOF_HEADERS,0); } - | SIZEOF '(' NAME ')' + | SIZEOF '(' NAME ')' { $$ = exp_nameop(SIZEOF,$3); } | ADDR '(' NAME ')' { $$ = exp_nameop(ADDR,$3); } @@ -680,9 +732,9 @@ exp : -section: NAME { ldlex_expression(); } +section: NAME { ldlex_expression(); } opt_exp { ldlex_popstate(); } - opt_type opt_block ':' opt_things'{' + opt_type opt_block ':' opt_things'{' { lang_enter_output_section_statement($1,$3,$5,$6); } @@ -693,16 +745,16 @@ section: NAME { ldlex_expression(); } ; -opt_type: +opt_type: '(' NOLOAD ')' { $$ = SEC_NO_FLAGS; } | '(' DSECT ')' { $$ = 0; } | '(' COPY ')' { $$ = 0; } | '(' INFO ')' { $$ = 0; } | '(' OVERLAY ')' { $$ = 0; } - | { $$ = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; } + | { $$ = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; } ; -opt_things: +opt_things: { }; @@ -728,4 +780,13 @@ memspec_opt: { $$ = $2; } | { $$ = "*default*"; } ; - +%% +void +yyerror(arg) +char *arg; +{ + if (error_index> 0 && error_index < ERROR_NAME_MAX) + einfo("%P%F: %S syntax error in %s\n",error_names[error_index-1]); + else + einfo("%P%F: %S syntax error\n"); +} @@ -51,12 +51,13 @@ YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; unsigned int include_stack_ptr = 0; -/* FOUR STATES +/* 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 + MRI in an MRI script */ #define RTOKEN(x) { yylval.token = x; return x; } %} @@ -73,6 +74,7 @@ WHITE [ \t\n]+ %x EXPRESSION %x COMMENT %x BOTH +%x MRI %% <COMMAND>"-defsym" { return OPTION_defsym; } @@ -153,7 +155,33 @@ WHITE [ \t\n]+ yylval.name = buystring(yytext+2); return OPTION_Aarch; } -<BOTH,EXPRESSION>"0x"?([0-9A-Fa-f])+(M|K|m|k)? { + +<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ { + yylval.integer = strtol(yytext+1, 0,16); + return INT; + } + +<MRI,EXPRESSION>([0-9A-Fa-f])+(H|X|B|O|D) + { + int base ; + switch (yytext[yyleng-1]) { + case 'X': + case 'H': + base = 16; + break; + case 'O': + base = 8; + break; + case 'B': + base = 2; + break; + default: + base = 10; + } + yylval.integer = strtol(yytext+1, 0, base); + return INT; + } +<MRI,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') { @@ -184,7 +212,7 @@ WHITE [ \t\n]+ <BOTH,SCRIPT,EXPRESSION>"|=" { RTOKEN(OREQ);} <BOTH,SCRIPT,EXPRESSION>"&&" { RTOKEN(ANDAND);} <BOTH,SCRIPT,EXPRESSION>">" { RTOKEN('>');} -<BOTH,SCRIPT,EXPRESSION>"," { RTOKEN(',');} +<MRI,BOTH,SCRIPT,EXPRESSION>"," { RTOKEN(',');} <BOTH,SCRIPT,EXPRESSION>"&" { RTOKEN('&');} <BOTH,SCRIPT,EXPRESSION>"|" { RTOKEN('|');} <BOTH,SCRIPT,EXPRESSION>"~" { RTOKEN('~');} @@ -197,7 +225,7 @@ WHITE [ \t\n]+ <BOTH,SCRIPT,EXPRESSION>"%" { RTOKEN('%');} <BOTH,SCRIPT,EXPRESSION>"<" { RTOKEN('<');} <BOTH,SCRIPT,EXPRESSION>">" { RTOKEN('>');} -<BOTH,SCRIPT,EXPRESSION>"=" { RTOKEN('=');} +<MRI,BOTH,SCRIPT,EXPRESSION>"=" { RTOKEN('=');} <BOTH,SCRIPT,EXPRESSION>"}" { RTOKEN('}') ; } <BOTH,SCRIPT,EXPRESSION>"{" { RTOKEN('{'); } <BOTH,SCRIPT,EXPRESSION>")" { RTOKEN(')');} @@ -250,7 +278,15 @@ WHITE [ \t\n]+ <BOTH,SCRIPT>"l" { RTOKEN( LENGTH);} <BOTH,SCRIPT>"len" { RTOKEN( LENGTH);} -<BOTH,EXPRESSION>{FILENAMECHAR1}{FILENAMECHAR}* { +<MRI>^"*".* { /* Mri comment line */ } +<MRI>\n { ++ lineno; } +<MRI>"CHIP" { RTOKEN(CHIP); } +<MRI>"LOAD" { RTOKEN(LOAD); } +<MRI>"LIST".*\n { RTOKEN(LIST); /* LIST and ignore to end of line */ } +<MRI>"SECT" { RTOKEN(SECT); } +<MRI>"ABSOLUTE" { RTOKEN(ABSOLUTE); } + +<MRI,BOTH,EXPRESSION>{FILENAMECHAR1}{FILENAMECHAR}* { yylval.name = buystring(yytext); return NAME; } @@ -266,7 +302,7 @@ WHITE [ \t\n]+ return NAME; } <BOTH,SCRIPT,EXPRESSION>"\n" { lineno++;} -<COMMAND,BOTH,SCRIPT,EXPRESSION>[ \t] +<MRI,COMMAND,BOTH,SCRIPT,EXPRESSION>[ \t] "/*" { old = INITIAL; BEGIN(COMMENT); } <COMMAND>"/*" { old = COMMAND; BEGIN(COMMENT); } @@ -279,6 +315,7 @@ WHITE [ \t\n]+ <COMMENT>\\n { ++lineno;} <COMMENT>"*"+"/" { BEGIN(old); } + <<EOF>> { include_stack_ptr--; @@ -390,6 +427,13 @@ BEGIN(SCRIPT); void +DEFUN_VOID(ldlex_mri_script) +{ + *(state_stack_p)++ = yy_start; + BEGIN(MRI); +} + +void DEFUN_VOID(ldlex_expression) { *(state_stack_p)++ = yy_start; diff --git a/ld/mri.c b/ld/mri.c new file mode 100644 index 0000000..fd2edcf --- /dev/null +++ b/ld/mri.c @@ -0,0 +1,69 @@ +/* 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. */ + + +/* This bit does the tree decoration when MRI style link scripts are parsed */ + +/* + contributed by Steve Chamberlain + sac@cygnus.com + +*/ + +#include "bfd.h" +#include "sysdep.h" +#include "ldlang.h" +#include "mri.h" +#include "ldexp.h" + +void +DEFUN(mri_output_section, (name, vma), + CONST char *name AND + etree_type *vma) + +{ + lang_output_section_statement_type *os; + + os = lang_output_section_statement_lookup(name); + + if (os->addr_tree == (etree_type *)NULL) { + os->addr_tree = vma; + } + + os->flags = 0; + os->block_value = 0; + } + +/* if any ABSOLUTE <name> are in the script, only load those files +marked thus */ + +void DEFUN(mri_only_load,(name), CONST char *name) + { + + + +} + + +void +DEFUN(mri_load,(name), + CONST char *name) +{ + + lang_add_input_file(name, lang_input_file_is_file_enum, (char *)NULL); +} diff --git a/ld/st2000.em b/ld/st2000.em new file mode 100644 index 0000000..d49ab86 --- /dev/null +++ b/ld/st2000.em @@ -0,0 +1,86 @@ +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 + +*/ + +#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 st2000_before_parse() +{ + ldfile_output_architecture = bfd_arch_m68k; +} + +static char *st2000_script = +#include "st2000.x" +; +static char *st2000_script_option_Ur = +#include "st2000.x" +; +static char *st2000_script_option_r = +#include "st2000.x" +; + +static char *st2000_get_script() +{ + extern ld_config_type config; + if (config.relocateable_output == true && + config.build_constructors == true) { + return st2000_script_option_Ur; + } + if (config.relocateable_output) { + return st2000_script_option_r; + } + + return st2000_script; +} +struct ld_emulation_xfer_struct ld_st2000_emulation = +{ + st2000_before_parse, + syslib_default, + hll_default, + after_parse_default, + after_allocation_default, + set_output_arch_default, + ldemul_default_target, + before_allocation_default, + st2000_get_script, + "st2000" +}; +EOF diff --git a/ld/st2000.sc-sh b/ld/st2000.sc-sh new file mode 100755 index 0000000..7ee132a --- /dev/null +++ b/ld/st2000.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 = .; + +} + +} +EOF + + + + diff --git a/ld/st2000.sh b/ld/st2000.sh new file mode 100755 index 0000000..8dfe710 --- /dev/null +++ b/ld/st2000.sh @@ -0,0 +1,8 @@ +EMULATION_NAME=st2000 +SCRIPT_NAME=st2000 +OUTPUT_FORMAT="coff-m68k" +TEXT_START_ADDR=0x0 +PAGE_SIZE=128 +ARCH=m68k +TEMPLATE_NAME=st2000 + |