Fixed some bugs.
This commit is contained in:
parent
301dfc71d4
commit
ac00487023
146
ld/ldexp.c
146
ld/ldexp.c
@ -281,82 +281,94 @@ bfd_vma dot;
|
|||||||
{
|
{
|
||||||
etree_value_type result;
|
etree_value_type result;
|
||||||
switch (tree->type.node_code)
|
switch (tree->type.node_code)
|
||||||
{
|
{
|
||||||
case DEFINED:
|
case DEFINED:
|
||||||
result.value =
|
result.value =
|
||||||
ldsym_get_soft(tree->name.name) != (ldsym_type *)NULL;
|
ldsym_get_soft(tree->name.name) != (ldsym_type *)NULL;
|
||||||
result.section = 0;
|
result.section = 0;
|
||||||
result.valid = true;
|
result.valid = true;
|
||||||
break;
|
break;
|
||||||
case NAME:
|
case NAME:
|
||||||
result.valid = false;
|
result.valid = false;
|
||||||
if (tree->name.name[0] == '.' && tree->name.name[1] == 0) {
|
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 {
|
||||||
|
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);
|
||||||
|
/* 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",
|
||||||
|
tree->name.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ADDR:
|
||||||
|
|
||||||
if (allocation_done != lang_first_phase_enum) {
|
if (allocation_done != lang_first_phase_enum) {
|
||||||
result = new_rel_from_section(dot, current_section);
|
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 {
|
else {
|
||||||
result = invalid();
|
result = invalid();
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else {
|
case SIZEOF:
|
||||||
if (allocation_done == lang_final_phase_enum) {
|
if(allocation_done != lang_first_phase_enum) {
|
||||||
ldsym_type *sy = ldsym_get_soft(tree->name.name);
|
lang_output_section_statement_type *os =
|
||||||
|
lang_output_section_find(tree->name.name);
|
||||||
if (sy) {
|
check(os,tree->name.name,"SIZEOF");
|
||||||
asymbol **sdefp = sy->sdefs_chain;
|
result = new_abs((bfd_vma)(os->bfd_section->size));
|
||||||
|
|
||||||
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 (result.valid == false) {
|
|
||||||
info("%F%S: undefined symbol `%s' referenced in expression.\n",
|
|
||||||
tree->name.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
result = invalid();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
break;
|
default:
|
||||||
|
FAIL();
|
||||||
case ADDR:
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,11 @@ command_line:
|
|||||||
;
|
;
|
||||||
|
|
||||||
command_line_option:
|
command_line_option:
|
||||||
SCRIPT ifile_list ENDSCRIPT
|
SCRIPT
|
||||||
|
{ ldgram_in_script = true; }
|
||||||
|
ifile_list
|
||||||
|
{ ldgram_in_script = false; }
|
||||||
|
ENDSCRIPT
|
||||||
| OPTION_v
|
| OPTION_v
|
||||||
{
|
{
|
||||||
ldversion();
|
ldversion();
|
||||||
@ -318,7 +322,7 @@ ifile_p1:
|
|||||||
| high_level_library
|
| high_level_library
|
||||||
| low_level_library
|
| low_level_library
|
||||||
| floating_point_support
|
| floating_point_support
|
||||||
| assignment end
|
| statement_anywhere
|
||||||
| TARGET_K '(' NAME ')'
|
| TARGET_K '(' NAME ')'
|
||||||
{ lang_add_target($3); }
|
{ lang_add_target($3); }
|
||||||
| SEARCH_DIR '(' filename ')'
|
| SEARCH_DIR '(' filename ')'
|
||||||
|
40
ld/ldlang.c
40
ld/ldlang.c
@ -1247,23 +1247,28 @@ DEFUN(size_input_section, (this_ptr, output_section_statement, fill, dot),
|
|||||||
asection *i = is->section;
|
asection *i = is->section;
|
||||||
|
|
||||||
if (is->ifile->just_syms_flag == false) {
|
if (is->ifile->just_syms_flag == false) {
|
||||||
dot = insert_pad(this_ptr, fill, i->alignment_power,
|
dot = insert_pad(this_ptr, fill, i->alignment_power,
|
||||||
output_section_statement->bfd_section, dot);
|
output_section_statement->bfd_section, dot);
|
||||||
|
|
||||||
/* remember the largest size so we can malloc the largest area */
|
/* remember the largest size so we can malloc the largest area */
|
||||||
/* needed for the output stage */
|
/* needed for the output stage */
|
||||||
if (i->size > largest_section) {
|
if (i->size > largest_section) {
|
||||||
largest_section = i->size;
|
largest_section = i->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember where in the output section this input section goes */
|
||||||
|
|
||||||
|
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
|
||||||
/* Remember where in the output section this input section goes */
|
{
|
||||||
i->output_offset = dot - output_section_statement->bfd_section->vma;
|
i->output_offset = i->vma - 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dot ;
|
return dot ;
|
||||||
}
|
}
|
||||||
@ -1718,8 +1723,10 @@ DEFUN_VOID(lang_common)
|
|||||||
com->section->alignment_power = power_of_two;
|
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)
|
if (write_map)
|
||||||
@ -1731,7 +1738,6 @@ DEFUN_VOID(lang_common)
|
|||||||
}
|
}
|
||||||
com->value = com->section->size;
|
com->value = com->section->size;
|
||||||
com->section->size += size;
|
com->section->size += size;
|
||||||
com->the_bfd = output_bfd;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
66
ld/ldlex.l
66
ld/ldlex.l
@ -383,27 +383,6 @@ WHITE [ \t]+
|
|||||||
yylval.name[yyleng-2] = 0; /* Fry final quote */
|
yylval.name[yyleng-2] = 0; /* Fry final quote */
|
||||||
return NAME;
|
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}+ {
|
"\#"{WHITE}*{FILENAMECHAR}+ {
|
||||||
char *p = yytext+1;
|
char *p = yytext+1;
|
||||||
@ -439,17 +418,34 @@ WHITE [ \t]+
|
|||||||
int ch;
|
int ch;
|
||||||
keyword_type *k;
|
keyword_type *k;
|
||||||
|
|
||||||
if (hex_mode) {
|
if ((hex_mode && isxdigit(yytext[0]))
|
||||||
ch = yytext[0];
|
||
|
||||||
/* Then always read a number */
|
(isdigit(yytext[0]) && (ldgram_in_expression == true || ldgram_in_script == true))) {
|
||||||
while (isxdigit(ch)) {
|
char *start = yytext;
|
||||||
yytext[yyleng++] = ch;
|
unsigned int base = 10;
|
||||||
ch = input();
|
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;
|
yytext[yyleng] = 0;
|
||||||
unput(ch);
|
unput(ch);
|
||||||
|
yylval.integer = number(start, base);
|
||||||
yylval.integer = number(yytext,16);
|
|
||||||
return INT;
|
return INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,8 +458,8 @@ WHITE [ \t]+
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Otherwise we only notice special things if were in an
|
/* Otherwise we only notice special things if were in an
|
||||||
expression */
|
expression */
|
||||||
|
|
||||||
if (ldgram_in_expression) {
|
if (ldgram_in_expression) {
|
||||||
if (yytext[0] != '/' || ldgram_in_defsym == false) {
|
if (yytext[0] != '/' || ldgram_in_defsym == false) {
|
||||||
@ -482,10 +478,10 @@ WHITE [ \t]+
|
|||||||
if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ) {
|
if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ) {
|
||||||
yytext[yyleng++] = ch;
|
yytext[yyleng++] = ch;
|
||||||
}
|
}
|
||||||
else if (ch == '=' && ldgram_in_script) {
|
else if (ch == '=' && ldgram_in_script) {
|
||||||
/* An = within a script is always taken to be an operator */
|
/* An = within a script is always taken to be an operator */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (ch == '+' || ch == '-' || ch == '/' || ch == '=') {
|
else if (ch == '+' || ch == '-' || ch == '/' || ch == '=') {
|
||||||
if (ldgram_in_expression) break;
|
if (ldgram_in_expression) break;
|
||||||
yytext[yyleng++] = ch;
|
yytext[yyleng++] = ch;
|
||||||
|
Loading…
Reference in New Issue
Block a user