VirtualBox

Changeset 101258 in vbox for trunk


Ignore:
Timestamp:
Sep 25, 2023 6:59:49 PM (19 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159241
Message:

VMM/IEM: Made throw/unwinding work on darwin.arm64. This was a bit of a struggle as some LR pointer authentication seems to be applied while unwinding and I couldn't track it down in the libunwind sources. Assuming it's unconditional for jit code and added the necessary instructions to the prolog and epilog to conform. bugref:10370

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/armv8.h

    r101248 r101258  
    22132213/** A64: Return instruction. */
    22142214#define ARMV8_A64_INSTR_RET         UINT32_C(0xd65f03c0)
     2215/** A64: Return instruction with LR pointer authentication using SP and key A. */
     2216#define ARMV8_A64_INSTR_RETAA       UINT32_C(0xd65f0bff)
     2217/** A64: Return instruction with LR pointer authentication using SP and key B. */
     2218#define ARMV8_A64_INSTR_RETAB       UINT32_C(0xd65f0fff)
     2219/** A64: Insert pointer authentication code into X17 using X16 and key B. */
     2220#define ARMV8_A64_INSTR_PACIB1716   UINT32_C(0xd503215f)
     2221/** A64: Insert pointer authentication code into LR using SP and key B. */
     2222#define ARMV8_A64_INSTR_PACIBSP     UINT32_C(0xd503237f)
     2223/** A64: Insert pointer authentication code into LR using XZR and key B. */
     2224#define ARMV8_A64_INSTR_PACIBZ      UINT32_C(0xd503235f)
    22152225
    22162226
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r101251 r101258  
    753753        *Ptr.pb++   = 0;                                    /* Segment selector size. */
    754754    }
     755#  ifdef RT_ARCH_AMD64
    755756    Ptr = iemDwarfPutLeb128(Ptr, 1);                        /* Code alignment factor (LEB128 = 1). */
     757#  else
     758    Ptr = iemDwarfPutLeb128(Ptr, 4);                        /* Code alignment factor (LEB128 = 4). */
     759#  endif
    756760    Ptr = iemDwarfPutLeb128(Ptr, -8);                       /* Data alignment factor (LEB128 = -8). */
    757761#  ifdef RT_ARCH_AMD64
    758762    Ptr = iemDwarfPutUleb128(Ptr, DWREG_AMD64_RA);          /* Return address column (ULEB128) */
    759763#  elif defined(RT_ARCH_ARM64)
    760     Ptr = iemDwarfPutUleb128(Ptr, DWREG_ARM64_PC);          /* Return address column (ULEB128) */
     764    Ptr = iemDwarfPutUleb128(Ptr, DWREG_ARM64_LR);          /* Return address column (ULEB128) */
    761765#  else
    762766#   error "port me"
     
    775779    Ptr = iemDwarfPutCfaDefCfa(Ptr, DWREG_ARM64_BP,  16);   /* CFA     = BP + 0x10 - first stack parameter */
    776780    //Ptr = iemDwarfPutCfaDefCfa(Ptr, DWREG_ARM64_SP,  IEMNATIVE_FRAME_VAR_SIZE + IEMNATIVE_FRAME_SAVE_REG_SIZE);
    777     Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_ARM64_PC,   1);   /* Ret PC  = [CFA + 1*-8] */
     781    Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_ARM64_LR,   1);   /* Ret PC  = [CFA + 1*-8] */
    778782    Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_ARM64_BP,   2);   /* Ret BP  = [CFA + 2*-8] */
    779783    Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_ARM64_X28,  3);   /* X28     = [CFA + 3*-8] */
     
    788792    Ptr = iemDwarfPutCfaOffset(Ptr, DWREG_ARM64_X19, 12);   /* X19     = [CFA +12*-8] */
    789793    AssertCompile(IEMNATIVE_FRAME_SAVE_REG_SIZE / 8 == 12);
     794    /** @todo we we need to do something about clearing DWREG_ARM64_RA_SIGN_STATE or something? */
     795#  else
     796#   error "port me"
    790797#  endif
    791798    while ((Ptr.u - PtrCie.u) & 3)
     
    806813    *Ptr.pu64++ = (uintptr_t)pvChunk;                       /* Absolute start PC of this FDE. */
    807814    *Ptr.pu64++ = pExecMemAllocator->cbChunk;               /* PC range length for this PDE. */
    808     //*Ptr.pb++ = DW_CFA_nop; - not required for recent libgcc/glibc.
     815#  if 0 /* not requried for recent libunwind.dylib nor recent libgcc/glib. */
     816    *Ptr.pb++ = DW_CFA_nop;
     817#  endif
    809818    while ((Ptr.u - PtrFde.u) & 3)
    810819        *Ptr.pb++ = DW_CFA_nop;
     
    16761685    pu32CodeBuf[off++] = Armv8A64MkInstrAddSub(false /*fSub*/, ARMV8_A64_REG_SP, ARMV8_A64_REG_SP, IEMNATIVE_FRAME_SAVE_REG_SIZE);
    16771686
    1678     /* ret */
    1679     pu32CodeBuf[off++] = ARMV8_A64_INSTR_RET;
     1687    /* retab / ret */
     1688# ifdef RT_OS_DARWIN /** @todo See todo on pacibsp in the prolog. */
     1689    if (1)
     1690        pu32CodeBuf[off++] = ARMV8_A64_INSTR_RETAB;
     1691    else
     1692# endif
     1693        pu32CodeBuf[off++] = ARMV8_A64_INSTR_RET;
    16801694
    16811695#else
     
    17471761    AssertReturn(pu32CodeBuf, UINT32_MAX);
    17481762
     1763# ifdef RT_OS_DARWIN /** @todo This seems to be requirement by libunwind for JIT FDEs. Investigate further as been unable
     1764                      * to figure out where the BRK following AUTHB*+XPACB* stuff comes from in libunwind.  It's
     1765                      * definitely the dwarf stepping code, but till found it's very tedious to figure out whether it's
     1766                      * in any way conditional, so just emitting this instructions now and hoping for the best... */
     1767    /* pacibsp */
     1768    pu32CodeBuf[off++] = ARMV8_A64_INSTR_PACIBSP;
     1769# endif
     1770
    17491771    /* stp x19, x20, [sp, #-IEMNATIVE_FRAME_SAVE_REG_SIZE] ; Allocate space for saving registers and place x19+x20 at the bottom. */
    17501772    AssertCompile(IEMNATIVE_FRAME_SAVE_REG_SIZE < 64*8);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette