diff options
Diffstat (limited to 'gas/symbols.c')
-rw-r--r-- | gas/symbols.c | 43 |
1 files changed, 19 insertions, 24 deletions
diff --git a/gas/symbols.c b/gas/symbols.c index d8a9c92..9786795 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1221,7 +1221,7 @@ valueT resolve_symbol_value (symbolS *symp) { int resolved; - valueT final_val = 0; + valueT final_val; segT final_seg; if (LOCAL_SYMBOL_CHECK (symp)) @@ -1245,10 +1245,18 @@ resolve_symbol_value (symbolS *symp) if (symp->sy_flags.sy_resolved) { + final_val = 0; + while (symp->sy_value.X_op == O_symbol + && symp->sy_value.X_add_symbol->sy_flags.sy_resolved) + { + final_val += symp->sy_value.X_add_number; + symp = symp->sy_value.X_add_symbol; + } if (symp->sy_value.X_op == O_constant) - return (valueT) symp->sy_value.X_add_number; + final_val += symp->sy_value.X_add_number; else - return 0; + final_val = 0; + return final_val; } resolved = 0; @@ -1305,6 +1313,7 @@ resolve_symbol_value (symbolS *symp) resolved = 1; } + final_val = 0; final_seg = undefined_section; goto exit_dont_set_value; } @@ -1392,11 +1401,16 @@ resolve_symbol_value (symbolS *symp) relocation to detect this case, and convert the relocation to be against the symbol to which this symbol is equated. */ - if (! S_IS_DEFINED (add_symbol) + if (seg_left == undefined_section + || bfd_is_com_section (seg_left) #if defined (OBJ_COFF) && defined (TE_PE) || S_IS_WEAK (add_symbol) #endif - || S_IS_COMMON (add_symbol)) + || (finalize_syms + && ((final_seg == expr_section + && seg_left != expr_section + && seg_left != absolute_section) + || symbol_shadow_p (symp)))) { if (finalize_syms) { @@ -1407,25 +1421,6 @@ resolve_symbol_value (symbolS *symp) symp->sy_value.X_op_symbol = add_symbol; } final_seg = seg_left; - final_val = 0; - resolved = symbol_resolved_p (add_symbol); - symp->sy_flags.sy_resolving = 0; - goto exit_dont_set_value; - } - else if (finalize_syms - && ((final_seg == expr_section && seg_left != expr_section) - || symbol_shadow_p (symp))) - { - /* If the symbol is an expression symbol, do similarly - as for undefined and common syms above. Handles - "sym +/- expr" where "expr" cannot be evaluated - immediately, and we want relocations to be against - "sym", eg. because it is weak. */ - symp->sy_value.X_op = O_symbol; - symp->sy_value.X_add_symbol = add_symbol; - symp->sy_value.X_add_number = final_val; - symp->sy_value.X_op_symbol = add_symbol; - final_seg = seg_left; final_val += symp->sy_frag->fr_address + left; resolved = symbol_resolved_p (add_symbol); symp->sy_flags.sy_resolving = 0; |