resolve_symbol_value vs. .loc view resolution

In most cases we don't want expression symbols, such as that created
for an expression like "symbol + (1f - .)", resolved down to a
constant.  Instead we'd like to leave the expression as "symbol +
constant" once the "1f - ." part has been resolved, and let the
backend decide whether "symbol" can be reduced further.

However, that doesn't work when trying to resolve .loc view symbols
early.  We get expression symbols left as an O_symbol expression
pointing at an absolute symbol, and marked as sy_flags.sy_resolved.
That wouldn't really be a problem, but when one of those expression
symbols is used in further .loc view expressions, its value is taken
as zero.

This patch fixes the symbol value mistake, and stops creation of
O_symbol expression symbols pointing to absolute symbols.  Either of
these fixes would cure the .loc view usage.

	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.
This commit is contained in:
Alan Modra 2019-04-24 11:26:51 +09:30
parent a679f24ecc
commit 1903f1385b
3 changed files with 35 additions and 29 deletions

View File

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

View File

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

View File

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