+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
resolve_symbol_value (symbolS *symp)
{
int resolved;
- valueT final_val = 0;
+ valueT final_val;
segT final_seg;
if (LOCAL_SYMBOL_CHECK (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;
resolved = 1;
}
+ final_val = 0;
final_seg = undefined_section;
goto exit_dont_set_value;
}
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)
{
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;
#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
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