diff options
-rw-r--r-- | gas/ChangeLog | 13 | ||||
-rw-r--r-- | gas/symbols.c | 43 | ||||
-rw-r--r-- | gas/testsuite/gas/mmix/basep-7.d | 8 |
3 files changed, 35 insertions, 29 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 090df4b..eeabe0c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2019-04-24 Alan Modra <amodra@gmail.com> + + PR 24444 + * symbols.c (resolve_symbol_value): When handling symbols + marked as sy_flags.resolved, return correct value for the + case of expression symbols left as an O_symbol expression. + Merge O_symbol code handling undefined and common symbols with + code handling special cases of expression symbols. Use + seg_left to test for undefined and common symbols. Don't + leave an O_symbol expression when X_add_symbol resolves to + the absolute_section. Init final_val later. + * testsuite/gas/mmix/basep-7.d: Adjust expected output. + 2019-04-24 John Darrington <john@darrington.wattle.id.au> * testsuite/gas/s12z/bit-manip-invalid.s: Extend test for BSET 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; diff --git a/gas/testsuite/gas/mmix/basep-7.d b/gas/testsuite/gas/mmix/basep-7.d index 0cd0a13..8aa7d00 100644 --- a/gas/testsuite/gas/mmix/basep-7.d +++ b/gas/testsuite/gas/mmix/basep-7.d @@ -3,8 +3,6 @@ #objdump: -drt # The -linker-allocated-gregs option validates omissions of GREG. -# Note the inconsequence in relocs regarding forward and backward -# references (not specific to this functionality); they may change. .*: file format elf64-mmix @@ -27,8 +25,8 @@ Disassembly of section \.text: 8: 23300000 addu \$48,\$0,0 a: R_MMIX_BASE_PLUS_OFFSET \*ABS\*\+0x86 c: 8d2b0000 ldo \$43,\$0,0 - e: R_MMIX_BASE_PLUS_OFFSET c\+0x2 + e: R_MMIX_BASE_PLUS_OFFSET \*ABS\*\+0x4a 10: 232f0000 addu \$47,\$0,0 - 12: R_MMIX_BASE_PLUS_OFFSET d\+0xd4 + 12: R_MMIX_BASE_PLUS_OFFSET \*ABS\*\+0xd7 14: 23300000 addu \$48,\$0,0 - 16: R_MMIX_BASE_PLUS_OFFSET c\+0x15 + 16: R_MMIX_BASE_PLUS_OFFSET \*ABS\*\+0x5d |