Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Apr 2023 23:39:00 GMT
From:      Po-Chuan Hsieh <sunpoet@FreeBSD.org>
To:        ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org
Subject:   git: 42ca033358a7 - main - devel/libunwind: Stop aliasing RSP and CFA
Message-ID:  <202304092339.339Nd0uC079093@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by sunpoet:

URL: https://cgit.FreeBSD.org/ports/commit/?id=42ca033358a793bf186420844535e97df3000df6

commit 42ca033358a793bf186420844535e97df3000df6
Author:     Po-Chuan Hsieh <sunpoet@FreeBSD.org>
AuthorDate: 2023-04-09 23:38:47 +0000
Commit:     Po-Chuan Hsieh <sunpoet@FreeBSD.org>
CommitDate: 2023-04-09 23:38:47 +0000

    devel/libunwind: Stop aliasing RSP and CFA
    
    - Bump PORTREVISION for package change
    
    PR:             269875
    Obtained from:  https://github.com/libunwind/libunwind/commit/400b3f819ad44ff4e15487b163cc3613389cb4c8
    Reported by:    mizhka
---
 devel/libunwind/Makefile               |   2 +-
 devel/libunwind/files/patch-bug-269875 | 310 +++++++++++++++++++++++++++++++++
 2 files changed, 311 insertions(+), 1 deletion(-)

diff --git a/devel/libunwind/Makefile b/devel/libunwind/Makefile
index 08c0dd1bedff..73df95e202bf 100644
--- a/devel/libunwind/Makefile
+++ b/devel/libunwind/Makefile
@@ -1,6 +1,6 @@
 PORTNAME=	libunwind
 PORTVERSION=	20211201	# This is the release date on https://download.savannah.gnu.org/releases/libunwind/
-PORTREVISION=	1
+PORTREVISION=	2
 CATEGORIES=	devel
 MASTER_SITES=	SAVANNAH \
 		https://github.com/libunwind/libunwind/releases/download/v${PORTVERSION}/
diff --git a/devel/libunwind/files/patch-bug-269875 b/devel/libunwind/files/patch-bug-269875
new file mode 100644
index 000000000000..6655731e6c4b
--- /dev/null
+++ b/devel/libunwind/files/patch-bug-269875
@@ -0,0 +1,310 @@
+Obtained from:	https://github.com/libunwind/libunwind/commit/400b3f819ad44ff4e15487b163cc3613389cb4c8
+
+--- include/dwarf.h.orig	2021-12-01 00:46:39 UTC
++++ include/dwarf.h
+@@ -231,6 +231,7 @@ typedef enum
+     DWARF_WHERE_REG,            /* register saved in another register */
+     DWARF_WHERE_EXPR,           /* register saved */
+     DWARF_WHERE_VAL_EXPR,       /* register has computed value */
++    DWARF_WHERE_CFA,            /* register is set to the computed cfa value */
+   }
+ dwarf_where_t;
+ 
+@@ -313,7 +314,7 @@ typedef struct dwarf_cursor
+     void *as_arg;               /* argument to address-space callbacks */
+     unw_addr_space_t as;        /* reference to per-address-space info */
+ 
+-    unw_word_t cfa;     /* canonical frame address; aka frame-/stack-pointer */
++    unw_word_t cfa;     /* canonical frame address; aka frame-pointer */
+     unw_word_t ip;              /* instruction pointer */
+     unw_word_t args_size;       /* size of arguments */
+     unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS];
+--- include/libunwind_i.h.orig	2021-12-01 00:46:39 UTC
++++ include/libunwind_i.h
+@@ -346,6 +346,10 @@ static inline void invalidate_edi (struct elf_dyn_info
+ 
+ #include "tdep/libunwind_i.h"
+ 
++#ifndef TDEP_DWARF_SP
++#define TDEP_DWARF_SP UNW_TDEP_SP
++#endif
++
+ #ifndef tdep_get_func_addr
+ # define tdep_get_func_addr(as,addr,v)          (*(v) = addr, 0)
+ #endif
+--- include/tdep-x86/dwarf-config.h.orig	2021-12-01 00:46:39 UTC
++++ include/tdep-x86/dwarf-config.h
+@@ -43,9 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+ typedef struct dwarf_loc
+   {
+     unw_word_t val;
+-#ifndef UNW_LOCAL_ONLY
+     unw_word_t type;            /* see X86_LOC_TYPE_* macros.  */
+-#endif
+   }
+ dwarf_loc_t;
+ 
+--- include/tdep-x86/libunwind_i.h.orig	2021-12-01 00:46:39 UTC
++++ include/tdep-x86/libunwind_i.h
+@@ -84,15 +84,26 @@ dwarf_get_uc(const struct dwarf_cursor *cursor)
+ }
+ 
+ #define DWARF_GET_LOC(l)        ((l).val)
++# define DWARF_LOC_TYPE_MEM     (0 << 0)
++# define DWARF_LOC_TYPE_FP      (1 << 0)
++# define DWARF_LOC_TYPE_REG     (1 << 1)
++# define DWARF_LOC_TYPE_VAL     (1 << 2)
+ 
+-#ifdef UNW_LOCAL_ONLY
++# define DWARF_IS_REG_LOC(l)    (((l).type & DWARF_LOC_TYPE_REG) != 0)
++# define DWARF_IS_FP_LOC(l)     (((l).type & DWARF_LOC_TYPE_FP) != 0)
++# define DWARF_IS_MEM_LOC(l)    ((l).type == DWARF_LOC_TYPE_MEM)
++# define DWARF_IS_VAL_LOC(l)    (((l).type & DWARF_LOC_TYPE_VAL) != 0)
++
++# define DWARF_LOC(r, t)        ((dwarf_loc_t) { .val = (r), .type = (t) })
+ # define DWARF_NULL_LOC         DWARF_LOC (0, 0)
+-# define DWARF_IS_NULL_LOC(l)   (DWARF_GET_LOC (l) == 0)
+-# define DWARF_LOC(r, t)        ((dwarf_loc_t) { .val = (r) })
+-# define DWARF_IS_REG_LOC(l)    0
++# define DWARF_IS_NULL_LOC(l)                                           \
++                ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
++# define DWARF_VAL_LOC(c,v)     DWARF_LOC ((v), DWARF_LOC_TYPE_VAL)
++# define DWARF_MEM_LOC(c,m)     DWARF_LOC ((m), DWARF_LOC_TYPE_MEM)
++
++#ifdef UNW_LOCAL_ONLY
+ # define DWARF_REG_LOC(c,r)     (DWARF_LOC((unw_word_t)                      \
+                                  tdep_uc_addr(dwarf_get_uc(c), (r)), 0))
+-# define DWARF_MEM_LOC(c,m)     DWARF_LOC ((m), 0)
+ # define DWARF_FPREG_LOC(c,r)   (DWARF_LOC((unw_word_t)                      \
+                                  tdep_uc_addr(dwarf_get_uc(c), (r)), 0))
+ 
+@@ -114,35 +125,8 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, 
+   return 0;
+ }
+ 
+-static inline int
+-dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
+-{
+-  if (!DWARF_GET_LOC (loc))
+-    return -1;
+-  return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
+-                                   0, c->as_arg);
+-}
+-
+-static inline int
+-dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
+-{
+-  if (!DWARF_GET_LOC (loc))
+-    return -1;
+-  return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
+-                                   1, c->as_arg);
+-}
+-
+ #else /* !UNW_LOCAL_ONLY */
+-# define DWARF_LOC_TYPE_FP      (1 << 0)
+-# define DWARF_LOC_TYPE_REG     (1 << 1)
+-# define DWARF_NULL_LOC         DWARF_LOC (0, 0)
+-# define DWARF_IS_NULL_LOC(l)                                           \
+-                ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
+-# define DWARF_LOC(r, t)        ((dwarf_loc_t) { .val = (r), .type = (t) })
+-# define DWARF_IS_REG_LOC(l)    (((l).type & DWARF_LOC_TYPE_REG) != 0)
+-# define DWARF_IS_FP_LOC(l)     (((l).type & DWARF_LOC_TYPE_FP) != 0)
+ # define DWARF_REG_LOC(c,r)     DWARF_LOC((r), DWARF_LOC_TYPE_REG)
+-# define DWARF_MEM_LOC(c,m)     DWARF_LOC ((m), 0)
+ # define DWARF_FPREG_LOC(c,r)   DWARF_LOC((r), (DWARF_LOC_TYPE_REG      \
+                                                 | DWARF_LOC_TYPE_FP))
+ 
+@@ -192,38 +176,33 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, 
+                                    1, c->as_arg);
+ }
+ 
++#endif /* !UNW_LOCAL_ONLY */
++
+ static inline int
+ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
+ {
+   if (DWARF_IS_NULL_LOC (loc))
+     return -UNW_EBADREG;
+ 
+-  /* If a code-generator were to save a value of type unw_word_t in a
+-     floating-point register, we would have to support this case.  I
+-     suppose it could happen with MMX registers, but does it really
+-     happen?  */
+-  assert (!DWARF_IS_FP_LOC (loc));
+-
+   if (DWARF_IS_REG_LOC (loc))
+     return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
+                                      0, c->as_arg);
+-  else
++  if (DWARF_IS_MEM_LOC (loc))
+     return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
+                                      0, c->as_arg);
++  assert(DWARF_IS_VAL_LOC (loc));
++  *val = DWARF_GET_LOC (loc);
++  return 0;
+ }
+ 
+ static inline int
+ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
+ {
++  assert(!DWARF_IS_VAL_LOC (loc));
++
+   if (DWARF_IS_NULL_LOC (loc))
+     return -UNW_EBADREG;
+ 
+-  /* If a code-generator were to save a value of type unw_word_t in a
+-     floating-point register, we would have to support this case.  I
+-     suppose it could happen with MMX registers, but does it really
+-     happen?  */
+-  assert (!DWARF_IS_FP_LOC (loc));
+-
+   if (DWARF_IS_REG_LOC (loc))
+     return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
+                                      1, c->as_arg);
+@@ -232,7 +211,9 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, un
+                                      1, c->as_arg);
+ }
+ 
+-#endif /* !UNW_LOCAL_ONLY */
++// For historical reasons, the DWARF numbering does not match the libunwind
++// numbering, necessitating this override
++#define TDEP_DWARF_SP 4
+ 
+ #define tdep_getcontext_trace           unw_getcontext
+ #define tdep_init_done                  UNW_OBJ(init_done)
+--- src/dwarf/Gparser.c.orig	2021-12-01 00:46:39 UTC
++++ src/dwarf/Gparser.c
+@@ -508,6 +508,9 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_
+   for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i)
+     set_reg (sr, i, DWARF_WHERE_SAME, 0);
+ 
++  // SP defaults to CFA (but is overridable)
++  set_reg (sr, TDEP_DWARF_SP, DWARF_WHERE_CFA, 0);
++
+   struct dwarf_cie_info *dci = c->pi.unwind_info;
+   sr->rs_current.ret_addr_column  = dci->ret_addr_column;
+   unw_word_t addr = dci->cie_instr_start;
+@@ -792,14 +795,14 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_
+       /* As a special-case, if the stack-pointer is the CFA and the
+          stack-pointer wasn't saved, popping the CFA implicitly pops
+          the stack-pointer as well.  */
+-      if ((rs->reg.val[DWARF_CFA_REG_COLUMN] == UNW_TDEP_SP)
+-          && (UNW_TDEP_SP < ARRAY_SIZE(rs->reg.val))
+-          && (rs->reg.where[UNW_TDEP_SP] == DWARF_WHERE_SAME))
++      if ((rs->reg.val[DWARF_CFA_REG_COLUMN] == TDEP_DWARF_SP)
++          && (TDEP_DWARF_SP < ARRAY_SIZE(rs->reg.val))
++          && (DWARF_IS_NULL_LOC(c->loc[TDEP_DWARF_SP])))
+           cfa = c->cfa;
+       else
+         {
+           regnum = dwarf_to_unw_regnum (rs->reg.val[DWARF_CFA_REG_COLUMN]);
+-          if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0)
++          if ((ret = unw_get_reg (dwarf_to_cursor(c), regnum, &cfa)) < 0)
+             return ret;
+         }
+       cfa += rs->reg.val[DWARF_CFA_OFF_COLUMN];
+@@ -834,6 +837,10 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_
+           break;
+ 
+         case DWARF_WHERE_SAME:
++          break;
++
++        case DWARF_WHERE_CFA:
++          new_loc[i] = DWARF_VAL_LOC (c, cfa);
+           break;
+ 
+         case DWARF_WHERE_CFAREL:
+--- src/x86/Gos-freebsd.c.orig	2021-12-01 00:46:39 UTC
++++ src/x86/Gos-freebsd.c
+@@ -138,6 +138,7 @@ x86_handle_signal_frame (unw_cursor_t *cursor)
+     c->dwarf.loc[ST0] = DWARF_NULL_LOC;
+   } else if (c->sigcontext_format == X86_SCF_FREEBSD_SYSCALL) {
+     c->dwarf.loc[EIP] = DWARF_LOC (c->dwarf.cfa, 0);
++    c->dwarf.loc[ESP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 4);
+     c->dwarf.loc[EAX] = DWARF_NULL_LOC;
+     c->dwarf.cfa += 4;
+     c->dwarf.use_prev_instr = 1;
+--- src/x86/Gregs.c.orig	2021-12-01 00:46:39 UTC
++++ src/x86/Gregs.c
+@@ -53,7 +53,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, u
+       break;
+ 
+     case UNW_X86_CFA:
+-    case UNW_X86_ESP:
+       if (write)
+         return -UNW_EREADONLYREG;
+       *valp = c->dwarf.cfa;
+@@ -81,6 +80,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, u
+     case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break;
+     case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break;
+ 
++    case UNW_X86_ESP: loc = c->dwarf.loc[ESP]; break;
+     case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break;
+     case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break;
+     case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break;
+--- src/x86/Gstep.c.orig	2021-12-01 00:46:39 UTC
++++ src/x86/Gstep.c
+@@ -47,7 +47,7 @@ unw_step (unw_cursor_t *cursor)
+     {
+       /* DWARF failed, let's see if we can follow the frame-chain
+          or skip over the signal trampoline.  */
+-      struct dwarf_loc ebp_loc, eip_loc;
++      struct dwarf_loc ebp_loc, eip_loc, esp_loc;
+ 
+       /* We could get here because of missing/bad unwind information.
+          Validate all addresses before dereferencing. */
+@@ -77,6 +77,7 @@ unw_step (unw_cursor_t *cursor)
+                  c->dwarf.cfa);
+ 
+           ebp_loc = DWARF_LOC (c->dwarf.cfa, 0);
++          esp_loc = DWARF_VAL_LOC (c, c->dwarf.cfa + 8);
+           eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0);
+           c->dwarf.cfa += 8;
+ 
+@@ -87,6 +88,7 @@ unw_step (unw_cursor_t *cursor)
+             c->dwarf.loc[i] = DWARF_NULL_LOC;
+ 
+           c->dwarf.loc[EBP] = ebp_loc;
++          c->dwarf.loc[ESP] = esp_loc;
+           c->dwarf.loc[EIP] = eip_loc;
+           c->dwarf.use_prev_instr = 1;
+         }
+--- src/x86_64/Gos-freebsd.c.orig	2021-12-01 00:46:39 UTC
++++ src/x86_64/Gos-freebsd.c
+@@ -133,6 +133,7 @@ x86_64_handle_signal_frame (unw_cursor_t *cursor)
+     c->dwarf.loc[RCX] = c->dwarf.loc[R10];
+     /*  rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0);       */
+     /*  rbp_loc = c->dwarf.loc[RBP];                    */
++    c->dwarf.loc[RSP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 8);
+     c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0);
+     ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip);
+     Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n",
+--- src/x86_64/Gregs.c.orig	2021-12-01 00:46:39 UTC
++++ src/x86_64/Gregs.c
+@@ -79,7 +79,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, u
+       break;
+ 
+     case UNW_X86_64_CFA:
+-    case UNW_X86_64_RSP:
+       if (write)
+         return -UNW_EREADONLYREG;
+       *valp = c->dwarf.cfa;
+@@ -107,6 +106,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, u
+     case UNW_X86_64_RCX: loc = c->dwarf.loc[RCX]; break;
+     case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break;
+ 
++    case UNW_X86_64_RSP: loc = c->dwarf.loc[RSP]; break;
+     case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break;
+     case UNW_X86_64_RSI: loc = c->dwarf.loc[RSI]; break;
+     case UNW_X86_64_RDI: loc = c->dwarf.loc[RDI]; break;
+--- src/x86_64/Gstep.c.orig	2021-12-01 00:46:39 UTC
++++ src/x86_64/Gstep.c
+@@ -223,7 +223,7 @@ unw_step (unw_cursor_t *cursor)
+                   Debug (2, "RIP fixup didn't work, falling back\n");
+                   unw_word_t rbp1 = 0;
+                   rbp_loc = DWARF_LOC(rbp, 0);
+-                  rsp_loc = DWARF_NULL_LOC;
++                  rsp_loc = DWARF_VAL_LOC(c, rbp + 16);
+                   rip_loc = DWARF_LOC (rbp + 8, 0);
+                   ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1);
+                   Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n",



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202304092339.339Nd0uC079093>