From: Max Filippov Date: Thu, 7 Dec 2017 06:52:16 +0000 (-0800) Subject: gas: xtensa: fix comparison of trampoline chain symbols X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=10af2a65c8891435d0d63411a3e694cc74c9447c;p=binutils-gdb.git 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 * config/tc-xtensa.c (xg_order_trampoline_chain): Replace xg_order_trampoline_chain_entry call with check for canonicalized symbol equality and offset equality. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 7a8d3df1213..5cae4d1c0f1 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2017-12-07 Max Filippov + + * config/tc-xtensa.c (xg_order_trampoline_chain): Replace + xg_order_trampoline_chain_entry call with check for + canonicalized symbol equality and offset equality. + 2017-12-04 Alan Modra PR 22544 diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index ce7eb499b84..a378d45cef6 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 *