aboutsummaryrefslogtreecommitdiff
path: root/ld/ldexp.c
diff options
context:
space:
mode:
Diffstat (limited to 'ld/ldexp.c')
-rw-r--r--ld/ldexp.c140
1 files changed, 76 insertions, 64 deletions
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 02fb314..a85c79e 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -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;
}