[PPC64][libunwind] Fix r2 not properly restored

This change makes each unwind step inspect the instruction at the
return address and, if needed, read r2 from its saved location and
modify the context appropriately.

The unwind logic is able to handle both ELFv1 and ELFv2 stacks.

Reported by Bug 41050

Patch by Leandro Lupori!

Differential Revision: https://reviews.llvm.org/D59694

llvm-svn: 360861
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 44266b9e115ad172b1f6a88d15d4e7579812c0fc
diff --git a/src/assembly.h b/src/assembly.h
index 7614b0c..7d22aeb 100644
--- a/src/assembly.h
+++ b/src/assembly.h
@@ -36,6 +36,20 @@
 #define SEPARATOR ;
 #endif
 
+#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1)
+#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR
+#define PPC64_OPD2 SEPARATOR \
+  .p2align 3 SEPARATOR \
+  .quad .Lfunc_begin0 SEPARATOR \
+  .quad .TOC.@tocbase SEPARATOR \
+  .quad 0 SEPARATOR \
+  .text SEPARATOR \
+.Lfunc_begin0:
+#else
+#define PPC64_OPD1
+#define PPC64_OPD2
+#endif
+
 #define GLUE2(a, b) a ## b
 #define GLUE(a, b) GLUE2(a, b)
 #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
@@ -123,7 +137,9 @@
   .globl SYMBOL_NAME(name) SEPARATOR                                           \
   HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                                   \
   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
-  SYMBOL_NAME(name):
+  PPC64_OPD1                                                                   \
+  SYMBOL_NAME(name):                                                           \
+  PPC64_OPD2
 
 #if defined(__arm__)
 #if !defined(__ARM_ARCH)