diff options
-rw-r--r-- | ld/ldexp.c | 140 | ||||
-rw-r--r-- | ld/ldgram.y | 8 | ||||
-rw-r--r-- | ld/ldlang.c | 38 | ||||
-rw-r--r-- | ld/ldlex.l | 66 |
4 files changed, 135 insertions, 117 deletions
@@ -281,82 +281,94 @@ bfd_vma dot; { etree_value_type result; switch (tree->type.node_code) - { - case DEFINED: - result.value = - ldsym_get_soft(tree->name.name) != (ldsym_type *)NULL; - result.section = 0; - result.valid = true; - break; - case NAME: - result.valid = false; - if (tree->name.name[0] == '.' && tree->name.name[1] == 0) { - - if (allocation_done != lang_first_phase_enum) { - result = new_rel_from_section(dot, current_section); + { + case DEFINED: + result.value = + ldsym_get_soft(tree->name.name) != (ldsym_type *)NULL; + result.section = 0; + result.valid = true; + break; + case NAME: + result.valid = false; + if (tree->name.name[0] == '.' && tree->name.name[1] == 0) { + + if (allocation_done != lang_first_phase_enum) { + result = new_rel_from_section(dot, current_section); + } + else { + result = invalid(); + } } else { - result = invalid(); - } - } - else { - if (allocation_done == lang_final_phase_enum) { - ldsym_type *sy = ldsym_get_soft(tree->name.name); + if (allocation_done == lang_final_phase_enum) { + ldsym_type *sy = ldsym_get_soft(tree->name.name); - if (sy) { - asymbol **sdefp = sy->sdefs_chain; - - if (sdefp) { - asymbol *sdef = *sdefp; - if (sdef->section == (asection *)NULL) { - /* This is an absolute symbol */ - result = new_abs(sdef->value); - } - else { - lang_output_section_statement_type *os = - lang_output_section_statement_lookup( sdef->section->output_section->name); - result = new_rel(sdef->value, os); + if (sy) { + asymbol **sdefp = sy->sdefs_chain; + + if (sdefp) { + asymbol *sdef = *sdefp; + if (sdef->section == (asection *)NULL) { + /* This is an absolute symbol */ + result = new_abs(sdef->value); + } + else { + lang_output_section_statement_type *os = + lang_output_section_statement_lookup( + sdef->section->output_section->name); + /* If the symbol is from a file which we are not + relocating (-R) then return an absolute for its + value */ + if (sdef->the_bfd->usrdata && + ((lang_input_statement_type*)(sdef->the_bfd->usrdata))->just_syms_flag == true) + { + result = new_abs(sdef->value + sdef->section ? + sdef->section->vma : 0); + } + else { + result = new_rel(sdef->value, os); + } + } } } - } - if (result.valid == false) { - info("%F%S: undefined symbol `%s' referenced in expression.\n", + if (result.valid == false) { + info("%F%S: undefined symbol `%s' referenced in expression.\n", tree->name.name); - } + } + } } - } - break; + break; - case ADDR: + case ADDR: - if (allocation_done != lang_first_phase_enum) { - lang_output_section_statement_type *os = - lang_output_section_find(tree->name.name); - check(os,tree->name.name,"ADDR"); - result = new_rel((bfd_vma)0, os); - } - else { - result = invalid(); - } - break; - case SIZEOF: - if(allocation_done != lang_first_phase_enum) { - lang_output_section_statement_type *os = - lang_output_section_find(tree->name.name); - check(os,tree->name.name,"SIZEOF"); - result = new_abs((bfd_vma)(os->bfd_section->size)); - } - else { - result = invalid(); - } - break; + if (allocation_done != lang_first_phase_enum) { + lang_output_section_statement_type *os = + lang_output_section_find(tree->name.name); + check(os,tree->name.name,"ADDR"); + result = new_rel((bfd_vma)0, os); + } + else { + result = invalid(); + } + break; + case SIZEOF: + if(allocation_done != lang_first_phase_enum) { + lang_output_section_statement_type *os = + lang_output_section_find(tree->name.name); + check(os,tree->name.name,"SIZEOF"); + result = new_abs((bfd_vma)(os->bfd_section->size)); + } + else { + result = invalid(); + } + break; - default: - FAIL(); - break; - } + default: + FAIL(); + break; + } return result; } diff --git a/ld/ldgram.y b/ld/ldgram.y index 2e0e501..304b0b2 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -151,7 +151,11 @@ command_line: ; command_line_option: - SCRIPT ifile_list ENDSCRIPT + SCRIPT + { ldgram_in_script = true; } + ifile_list + { ldgram_in_script = false; } + ENDSCRIPT | OPTION_v { ldversion(); @@ -318,7 +322,7 @@ ifile_p1: | high_level_library | low_level_library | floating_point_support - | assignment end + | statement_anywhere | TARGET_K '(' NAME ')' { lang_add_target($3); } | SEARCH_DIR '(' filename ')' diff --git a/ld/ldlang.c b/ld/ldlang.c index e63f899..afbc385 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1247,23 +1247,28 @@ DEFUN(size_input_section, (this_ptr, output_section_statement, fill, dot), asection *i = is->section; if (is->ifile->just_syms_flag == false) { - dot = insert_pad(this_ptr, fill, i->alignment_power, - output_section_statement->bfd_section, dot); + dot = insert_pad(this_ptr, fill, i->alignment_power, + output_section_statement->bfd_section, dot); - /* remember the largest size so we can malloc the largest area */ - /* needed for the output stage */ - if (i->size > largest_section) { - largest_section = i->size; - } + /* remember the largest size so we can malloc the largest area */ + /* needed for the output stage */ + if (i->size > largest_section) { + largest_section = i->size; + } - /* Remember where in the output section this input section goes */ - i->output_offset = dot - output_section_statement->bfd_section->vma; + /* Remember where in the output section this input section goes */ - /* Mark how big the output section must be to contain this now */ - dot += i->size; - output_section_statement->bfd_section->size = - dot - output_section_statement->bfd_section->vma; -} + i->output_offset = dot - output_section_statement->bfd_section->vma; + + /* Mark how big the output section must be to contain this now */ + dot += i->size; + output_section_statement->bfd_section->size = + dot - output_section_statement->bfd_section->vma; + } + else + { + i->output_offset = i->vma - output_section_statement->bfd_section->vma; + } return dot ; } @@ -1718,8 +1723,10 @@ DEFUN_VOID(lang_common) com->section->alignment_power = power_of_two; } + /* Symbol stops being common and starts being global, but + we remember that it was common once. */ - com->flags = BSF_EXPORT | BSF_GLOBAL ; + com->flags = BSF_EXPORT | BSF_GLOBAL | BSF_OLD_COMMON; if (write_map) @@ -1731,7 +1738,6 @@ DEFUN_VOID(lang_common) } com->value = com->section->size; com->section->size += size; - com->the_bfd = output_bfd; } @@ -383,27 +383,6 @@ WHITE [ \t]+ yylval.name[yyleng-2] = 0; /* Fry final quote */ return NAME; } -[0][0-7KM]* { - - yylval.integer = number(yytext+1, 8); - return INT; -} - -[0-9]+[KM]? { - if (hex_mode == true || ldgram_in_defsym == true) { - yylval.integer = number(yytext, 16); - } - else { - yylval.integer = number(yytext, 10); - } - return INT; -} - -0[Xx][0-9a-fA-FKM]+ { - - yylval.integer = number(yytext+2,16); - return INT; -} "\#"{WHITE}*{FILENAMECHAR}+ { char *p = yytext+1; @@ -439,17 +418,34 @@ WHITE [ \t]+ int ch; keyword_type *k; - if (hex_mode) { - ch = yytext[0]; - /* Then always read a number */ - while (isxdigit(ch)) { - yytext[yyleng++] = ch; - ch = input(); + if ((hex_mode && isxdigit(yytext[0])) + || + (isdigit(yytext[0]) && (ldgram_in_expression == true || ldgram_in_script == true))) { + char *start = yytext; + unsigned int base = 10; + if (hex_mode == true) base = 16; + if (yytext[0] == '0') { + base = 8; } + ch = input(); + while (isxdigit(ch) + || ch == 'x' + || ch == 'X' + || ch == 'M' + ) + { + if (ch == 'x' || ch == 'X') { + base = 16; + start = yytext + yyleng; + } + else { + yytext[yyleng++] = ch; + } + ch = input(); + } yytext[yyleng] = 0; unput(ch); - - yylval.integer = number(yytext,16); + yylval.integer = number(start, base); return INT; } @@ -462,8 +458,8 @@ WHITE [ \t]+ - /* Otherwise we only notice special things if were in an - expression */ + /* Otherwise we only notice special things if were in an + expression */ if (ldgram_in_expression) { if (yytext[0] != '/' || ldgram_in_defsym == false) { @@ -482,10 +478,10 @@ WHITE [ \t]+ if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ) { yytext[yyleng++] = ch; } -else if (ch == '=' && ldgram_in_script) { -/* An = within a script is always taken to be an operator */ -break; -} + else if (ch == '=' && ldgram_in_script) { + /* An = within a script is always taken to be an operator */ + break; + } else if (ch == '+' || ch == '-' || ch == '/' || ch == '=') { if (ldgram_in_expression) break; yytext[yyleng++] = ch; |