aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog14
-rw-r--r--gas/dwarf2dbg.c19
-rw-r--r--gas/read.c2
-rw-r--r--gas/symbols.c33
4 files changed, 48 insertions, 20 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 71dd3b8..240e078 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,17 @@
+2018-10-22 Alan Modra <amodra@gmail.com>
+
+ PR 23040
+ * symbols.c (get_real_sym): New function.
+ (symbol_same_p): Use get_real_sym.
+ (symbol_clone_if_forward_ref): Save real original add_symbol and
+ op_symbol for comparison against that returned from lookup or
+ recursive calls.
+ * dwarf2dbg.c (set_or_check_view): Use expr_section for
+ expression symbols, not absolute_section.
+ (dwarf2_directive_loc): Check symbol_equated_p and tidy cloning
+ of view symbols.
+ * read.c (s_leb128): Don't use deferred_expression.
+
2018-10-20 Alan Modra <amodra@gmail.com>
PR 23800
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index e42c561..57c837b 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -426,7 +426,7 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
if (!S_IS_DEFINED (e->loc.view))
{
symbol_set_value_expression (e->loc.view, &viewx);
- S_SET_SEGMENT (e->loc.view, absolute_section);
+ S_SET_SEGMENT (e->loc.view, expr_section);
symbol_set_frag (e->loc.view, &zero_address_frag);
}
@@ -960,16 +960,19 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
if (!name)
return;
sym = symbol_find_or_make (name);
- if (S_IS_DEFINED (sym))
+ if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
{
- if (!S_CAN_BE_REDEFINED (sym))
- as_bad (_("symbol `%s' is already defined"), name);
- else
+ if (S_IS_VOLATILE (sym))
sym = symbol_clone (sym, 1);
- S_SET_SEGMENT (sym, undefined_section);
- S_SET_VALUE (sym, 0);
- symbol_set_frag (sym, &zero_address_frag);
+ else if (!S_CAN_BE_REDEFINED (sym))
+ {
+ as_bad (_("symbol `%s' is already defined"), name);
+ return;
+ }
}
+ S_SET_SEGMENT (sym, undefined_section);
+ S_SET_VALUE (sym, 0);
+ symbol_set_frag (sym, &zero_address_frag);
}
current.view = sym;
}
diff --git a/gas/read.c b/gas/read.c
index f011149..4a8b15a 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -5252,7 +5252,7 @@ s_leb128 (int sign)
do
{
- deferred_expression (&exp);
+ expression (&exp);
emit_leb128_expr (&exp, sign);
}
while (*input_line_pointer++ == ',');
diff --git a/gas/symbols.c b/gas/symbols.c
index 4088837..2056981 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -619,9 +619,22 @@ symbol_clone (symbolS *orgsymP, int replace)
return newsymP;
}
+/* If S is a local symbol that has been converted, return the
+ converted symbol. Otherwise return S. */
+
+static inline symbolS *
+get_real_sym (symbolS *s)
+{
+ if (s != NULL
+ && s->sy_flags.sy_local_symbol
+ && local_symbol_converted_p ((struct local_symbol *) s))
+ s = local_symbol_get_real_symbol ((struct local_symbol *) s);
+ return s;
+}
+
/* Referenced symbols, if they are forward references, need to be cloned
(without replacing the original) so that the value of the referenced
- symbols at the point of use . */
+ symbols at the point of use is saved by the clone. */
#undef symbol_clone_if_forward_ref
symbolS *
@@ -629,8 +642,10 @@ symbol_clone_if_forward_ref (symbolS *symbolP, int is_forward)
{
if (symbolP && !LOCAL_SYMBOL_CHECK (symbolP))
{
- symbolS *add_symbol = symbolP->sy_value.X_add_symbol;
- symbolS *op_symbol = symbolP->sy_value.X_op_symbol;
+ symbolS *orig_add_symbol = get_real_sym (symbolP->sy_value.X_add_symbol);
+ symbolS *orig_op_symbol = get_real_sym (symbolP->sy_value.X_op_symbol);
+ symbolS *add_symbol = orig_add_symbol;
+ symbolS *op_symbol = orig_op_symbol;
if (symbolP->sy_flags.sy_forward_ref)
is_forward = 1;
@@ -659,8 +674,8 @@ symbol_clone_if_forward_ref (symbolS *symbolP, int is_forward)
}
if (symbolP->sy_flags.sy_forward_ref
- || add_symbol != symbolP->sy_value.X_add_symbol
- || op_symbol != symbolP->sy_value.X_op_symbol)
+ || add_symbol != orig_add_symbol
+ || op_symbol != orig_op_symbol)
{
if (symbolP != &dot_symbol)
{
@@ -2462,12 +2477,8 @@ symbol_set_value_expression (symbolS *s, const expressionS *exp)
int
symbol_same_p (symbolS *s1, symbolS *s2)
{
- if (s1->sy_flags.sy_local_symbol
- && local_symbol_converted_p ((struct local_symbol *) s1))
- s1 = local_symbol_get_real_symbol ((struct local_symbol *) s1);
- if (s2->sy_flags.sy_local_symbol
- && local_symbol_converted_p ((struct local_symbol *) s2))
- s2 = local_symbol_get_real_symbol ((struct local_symbol *) s2);
+ s1 = get_real_sym (s1);
+ s2 = get_real_sym (s2);
return s1 == s2;
}