aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2017-12-06 22:52:16 -0800
committerMax Filippov <jcmvbkbc@gmail.com>2017-12-08 08:49:21 -0800
commit10af2a65c8891435d0d63411a3e694cc74c9447c (patch)
tree4e024390a684005c542bd794f8ce3a83a861afc3 /gas/config
parent1cd9a73b4280cb133b305ee31a0e87f114bd1be8 (diff)
downloadgdb-10af2a65c8891435d0d63411a3e694cc74c9447c.zip
gdb-10af2a65c8891435d0d63411a3e694cc74c9447c.tar.gz
gdb-10af2a65c8891435d0d63411a3e694cc74c9447c.tar.bz2
gas: xtensa: fix comparison of trampoline chain symbols
Don't use address where symbol gets resolved, as during section relaxation symbols will slide, instead canonicalize symbols and check that they are are the same. This fixes a bug when a relaxed jump goes into the wrong trampoline. gas/ 2017-12-07 Max Filippov <jcmvbkbc@gmail.com> * config/tc-xtensa.c (xg_order_trampoline_chain): Replace xg_order_trampoline_chain_entry call with check for canonicalized symbol equality and offset equality.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-xtensa.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index ce7eb49..a378d45 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -7646,10 +7646,28 @@ xg_get_best_chain_entry (struct trampoline_chain *tc, addressT source)
static int xg_order_trampoline_chain (const void *a, const void *b)
{
- const struct trampoline_chain *pa = a;
- const struct trampoline_chain *pb = b;
-
- return xg_order_trampoline_chain_entry (&pa->target, &pb->target);
+ const struct trampoline_chain *_pa = a;
+ const struct trampoline_chain *_pb = b;
+ const struct trampoline_chain_entry *pa = &_pa->target;
+ const struct trampoline_chain_entry *pb = &_pb->target;
+ symbolS *s1 = pa->sym;
+ symbolS *s2 = pb->sym;
+
+ 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);
+
+ if (s1 == s2)
+ if (pa->offset == pb->offset)
+ return 0;
+ else
+ return pa->offset < pb->offset ? -1 : 1;
+ else
+ return s1 < s2 ? -1 : 1;
}
static struct trampoline_chain *