[libcxx-commits] [PATCH] D59694: [PPC64][libunwind] Fix r2 not properly restored

Leandro Lupori via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Mar 29 13:00:03 PDT 2019


luporl updated this revision to Diff 192895.
luporl added a comment.
Herald added a subscriber: dexonsmith.

- Addressed review comments
- Fixed ELFv1 ASM functions


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59694/new/

https://reviews.llvm.org/D59694

Files:
  libunwind/src/DwarfInstructions.hpp
  libunwind/src/assembly.h


Index: libunwind/src/assembly.h
===================================================================
--- libunwind/src/assembly.h
+++ libunwind/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", at progbits SEPARATOR
+#define PPC64_OPD2 SEPARATOR \
+  .p2align 3 SEPARATOR \
+  .quad .Lfunc_begin0 SEPARATOR \
+  .quad .TOC. at 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)
@@ -96,13 +110,17 @@
   .globl SYMBOL_NAME(name) SEPARATOR                      \
   EXPORT_SYMBOL(name) SEPARATOR                           \
   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR             \
-  SYMBOL_NAME(name):
+  PPC64_OPD1                                              \
+  SYMBOL_NAME(name):                                      \
+  PPC64_OPD2
 
 #define DEFINE_LIBUNWIND_PRIVATE_FUNCTION(name)           \
   .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)
Index: libunwind/src/DwarfInstructions.hpp
===================================================================
--- libunwind/src/DwarfInstructions.hpp
+++ libunwind/src/DwarfInstructions.hpp
@@ -232,6 +232,31 @@
       }
 #endif
 
+#if defined(_LIBUNWIND_TARGET_PPC64)
+#define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1)
+#define PPC64_ELFV1_R2_OFFSET 40
+#define PPC64_ELFV2_R2_LOAD_INST_ENCODING 0xe8410018u // ld r2,24(r1)
+#define PPC64_ELFV2_R2_OFFSET 24
+      // If the instruction at return address is a TOC (r2) restore,
+      // then r2 was saved and needs to be restored.
+      // ELFv2 ABI specifies that the TOC Pointer must be saved at SP + 24,
+      // while in ELFv1 ABI it is saved at SP + 40.
+      if (R::getArch() == REGISTERS_PPC64 && returnAddress != 0) {
+        pint_t sp = newRegisters.getRegister(UNW_REG_SP);
+        pint_t r2 = 0;
+        switch (addressSpace.get32(returnAddress)) {
+        case PPC64_ELFV1_R2_LOAD_INST_ENCODING:
+          r2 = addressSpace.get64(sp + PPC64_ELFV1_R2_OFFSET);
+          break;
+        case PPC64_ELFV2_R2_LOAD_INST_ENCODING:
+          r2 = addressSpace.get64(sp + PPC64_ELFV2_R2_OFFSET);
+          break;
+        }
+        if (r2)
+          newRegisters.setRegister(UNW_PPC64_R2, r2);
+      }
+#endif
+
       // Return address is address after call site instruction, so setting IP to
       // that does simualates a return.
       newRegisters.setIP(returnAddress);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D59694.192895.patch
Type: text/x-patch
Size: 2987 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20190329/67906cb8/attachment-0001.bin>


More information about the libcxx-commits mailing list