From: Steve Chamberlain Date: Tue, 30 Mar 1993 22:45:39 +0000 (+0000) Subject: Support for linking and loading at different places: X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9fce28edd50c09017ccfc29f30508362081ed66f;p=binutils-gdb.git 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. --- diff --git a/ld/ChangeLog b/ld/ChangeLog index 0812c0b7368..6ce807f6d69 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,15 @@ 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 symbol chain. * ldlang.c (wild_doit): Don't inherit NEVER_LOAD section diff --git a/ld/ldgram.y b/ld/ldgram.y index eb9000a94ad..e106b5f5c14 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -54,11 +54,11 @@ lang_memory_region_type *region; lang_memory_region_type *lang_memory_region_lookup(); lang_output_section_statement_type *lang_output_section_statement_lookup(); - +etree_type *lang_atin(); #ifdef __STDC__ 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 @@ -103,7 +103,7 @@ struct sec *section; } -%type exp opt_exp_with_type mustbe_exp +%type exp opt_exp_with_type mustbe_exp opt_at %type fill_opt %type memspec_opt %token INT @@ -138,6 +138,7 @@ struct sec *section; %token NOLOAD DSECT COPY INFO OVERLAY %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_EB OPTION_EL %token OPTION_format OPTION_F OPTION_u OPTION_Bstatic OPTION_N %token SIZEOF NEXT ADDR %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym @@ -149,7 +150,7 @@ struct sec *section; %token OPTION_Ur %token ORIGIN FILL OPTION_g %token LENGTH CREATE_OBJECT_SYMBOLS INPUT OUTPUT CONSTRUCTORS -%token OPTION_RETAIN_SYMBOLS_FILE ALIGNMOD +%token OPTION_RETAIN_SYMBOLS_FILE ALIGNMOD AT %type assign_op @@ -196,10 +197,10 @@ command_line_option: write_map = true; config.map_filename = $2; } - | OPTION_M { - config.map_filename = "-"; - - } + | OPTION_M + { + config.map_filename = "-"; + } | OPTION_n { config.magic_demand_paged = false; } @@ -335,6 +336,18 @@ command_line_option: } | OPTION_RETAIN_SYMBOLS_FILE filename { 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 { info("%P%F Unrecognized option -%s\n", $2); } @@ -528,35 +541,38 @@ input_section_spec: ; statement: - statement assignment end - | statement CREATE_OBJECT_SYMBOLS + assignment end + | CREATE_OBJECT_SYMBOLS { - -lang_add_attribute(lang_object_symbols_statement_enum); } - | statement ';' - | statement CONSTRUCTORS + lang_add_attribute(lang_object_symbols_statement_enum); + } + | ';' + | CONSTRUCTORS { -lang_add_attribute(lang_constructors_statement_enum); } - - | statement input_section_spec - | statement length '(' exp ')' + lang_add_attribute(lang_constructors_statement_enum); + } + | input_section_spec + | length '(' exp ')' { - lang_add_data($2,$4); + lang_add_data($1,$3); } - | statement FILL '(' exp ')' + | FILL '(' exp ')' { lang_add_fill - (exp_get_value_int($4, + (exp_get_value_int($3, 0, "fill value", - -lang_first_phase_enum)); + lang_first_phase_enum)); } - | ; +statement_list: + statement_list statement + | statement + ; + length: LONG { $$ = $1; } @@ -773,19 +789,23 @@ exp : ; - +opt_at: + AT '(' exp ')' { $$ = $3; } + | { $$ = 0; } + ; 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); - } - statement + { + lang_enter_output_section_statement($1,$3,typebits,0,0,0,$4); + } + statement_list '}' {ldlex_expression();} fill_opt memspec_opt { ldlex_popstate(); - lang_leave_output_section_statement($10, $11); + lang_leave_output_section_statement($11, $12); } opt_comma @@ -802,9 +822,10 @@ type: opt_exp_with_type: - exp ':' { $$ = $1; typebits =0;} - | exp '(' type ')' ':' { $$ = $1; } - | ':' { $$= (etree_type *)NULL; typebits = 0} + exp ':' { $$ = $1; typebits =0;} + | exp '(' type ')' ':' { $$ = $1; } + | ':' { $$= (etree_type *)NULL; typebits = 0; } + | '(' type ')' ':' { $$= (etree_type *)NULL; } ; memspec_opt: diff --git a/ld/ldlang.c b/ld/ldlang.c index 588660ba58e..151fe58fa8e 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -95,6 +95,10 @@ extern ld_config_type config; extern boolean had_script; extern boolean write_map; + +etree_type *base; /* Relocation base - or null */ + + #ifdef __STDC__ #define cat(a,b) a##b #else @@ -1091,6 +1095,12 @@ DEFUN (print_output_section_statement, (output_section_statement), fprintf (config.map_file, "No attached output section"); } 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 || 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); 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; /* Make sure this isn't silly */ - if (os->region->current > - os->region->origin + - os->region->length) - { - einfo ("%X%P: Region %s is full (%B section %s)\n", - os->region->name, - os->bfd_section->owner, - os->bfd_section->name); - /* Reset the region pointer */ - os->region->current = 0; + if (( os->region->current + > os->region->origin + os->region->length) + || ( os->region->origin > os->region->current )) + { + einfo ("%X%P: Region %s is full (%B section %s)\n", + os->region->name, + os->bfd_section->owner, + os->bfd_section->name); + /* Reset the region pointer */ + os->region->current = 0; - } + } } } @@ -2319,13 +2334,14 @@ DEFUN (lang_enter_output_section_statement, address_exp, flags, block_value, - align, subalign), + align, subalign, base), char *output_section_statement_name AND etree_type * address_exp AND int flags AND bfd_vma block_value AND etree_type *align AND - etree_type *subalign) + etree_type *subalign AND + etree_type *base) { lang_output_section_statement_type *os; @@ -2361,8 +2377,11 @@ DEFUN (lang_enter_output_section_statement, os->section_alignment = topower( exp_get_value_int(align, -1, "section alignment", 0)); + + os->load_base = base; } + void DEFUN_VOID (lang_final) { @@ -2765,3 +2784,4 @@ DEFUN (lang_add_output_format, (format), { output_target = format; } + diff --git a/ld/ldlex.l b/ld/ldlex.l index d43cf498d11..98ea160d2e2 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -184,6 +184,12 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] "-retain-symbols-file" { return OPTION_RETAIN_SYMBOLS_FILE; } +"-EB" { + return OPTION_EB; + } +"-EL" { + return OPTION_EL; + } "$"([0-9A-Fa-f])+ { yylval.integer = strtoul(yytext+1, 0,16); return INT; @@ -208,7 +214,7 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] yylval.integer = strtoul(yytext+1, 0, base); return INT; } -"$"?"0x"?([0-9A-Fa-f])+(M|K|m|k)? { +"$"?"0x"?([0-9A-Fa-f])+(M|K|m|k)? { yylval.integer = strtoul(yytext,0,hex_mode); if (yytext[yyleng-1]=='M' || yytext[yyleng-1] == 'm') { @@ -305,6 +311,7 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] "l" { RTOKEN( LENGTH);} "len" { RTOKEN( LENGTH);} "INCLUDE" { RTOKEN(INCLUDE);} +"AT" { RTOKEN(AT);} "\n" { ++ lineno; RTOKEN(NEWLINE); } "*".* { /* Mri comment line */ } "END" { RTOKEN(ENDWORD); } @@ -383,6 +390,7 @@ NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~] } else { + BEGIN(SCRIPT); ldfile_input_filename = file_name_stack[include_stack_ptr-1]; }