You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/09/16 11:51:25 UTC

[nuttx] 02/02: backtrace/unwind: add more unwind instruction support

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 9f049b47bfdda4f4246a0178e63e07147a5c5cbd
Author: chao an <an...@xiaomi.com>
AuthorDate: Thu Sep 14 16:42:05 2023 +0800

    backtrace/unwind: add more unwind instruction support
    
    Signed-off-by: chao an <an...@xiaomi.com>
---
 arch/arm/src/common/arm_backtrace_unwind.c | 56 ++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arch/arm/src/common/arm_backtrace_unwind.c b/arch/arm/src/common/arm_backtrace_unwind.c
index 599df384db..9369f91615 100644
--- a/arch/arm/src/common/arm_backtrace_unwind.c
+++ b/arch/arm/src/common/arm_backtrace_unwind.c
@@ -432,6 +432,62 @@ static int unwind_exec_content(struct unwind_ctrl_s *ctrl)
 
       ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
     }
+  else if (content == 0xb3 || content == 0xc8 || content == 0xc9)
+    {
+      unsigned long reg_from;
+      unsigned long reg_to;
+      unsigned long mask;
+      unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+      int i;
+
+      mask = unwind_get_byte(ctrl);
+      if (mask == 0)
+        {
+          return -1;
+        }
+
+      reg_from = (mask & 0xf0) >> 4;
+      reg_to = reg_from + (mask & 0x0f);
+
+      if (content == 0xc8)
+        {
+          reg_from += 16;
+          reg_to += 16;
+        }
+
+      for (i = reg_from; i <= reg_to; i++)
+        {
+          vsp += 2;
+        }
+
+      if (content == 0xb3)
+        {
+          vsp++;
+        }
+
+      ctrl->vrs[SP] = (unsigned long)vsp;
+    }
+  else if ((content & 0xf8) == 0xb8 || (content & 0xf8) == 0xd0)
+    {
+      unsigned long reg_to;
+      unsigned long mask = content & 0x07;
+      unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+      int i;
+
+      reg_to = 8 + mask;
+
+      for (i = 8; i <= reg_to; i++)
+        {
+          vsp += 2;
+        }
+
+      if ((content & 0xf8) == 0xb8)
+        {
+          vsp++;
+        }
+
+      ctrl->vrs[SP] = (unsigned long)vsp;
+    }
   else
     {
       ret = -1;