summaryrefslogtreecommitdiff
path: root/gas/symbols.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2006-11-15 15:59:26 +0000
committerJan Beulich <jbeulich@novell.com>2006-11-15 15:59:26 +0000
commit82d31429c19bbdd16d7ad6987ed14d5d540238b2 (patch)
treec8534a52ae353fc5f9cf5bab953a553171c01a4c /gas/symbols.c
parent5e283623a4db4e05e91f028e35103341eec8a6ac (diff)
downloadbinutils-redhat-82d31429c19bbdd16d7ad6987ed14d5d540238b2.tar.gz
gas/
2006-11-15 Jan Beulich <jbeulich@novell.com> PR/3469 * symbols.c (symbol_clone): Mark symbol ending up not on symbol chain by linking it to itself. (resolve_symbol_value): Also check symbol_shadow_p(). (symbol_shadow_p): New. * symbols.h (symbol_shadow_p): Declare. gas/testsuite/ 2006-11-15 Jan Beulich <jbeulich@novell.com> * gas/elf/equ-reloc.[sd]: New. * gas/elf/elf.exp: Run new test.
Diffstat (limited to 'gas/symbols.c')
-rw-r--r--gas/symbols.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/gas/symbols.c b/gas/symbols.c
index dccc46af92..6a90bba219 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -598,11 +598,13 @@ symbol_clone (symbolS *orgsymP, int replace)
symbol_lastP = newsymP;
else if (orgsymP->sy_next)
orgsymP->sy_next->sy_previous = newsymP;
- orgsymP->sy_next = NULL;
+ orgsymP->sy_previous = orgsymP->sy_next = orgsymP;
debug_verify_symchain (symbol_rootP, symbol_lastP);
symbol_table_insert (newsymP);
}
+ else
+ newsymP->sy_previous = newsymP->sy_next = newsymP;
return newsymP;
}
@@ -1078,8 +1080,9 @@ resolve_symbol_value (symbolS *symp)
symp->sy_resolving = 0;
goto exit_dont_set_value;
}
- else if (finalize_syms && final_seg == expr_section
- && seg_left != expr_section)
+ 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
@@ -2492,6 +2495,17 @@ symbol_constant_p (symbolS *s)
return s->sy_value.X_op == O_constant;
}
+/* Return whether a symbol was cloned and thus removed from the global
+ symbol list. */
+
+int
+symbol_shadow_p (symbolS *s)
+{
+ if (LOCAL_SYMBOL_CHECK (s))
+ return 0;
+ return s->sy_next == s;
+}
+
/* Return the BFD symbol for a symbol. */
asymbol *