]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas: xtensa: fix comparison of trampoline chain symbols
authorMax Filippov <jcmvbkbc@gmail.com>
Thu, 7 Dec 2017 06:52:16 +0000 (22:52 -0800)
committerMax Filippov <jcmvbkbc@gmail.com>
Fri, 8 Dec 2017 16:49:21 +0000 (08:49 -0800)
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/ChangeLog
gas/config/tc-xtensa.c

index 7a8d3df1213123948d69256f34b9c6a2f8eddac1..5cae4d1c0f1dc27d80121e01e2628fa1b78e5096 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2017-12-04  Alan Modra  <amodra@gmail.com>
 
        PR 22544
index ce7eb499b844f7640a22fbcaead58cb0fcf91438..a378d45cef6d53b4fde2c225b03fb967319d3039 100644 (file)
@@ -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 *