Personal checkpoint - now should parse some MRI stuff

This commit is contained in:
Steve Chamberlain 1992-04-15 22:23:33 +00:00
parent b7311408af
commit 3d2b83ea49
8 changed files with 383 additions and 78 deletions

2
ld/config/st2000.mt Normal file
View File

@ -0,0 +1,2 @@
EMUL=st2000

View File

@ -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 =

View File

@ -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");
}

View File

@ -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--;
@ -389,6 +426,13 @@ BEGIN(SCRIPT);
}
void
DEFUN_VOID(ldlex_mri_script)
{
*(state_stack_p)++ = yy_start;
BEGIN(MRI);
}
void
DEFUN_VOID(ldlex_expression)
{

69
ld/mri.c Normal file
View File

@ -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);
}

86
ld/st2000.em Normal file
View File

@ -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

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

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

8
ld/st2000.sh Executable file
View File

@ -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