diff -rup binutils.orig/gas/symbols.c binutils-2.38/gas/symbols.c --- binutils.orig/gas/symbols.c 2022-03-09 11:43:34.706610216 +0000 +++ binutils-2.38/gas/symbols.c 2022-03-09 11:45:57.540686508 +0000 @@ -61,8 +61,10 @@ struct symbol_flags /* Whether the symbol can be re-defined. */ unsigned int volatil : 1; - /* Whether the symbol is a forward reference. */ + /* Whether the symbol is a forward reference, and whether such has + been determined. */ unsigned int forward_ref : 1; + unsigned int forward_resolved : 1; /* This is set if the symbol is defined in an MRI common section. We handle such sections as single common symbols, so symbols @@ -202,7 +204,7 @@ static void * symbol_entry_find (htab_t table, const char *name) { hashval_t hash = htab_hash_string (name); - symbol_entry_t needle = { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + symbol_entry_t needle = { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, hash, name, 0, 0, 0 } }; return htab_find_with_hash (table, &needle, hash); } @@ -784,7 +786,9 @@ symbol_clone (symbolS *orgsymP, int repl symbolS * symbol_clone_if_forward_ref (symbolS *symbolP, int is_forward) { - if (symbolP && !symbolP->flags.local_symbol) + if (symbolP + && !symbolP->flags.local_symbol + && !symbolP->flags.forward_resolved) { symbolS *orig_add_symbol = symbolP->x->value.X_add_symbol; symbolS *orig_op_symbol = symbolP->x->value.X_op_symbol; @@ -837,6 +841,7 @@ symbol_clone_if_forward_ref (symbolS *sy symbolP->x->value.X_add_symbol = add_symbol; symbolP->x->value.X_op_symbol = op_symbol; + symbolP->flags.forward_resolved = 1; } return symbolP; diff -rup binutils.orig/gas/testsuite/gas/elf/dwarf2-18.d binutils-2.38/gas/testsuite/gas/elf/dwarf2-18.d --- binutils.orig/gas/testsuite/gas/elf/dwarf2-18.d 2022-03-09 11:43:34.487611632 +0000 +++ binutils-2.38/gas/testsuite/gas/elf/dwarf2-18.d 2022-03-09 11:48:03.298873228 +0000 @@ -2,9 +2,8 @@ #readelf: -x.rodata -wL #name: DWARF2 18 # The am33 cr16 crx ft32 mn10 msp430 nds32 and rl78 targets do not evaluate the subtraction of symbols at assembly time. -# The mep targets turns some view computations into complex relocations. # The riscv targets do not support the subtraction of symbols. -#xfail: am3*-* cr16-* crx-* ft32*-* mep-* mn10*-* msp430-* nds32*-* riscv*-* rl78-* +#xfail: am3*-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* riscv*-* rl78-* Hex dump of section '\.rodata': 0x00000000 0100 *.* --- binutils.orig/gas/dwarf2dbg.c 2022-03-10 09:13:18.516639363 +0000 +++ binutils-2.38/gas/dwarf2dbg.c 2022-03-10 12:45:25.191933733 +0000 @@ -402,18 +402,27 @@ set_or_check_view (struct line_entry *e, if (viewx.X_op != O_constant || viewx.X_add_number) { expressionS incv; + expressionS *p_view; if (!p->loc.u.view) - { - p->loc.u.view = symbol_temp_make (); - gas_assert (!S_IS_DEFINED (p->loc.u.view)); - } + p->loc.u.view = symbol_temp_make (); memset (&incv, 0, sizeof (incv)); incv.X_unsigned = 1; incv.X_op = O_symbol; incv.X_add_symbol = p->loc.u.view; incv.X_add_number = 1; + p_view = symbol_get_value_expression (p->loc.u.view); + if (p_view->X_op == O_constant || p_view->X_op == O_symbol) + { + /* If we can, constant fold increments so that a chain of + expressions v + 1 + 1 ... + 1 is not created. + resolve_expression isn't ideal for this purpose. The + base v might not be resolvable until later. */ + incv.X_op = p_view->X_op; + incv.X_add_symbol = p_view->X_add_symbol; + incv.X_add_number = p_view->X_add_number + 1; + } if (viewx.X_op == O_constant) {