Support for linking and loading at different places:

* ldlex.l: Add "AT" keyword.
	* ldgram.y: Cleanup, and parse AT.
	* ldlang.c (print_output_section_statement): Print output address
	of section in map. (lang_size_sections): Fill sections' lma with
	load address.
	* ldlang.h (lang_output_section_statement_type): Add load_base
	information.
This commit is contained in:
Steve Chamberlain
1993-03-30 22:45:39 +00:00
parent 01b4d31847
commit 9fce28edd5
4 changed files with 108 additions and 49 deletions

View File

@ -1,5 +1,15 @@
Tue Mar 30 09:40:25 1993 Steve Chamberlain (sac@thepub.cygnus.com) Tue Mar 30 09:40:25 1993 Steve Chamberlain (sac@thepub.cygnus.com)
Support for linking and loading at different places:
* ldlex.l: Add "AT" keyword.
* ldgram.y: Cleanup, and parse AT.
* ldlang.c (print_output_section_statement): Print output address
of section in map. (lang_size_sections): Fill sections' lma with
load address.
* ldlang.h (lang_output_section_statement_type): Add load_base
information.
* ldindr.c (add_indirect): Keep more information in the alias * ldindr.c (add_indirect): Keep more information in the alias
symbol chain. symbol chain.
* ldlang.c (wild_doit): Don't inherit NEVER_LOAD section * ldlang.c (wild_doit): Don't inherit NEVER_LOAD section

View File

@ -54,11 +54,11 @@ lang_memory_region_type *region;
lang_memory_region_type *lang_memory_region_lookup(); lang_memory_region_type *lang_memory_region_lookup();
lang_output_section_statement_type *lang_output_section_statement_lookup(); lang_output_section_statement_type *lang_output_section_statement_lookup();
etree_type *lang_atin();
#ifdef __STDC__ #ifdef __STDC__
void lang_add_data(int type, union etree_union *exp); void lang_add_data(int type, union etree_union *exp);
void lang_enter_output_section_statement(char *output_section_statement_name, etree_type *address_exp, int flags, bfd_vma block_value,etree_type*,etree_type*); void lang_enter_output_section_statement(char *output_section_statement_name, etree_type *address_exp, int flags, bfd_vma block_value,etree_type*,etree_type*, etree_type*);
#else #else
@ -103,7 +103,7 @@ struct sec *section;
} }
%type <etree> exp opt_exp_with_type mustbe_exp %type <etree> exp opt_exp_with_type mustbe_exp opt_at
%type <integer> fill_opt %type <integer> fill_opt
%type <name> memspec_opt %type <name> memspec_opt
%token <integer> INT %token <integer> INT
@ -138,6 +138,7 @@ struct sec *section;
%token NOLOAD DSECT COPY INFO OVERLAY %token NOLOAD DSECT COPY INFO OVERLAY
%token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY %token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
%token OPTION_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S OPTION_sort_common %token OPTION_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S OPTION_sort_common
%token OPTION_EB OPTION_EL
%token OPTION_format OPTION_F OPTION_u OPTION_Bstatic OPTION_N %token OPTION_format OPTION_F OPTION_u OPTION_Bstatic OPTION_N
%token <integer> SIZEOF NEXT ADDR %token <integer> SIZEOF NEXT ADDR
%token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym
@ -149,7 +150,7 @@ struct sec *section;
%token OPTION_Ur %token OPTION_Ur
%token ORIGIN FILL OPTION_g %token ORIGIN FILL OPTION_g
%token LENGTH CREATE_OBJECT_SYMBOLS INPUT OUTPUT CONSTRUCTORS %token LENGTH CREATE_OBJECT_SYMBOLS INPUT OUTPUT CONSTRUCTORS
%token OPTION_RETAIN_SYMBOLS_FILE ALIGNMOD %token OPTION_RETAIN_SYMBOLS_FILE ALIGNMOD AT
%type <token> assign_op %type <token> assign_op
@ -196,9 +197,9 @@ command_line_option:
write_map = true; write_map = true;
config.map_filename = $2; config.map_filename = $2;
} }
| OPTION_M { | OPTION_M
{
config.map_filename = "-"; config.map_filename = "-";
} }
| OPTION_n { | OPTION_n {
config.magic_demand_paged = false; config.magic_demand_paged = false;
@ -335,6 +336,18 @@ command_line_option:
} }
| OPTION_RETAIN_SYMBOLS_FILE filename | OPTION_RETAIN_SYMBOLS_FILE filename
{ lang_add_keepsyms_file ($2); } { lang_add_keepsyms_file ($2); }
| OPTION_EB
{
/* FIXME: This is currently ignored. It means
``produce a big-endian object file''. It could
be used to select an output format. */
}
| OPTION_EL
{
/* FIXME: This is currently ignored. It means
``produce a little-endian object file''. It could
be used to select an output format. */
}
| '-' NAME | '-' NAME
{ info("%P%F Unrecognized option -%s\n", $2); } { info("%P%F Unrecognized option -%s\n", $2); }
@ -528,33 +541,36 @@ input_section_spec:
; ;
statement: statement:
statement assignment end assignment end
| statement CREATE_OBJECT_SYMBOLS | CREATE_OBJECT_SYMBOLS
{
lang_add_attribute(lang_object_symbols_statement_enum);
}
| ';'
| CONSTRUCTORS
{ {
lang_add_attribute(lang_object_symbols_statement_enum); } lang_add_attribute(lang_constructors_statement_enum);
| statement ';' }
| statement CONSTRUCTORS | input_section_spec
| length '(' exp ')'
{ {
lang_add_data($1,$3);
lang_add_attribute(lang_constructors_statement_enum); }
| statement input_section_spec
| statement length '(' exp ')'
{
lang_add_data($2,$4);
} }
| statement FILL '(' exp ')' | FILL '(' exp ')'
{ {
lang_add_fill lang_add_fill
(exp_get_value_int($4, (exp_get_value_int($3,
0, 0,
"fill value", "fill value",
lang_first_phase_enum)); lang_first_phase_enum));
} }
| ;
statement_list:
statement_list statement
| statement
; ;
length: length:
@ -773,19 +789,23 @@ exp :
; ;
opt_at:
AT '(' exp ')' { $$ = $3; }
| { $$ = 0; }
;
section: NAME { ldlex_expression(); } section: NAME { ldlex_expression(); }
opt_exp_with_type { ldlex_popstate(); } opt_exp_with_type
opt_at { ldlex_popstate(); }
'{' '{'
{ {
lang_enter_output_section_statement($1,$3,typebits,0,0,0); lang_enter_output_section_statement($1,$3,typebits,0,0,0,$4);
} }
statement statement_list
'}' {ldlex_expression();} fill_opt memspec_opt '}' {ldlex_expression();} fill_opt memspec_opt
{ {
ldlex_popstate(); ldlex_popstate();
lang_leave_output_section_statement($10, $11); lang_leave_output_section_statement($11, $12);
} }
opt_comma opt_comma
@ -804,7 +824,8 @@ type:
opt_exp_with_type: opt_exp_with_type:
exp ':' { $$ = $1; typebits =0;} exp ':' { $$ = $1; typebits =0;}
| exp '(' type ')' ':' { $$ = $1; } | exp '(' type ')' ':' { $$ = $1; }
| ':' { $$= (etree_type *)NULL; typebits = 0} | ':' { $$= (etree_type *)NULL; typebits = 0; }
| '(' type ')' ':' { $$= (etree_type *)NULL; }
; ;
memspec_opt: memspec_opt:

View File

@ -95,6 +95,10 @@ extern ld_config_type config;
extern boolean had_script; extern boolean had_script;
extern boolean write_map; extern boolean write_map;
etree_type *base; /* Relocation base - or null */
#ifdef __STDC__ #ifdef __STDC__
#define cat(a,b) a##b #define cat(a,b) a##b
#else #else
@ -1091,6 +1095,12 @@ DEFUN (print_output_section_statement, (output_section_statement),
fprintf (config.map_file, "No attached output section"); fprintf (config.map_file, "No attached output section");
} }
print_nl (); print_nl ();
if (output_section_statement->load_base)
{
int b = exp_get_value_int(output_section_statement->load_base,
0, "output base", lang_final_phase_enum);
printf("Output address %08x\n", b);
}
if (output_section_statement->section_alignment >= 0 if (output_section_statement->section_alignment >= 0
|| output_section_statement->section_alignment >= 0) || output_section_statement->section_alignment >= 0)
{ {
@ -1583,6 +1593,11 @@ DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
dot = align_power (dot, os->bfd_section->alignment_power); dot = align_power (dot, os->bfd_section->alignment_power);
bfd_set_section_vma (0, os->bfd_section, dot); bfd_set_section_vma (0, os->bfd_section, dot);
if (os->load_base) {
os->bfd_section->lma
= exp_get_value_int(os->load_base, 0,"load base", lang_final_phase_enum);
}
} }
@ -1609,9 +1624,9 @@ DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
{ {
os->region->current = dot; os->region->current = dot;
/* Make sure this isn't silly */ /* Make sure this isn't silly */
if (os->region->current > if (( os->region->current
os->region->origin + > os->region->origin + os->region->length)
os->region->length) || ( os->region->origin > os->region->current ))
{ {
einfo ("%X%P: Region %s is full (%B section %s)\n", einfo ("%X%P: Region %s is full (%B section %s)\n",
os->region->name, os->region->name,
@ -2319,13 +2334,14 @@ DEFUN (lang_enter_output_section_statement,
address_exp, address_exp,
flags, flags,
block_value, block_value,
align, subalign), align, subalign, base),
char *output_section_statement_name AND char *output_section_statement_name AND
etree_type * address_exp AND etree_type * address_exp AND
int flags AND int flags AND
bfd_vma block_value AND bfd_vma block_value AND
etree_type *align AND etree_type *align AND
etree_type *subalign) etree_type *subalign AND
etree_type *base)
{ {
lang_output_section_statement_type *os; lang_output_section_statement_type *os;
@ -2361,8 +2377,11 @@ DEFUN (lang_enter_output_section_statement,
os->section_alignment = topower( os->section_alignment = topower(
exp_get_value_int(align, -1, exp_get_value_int(align, -1,
"section alignment", 0)); "section alignment", 0));
os->load_base = base;
} }
void void
DEFUN_VOID (lang_final) DEFUN_VOID (lang_final)
{ {
@ -2765,3 +2784,4 @@ DEFUN (lang_add_output_format, (format),
{ {
output_target = format; output_target = format;
} }

View File

@ -184,6 +184,12 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
<COMMAND>"-retain-symbols-file" { return OPTION_RETAIN_SYMBOLS_FILE; } <COMMAND>"-retain-symbols-file" { return OPTION_RETAIN_SYMBOLS_FILE; }
<COMMAND>"-EB" {
return OPTION_EB;
}
<COMMAND>"-EL" {
return OPTION_EL;
}
<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ { <MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
yylval.integer = strtoul(yytext+1, 0,16); yylval.integer = strtoul(yytext+1, 0,16);
return INT; return INT;
@ -208,7 +214,7 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
yylval.integer = strtoul(yytext+1, 0, base); yylval.integer = strtoul(yytext+1, 0, base);
return INT; return INT;
} }
<DEFSYMEXP,MRI,BOTH,EXPRESSION>"$"?"0x"?([0-9A-Fa-f])+(M|K|m|k)? { <SCRIPT,DEFSYMEXP,MRI,BOTH,EXPRESSION>"$"?"0x"?([0-9A-Fa-f])+(M|K|m|k)? {
yylval.integer = strtoul(yytext,0,hex_mode); yylval.integer = strtoul(yytext,0,hex_mode);
if (yytext[yyleng-1]=='M' if (yytext[yyleng-1]=='M'
|| yytext[yyleng-1] == 'm') { || yytext[yyleng-1] == 'm') {
@ -305,6 +311,7 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
<BOTH,SCRIPT>"l" { RTOKEN( LENGTH);} <BOTH,SCRIPT>"l" { RTOKEN( LENGTH);}
<BOTH,SCRIPT>"len" { RTOKEN( LENGTH);} <BOTH,SCRIPT>"len" { RTOKEN( LENGTH);}
<BOTH,SCRIPT>"INCLUDE" { RTOKEN(INCLUDE);} <BOTH,SCRIPT>"INCLUDE" { RTOKEN(INCLUDE);}
<EXPRESSION,BOTH,SCRIPT>"AT" { RTOKEN(AT);}
<MRI>"\n" { ++ lineno; RTOKEN(NEWLINE); } <MRI>"\n" { ++ lineno; RTOKEN(NEWLINE); }
<MRI>"*".* { /* Mri comment line */ } <MRI>"*".* { /* Mri comment line */ }
<MRI>"END" { RTOKEN(ENDWORD); } <MRI>"END" { RTOKEN(ENDWORD); }
@ -383,6 +390,7 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
} }
else else
{ {
BEGIN(SCRIPT);
ldfile_input_filename = file_name_stack[include_stack_ptr-1]; ldfile_input_filename = file_name_stack[include_stack_ptr-1];
} }