aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/config/st2000.mt2
-rw-r--r--ld/gld960.em11
-rw-r--r--ld/ldgram.y203
-rw-r--r--ld/ldlex.l56
-rw-r--r--ld/mri.c69
-rw-r--r--ld/st2000.em86
-rwxr-xr-xld/st2000.sc-sh26
-rwxr-xr-xld/st2000.sh8
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");
+}
diff --git a/ld/ldlex.l b/ld/ldlex.l
index 147db3e..c2eb5ea 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -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
+