From 3690dc5f567906c45f057509305fbaa021b33adb Mon Sep 17 00:00:00 2001
From: Yichao Yu <yyc1992@gmail.com>
Date: Tue, 15 Sep 2020 12:35:46 -0700
Subject: [PATCH] Fix compilation with -fno-common.

Making all other archs consistent with IA64 which should not have this problem.
Also move the FIXME to the correct place.

Also add some minimum comments about this...

Upstream-Status: Backport [https://github.com/libunwind/libunwind/pull/166/commits/29e17d8d2ccbca07c423e3089a6d5ae8a1c9cb6e]
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 src/third_party/unwind/dist/src/aarch64/Ginit.c   | 15 +++++++--------
 src/third_party/unwind/dist/src/arm/Ginit.c       | 15 +++++++--------
 .../src/coredump/_UPT_get_dyn_info_list_addr.c    |  5 +++++
 src/third_party/unwind/dist/src/hppa/Ginit.c      | 15 +++++++--------
 src/third_party/unwind/dist/src/ia64/Ginit.c      |  1 +
 .../unwind/dist/src/mi/Gfind_dynamic_proc_info.c  |  1 +
 src/third_party/unwind/dist/src/mips/Ginit.c      | 15 +++++++--------
 src/third_party/unwind/dist/src/ppc32/Ginit.c     | 11 +++++++----
 src/third_party/unwind/dist/src/ppc64/Ginit.c     | 11 +++++++----
 .../dist/src/ptrace/_UPT_get_dyn_info_list_addr.c |  5 +++++
 src/third_party/unwind/dist/src/s390x/Ginit.c     | 15 +++++++--------
 src/third_party/unwind/dist/src/sh/Ginit.c        | 15 +++++++--------
 src/third_party/unwind/dist/src/tilegx/Ginit.c    | 15 +++++++--------
 src/third_party/unwind/dist/src/x86/Ginit.c       | 15 +++++++--------
 src/third_party/unwind/dist/src/x86_64/Ginit.c    | 15 +++++++--------
 15 files changed, 89 insertions(+), 80 deletions(-)

diff --git a/src/third_party/unwind/dist/src/aarch64/Ginit.c b/src/third_party/unwind/dist/src/aarch64/Ginit.c
index dec235c829..35389762f2 100644
--- a/src/third_party/unwind/dist/src/aarch64/Ginit.c
+++ b/src/third_party/unwind/dist/src/aarch64/Ginit.c
@@ -61,13 +61,6 @@ tdep_uc_addr (unw_tdep_context_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
-       by a remote unwinder.  On ia64, this is done via a special
-       unwind-table entry.  Perhaps something similar can be done with
-       DWARF2 unwind info.  */
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -78,7 +71,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/arm/Ginit.c b/src/third_party/unwind/dist/src/arm/Ginit.c
index 2720d063a2..0bac0d72da 100644
--- a/src/third_party/unwind/dist/src/arm/Ginit.c
+++ b/src/third_party/unwind/dist/src/arm/Ginit.c
@@ -57,18 +57,17 @@ tdep_uc_addr (unw_tdep_context_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
-       by a remote unwinder.  On ia64, this is done via a special
-       unwind-table entry.  Perhaps something similar can be done with
-       DWARF2 unwind info.  */
-
 static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/third_party/unwind/dist/src/coredump/_UPT_get_dyn_info_list_addr.c
index 0d11905566..739ed0569b 100644
--- a/src/third_party/unwind/dist/src/coredump/_UPT_get_dyn_info_list_addr.c
+++ b/src/third_party/unwind/dist/src/coredump/_UPT_get_dyn_info_list_addr.c
@@ -74,6 +74,11 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
 
 #else
 
+/* XXX fix me: there is currently no way to locate the dyn-info list
+       by a remote unwinder.  On ia64, this is done via a special
+       unwind-table entry.  Perhaps something similar can be done with
+       DWARF2 unwind info.  */
+
 static inline int
 get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
                int *countp)
diff --git a/src/third_party/unwind/dist/src/hppa/Ginit.c b/src/third_party/unwind/dist/src/hppa/Ginit.c
index 461e4b93da..265455a68c 100644
--- a/src/third_party/unwind/dist/src/hppa/Ginit.c
+++ b/src/third_party/unwind/dist/src/hppa/Ginit.c
@@ -64,13 +64,6 @@ _Uhppa_uc_addr (ucontext_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
-       by a remote unwinder.  On ia64, this is done via a special
-       unwind-table entry.  Perhaps something similar can be done with
-       DWARF2 unwind info.  */
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -81,7 +74,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/ia64/Ginit.c b/src/third_party/unwind/dist/src/ia64/Ginit.c
index b09a2ad57c..8601bb3ca8 100644
--- a/src/third_party/unwind/dist/src/ia64/Ginit.c
+++ b/src/third_party/unwind/dist/src/ia64/Ginit.c
@@ -68,6 +68,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
   if (!_U_dyn_info_list_addr)
     return -UNW_ENOINFO;
 #endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
   *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
diff --git a/src/third_party/unwind/dist/src/mi/Gfind_dynamic_proc_info.c b/src/third_party/unwind/dist/src/mi/Gfind_dynamic_proc_info.c
index 98d3501286..2e7c62e5e8 100644
--- a/src/third_party/unwind/dist/src/mi/Gfind_dynamic_proc_info.c
+++ b/src/third_party/unwind/dist/src/mi/Gfind_dynamic_proc_info.c
@@ -49,6 +49,7 @@ local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
     return -UNW_ENOINFO;
 #endif
 
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
   list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr ();
   for (di = list->first; di; di = di->next)
     if (ip >= di->start_ip && ip < di->end_ip)
diff --git a/src/third_party/unwind/dist/src/mips/Ginit.c b/src/third_party/unwind/dist/src/mips/Ginit.c
index 3df170c754..bf7a8f5a8f 100644
--- a/src/third_party/unwind/dist/src/mips/Ginit.c
+++ b/src/third_party/unwind/dist/src/mips/Ginit.c
@@ -69,13 +69,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
-       by a remote unwinder.  On ia64, this is done via a special
-       unwind-table entry.  Perhaps something similar can be done with
-       DWARF2 unwind info.  */
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -86,7 +79,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/ppc32/Ginit.c b/src/third_party/unwind/dist/src/ppc32/Ginit.c
index ba302448a3..7b45455807 100644
--- a/src/third_party/unwind/dist/src/ppc32/Ginit.c
+++ b/src/third_party/unwind/dist/src/ppc32/Ginit.c
@@ -91,9 +91,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -104,7 +101,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/ppc64/Ginit.c b/src/third_party/unwind/dist/src/ppc64/Ginit.c
index 4c88cd6e77..7bfb395a79 100644
--- a/src/third_party/unwind/dist/src/ppc64/Ginit.c
+++ b/src/third_party/unwind/dist/src/ppc64/Ginit.c
@@ -95,9 +95,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -108,7 +105,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/third_party/unwind/dist/src/ptrace/_UPT_get_dyn_info_list_addr.c
index cc5ed04418..16671d453e 100644
--- a/src/third_party/unwind/dist/src/ptrace/_UPT_get_dyn_info_list_addr.c
+++ b/src/third_party/unwind/dist/src/ptrace/_UPT_get_dyn_info_list_addr.c
@@ -71,6 +71,11 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
 
 #else
 
+/* XXX fix me: there is currently no way to locate the dyn-info list
+       by a remote unwinder.  On ia64, this is done via a special
+       unwind-table entry.  Perhaps something similar can be done with
+       DWARF2 unwind info.  */
+
 static inline int
 get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
                int *countp)
diff --git a/src/third_party/unwind/dist/src/s390x/Ginit.c b/src/third_party/unwind/dist/src/s390x/Ginit.c
index f0886ac933..db01743c06 100644
--- a/src/third_party/unwind/dist/src/s390x/Ginit.c
+++ b/src/third_party/unwind/dist/src/s390x/Ginit.c
@@ -50,8 +50,6 @@ static struct unw_addr_space local_addr_space;
 
 unw_addr_space_t unw_local_addr_space = &local_addr_space;
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
 static inline void *
 uc_addr (ucontext_t *uc, int reg)
 {
@@ -75,11 +73,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-/* XXX fix me: there is currently no way to locate the dyn-info list
-       by a remote unwinder.  On ia64, this is done via a special
-       unwind-table entry.  Perhaps something similar can be done with
-       DWARF2 unwind info.  */
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -90,7 +83,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/sh/Ginit.c b/src/third_party/unwind/dist/src/sh/Ginit.c
index 52988a721e..9fe96d2bd4 100644
--- a/src/third_party/unwind/dist/src/sh/Ginit.c
+++ b/src/third_party/unwind/dist/src/sh/Ginit.c
@@ -58,13 +58,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
-       by a remote unwinder.  On ia64, this is done via a special
-       unwind-table entry.  Perhaps something similar can be done with
-       DWARF2 unwind info.  */
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -75,7 +68,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/tilegx/Ginit.c b/src/third_party/unwind/dist/src/tilegx/Ginit.c
index 7564a558be..925e641324 100644
--- a/src/third_party/unwind/dist/src/tilegx/Ginit.c
+++ b/src/third_party/unwind/dist/src/tilegx/Ginit.c
@@ -64,13 +64,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
-       by a remote unwinder.  On ia64, this is done via a special
-       unwind-table entry.  Perhaps something similar can be done with
-       DWARF2 unwind info.  */
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -81,7 +74,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/x86/Ginit.c b/src/third_party/unwind/dist/src/x86/Ginit.c
index f6b8dc27d4..3cec74a216 100644
--- a/src/third_party/unwind/dist/src/x86/Ginit.c
+++ b/src/third_party/unwind/dist/src/x86/Ginit.c
@@ -54,13 +54,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
 
 # endif /* UNW_LOCAL_ONLY */
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
-       by a remote unwinder.  On ia64, this is done via a special
-       unwind-table entry.  Perhaps something similar can be done with
-       DWARF2 unwind info.  */
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -71,7 +64,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
diff --git a/src/third_party/unwind/dist/src/x86_64/Ginit.c b/src/third_party/unwind/dist/src/x86_64/Ginit.c
index 6161da6401..5c4e4269a6 100644
--- a/src/third_party/unwind/dist/src/x86_64/Ginit.c
+++ b/src/third_party/unwind/dist/src/x86_64/Ginit.c
@@ -49,13 +49,6 @@ static struct unw_addr_space local_addr_space;
 
 unw_addr_space_t unw_local_addr_space = &local_addr_space;
 
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
-       by a remote unwinder.  On ia64, this is done via a special
-       unwind-table entry.  Perhaps something similar can be done with
-       DWARF2 unwind info.  */
-
 static void
 put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
 {
@@ -66,7 +59,13 @@ static int
 get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
                         void *arg)
 {
-  *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+  if (!_U_dyn_info_list_addr)
+    return -UNW_ENOINFO;
+#endif
+  // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+  *dyn_info_list_addr = _U_dyn_info_list_addr ();
   return 0;
 }
 
-- 
2.28.0

