[PATCH] gas: xtensa: fix comparison of trampoline chain symbols

Max Filippov jcmvbkbc@gmail.com
Thu Dec 7 22:32:00 GMT 2017


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.
---
 gas/config/tc-xtensa.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index ce7eb499b844..a378d45cef6d 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 *
-- 
2.1.4



More information about the Binutils mailing list