|
|
|
@ -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; |
|
|
|
} |
|
|
|
|