mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-29 08:24:05 +08:00
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:
10
ld/ChangeLog
10
ld/ChangeLog
@ -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
|
||||||
|
91
ld/ldgram.y
91
ld/ldgram.y
@ -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,10 +197,10 @@ 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,35 +541,38 @@ 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_attribute(lang_constructors_statement_enum); }
|
|
||||||
|
|
||||||
| statement input_section_spec
|
|
||||||
| statement length '(' exp ')'
|
|
||||||
{
|
{
|
||||||
lang_add_data($2,$4);
|
lang_add_data($1,$3);
|
||||||
}
|
}
|
||||||
|
|
||||||
| 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:
|
||||||
LONG
|
LONG
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
@ -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
|
||||||
|
|
||||||
@ -802,9 +822,10 @@ 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:
|
||||||
|
46
ld/ldlang.c
46
ld/ldlang.c
@ -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,18 +1624,18 @@ 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,
|
||||||
os->bfd_section->owner,
|
os->bfd_section->owner,
|
||||||
os->bfd_section->name);
|
os->bfd_section->name);
|
||||||
/* Reset the region pointer */
|
/* Reset the region pointer */
|
||||||
os->region->current = 0;
|
os->region->current = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
ld/ldlex.l
10
ld/ldlex.l
@ -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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user