VirtualBox

Changeset 104215 in vbox for trunk/src


Ignore:
Timestamp:
Apr 7, 2024 6:37:57 PM (10 months ago)
Author:
vboxsync
Message:

libs/xpcom: Rework the xptcstubs and xptcinvoke code for arm64 to work with gcc, bugref:10391

Unlike clang/llvm gcc doesn't support the naked attribute on arm64 for some unknown reason.
In order to avoid having two almost identical copies of the assembly code convert the existing
code to raw asm statements which works on both clang and gcc. These are not put into a separate
assembly file in order to be able to use the defined preprocessor macros used in the C++ code as well.
This also creates a header defining some assembler macros getting injected into the generated assembly
for both xptcinvoke and xptcstubs in order to hide the differences between clang/macho-o and gcc/elf.
This is as pretty as I could get it but it is still uglier than the lean clang only solution using naked
functions.

Location:
trunk/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm64_vbox.cpp

    r98103 r104215  
    3535#include <iprt/assert.h>
    3636
     37#include "xptc_arm64_vbox.h"
     38
    3739
    3840/*********************************************************************************************************************************
    3941*   Defined Constants And Macros                                                                                                 *
    4042*********************************************************************************************************************************/
    41 #define NUM_ARGS_IN_GPRS    8   /**< Number of arguments passed in general purpose registers (starting with x0). */
    42 #define NUM_ARGS_IN_FPRS    8   /**< Number of arguments passed in floating point registers (starting with d0). */
    43 
    4443#define MY_MAX_ARGS         64  /**< Limit ourselves to 64 arguments. */
    4544
    46 
    47 
     45#define NSXPTC_VARIANT_SIZE    (8 + 8 + 8)
     46#define NSXPTC_VARIANT_PTR_OFF 8
     47
     48AssertCompileSize(nsXPTCVariant, NSXPTC_VARIANT_SIZE);
     49AssertCompileMemberOffset(nsXPTCVariant, ptr, NSXPTC_VARIANT_PTR_OFF);
    4850AssertCompileMemberOffset(nsXPTCVariant, val, 0);
    4951
    50 extern "C" __attribute__((naked)) nsresult
     52
     53/*
     54 * clang supports the naked attribute on arm64 whereas gcc does not, so we have to resort to this ugliness
     55 * in order to support both and not require a separate assembly file so we need only one set of defines...
     56 * Luckily this abormination is contained in this file.
     57 */
     58extern "C" nsresult
    5159arm64AsmInvoker(uintptr_t pfnMethod /*x0*/, uint32_t cParams /*w1*/, nsXPTCVariant *paParams /*x2*/, uint64_t cbStack /*x3*/,
    52                 uint8_t *acbStackArgs /*x4*/, uint64_t *pauGprArgs /*x5*/, uint64_t *pauFprArgs /*x6*/, uint32_t cFprArgs /*x7*/)
    53 {
    54     __asm__ __volatile__(
     60                uint8_t *acbStackArgs /*x4*/, uint64_t *pauGprArgs /*x5*/, uint64_t *pauFprArgs /*x6*/, uint32_t cFprArgs /*x7*/);
     61
     62__asm__ (
     63"BEGINCODE\n"
     64"BEGINPROC_HIDDEN arm64AsmInvoker\n"
     65        ".cfi_startproc\n"
    5566        /* Prologue - create the frame. */ "\
    5667        sub     sp, sp, 16 \n\
     
    97108        bic     x3, x3, #3 \n\
    98109        str     w0, [x3] \n"
    99 #ifdef RT_OS_DARWIN /* macOS compacts stack usage. */
     110#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) /* macOS compacts stack usage. */
    100111"       add     x3, x3, #4 \n"
    101112#endif
     
    105116        ldrb    w0, [x2] \n\
    106117        strb    w0, [x3] \n"
    107 #ifdef RT_OS_DARWIN /* macOS compacts stack usage. */
     118#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) /* macOS compacts stack usage. */
    108119"       add     x3, x3, #1 \n"
    109120#endif
     
    115126        bic     x3, x3, #1 \n\
    116127        strh    w0, [x3] \n"
    117 #ifdef RT_OS_DARWIN /* macOS compacts stack usage. */
     128#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) /* macOS compacts stack usage. */
    118129"       add     x3, x3, #2 \n"
    119130#endif
     
    121132\n\
    122133Lstore_64bits_ptr:\n\
    123         ldr     x0, [x2, %[offPtrInXPTCVariant]] \n\
     134        ldr     x0, [x2, #" RT_XSTR(NSXPTC_VARIANT_PTR_OFF) "] \n\
    124135        b       Lstore_64bits_common \n\
    125136Lstore_64bits:\n\
     
    131142        bic     x3, x3, #7 \n\
    132143        str     x0, [x3] \n"
    133 #ifdef RT_OS_DARWIN /* macOS compacts stack usage. */
     144#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) /* macOS compacts stack usage. */
    134145"       add     x3, x3, #8 \n"
    135146#endif
    136147"\n\
    137148Ladvance:\n"
    138 #ifndef RT_OS_DARWIN /* macOS compacts stack usage. */
     149#if !defined(RT_OS_DARWIN) && !defined(RT_OS_LINUX) /* macOS compacts stack usage. */
    139150"       add     x3, x3, #8 \n"
    140151#endif
    141152"       add     x4, x4, #1 \n\
    142         add     x2, x2, %[cbXPTCVariant] \n\
     153        add     x2, x2, # " RT_XSTR(NSXPTC_VARIANT_SIZE) " \n\
    143154        sub     w1, w1, #1 \n\
    144155        cmp     w1, #0 \n\
     
    164175        .cfi_restore x29 \n\
    165176        .cfi_restore x30 \n\
    166         ret \n\
    167 "   :
    168     : [cbXPTCVariant] "i" (sizeof(nsXPTCVariant))
    169     , [offPtrInXPTCVariant] "i" (offsetof(nsXPTCVariant, ptr))
    170     :);
    171 }
     177        ret \n"
     178        ".cfi_endproc\n"
     179);
    172180
    173181
  • trunk/src/libs/xpcom18a4/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm64_vbox.cpp

    r98103 r104215  
    3535#include <iprt/assert.h>
    3636
    37 
    38 /*********************************************************************************************************************************
    39 *   Defined Constants And Macros                                                                                                 *
    40 *********************************************************************************************************************************/
    41 #if defined(RT_OS_DARWIN)
    42 # define NAME_PREFIX        _
    43 # define NAME_PREFIX_STR    "_"
    44 #else
    45 # define NAME_PREFIX
    46 # define NAME_PREFIX_STR    ""
    47 #endif
    48 #define ASMNAME(a_Name)     NAME_PREFIX ## a_Name
    49 #define NUM_ARGS_IN_GPRS    8   /**< Number of arguments passed in general purpose registers (starting with x0). */
    50 #define NUM_ARGS_IN_FPRS    8   /**< Number of arguments passed in floating point registers (starting with d0). */
     37#include "xptc_arm64_vbox.h"
    5138
    5239
     
    5441*   Internal Functions                                                                                                           *
    5542*********************************************************************************************************************************/
    56 extern "C" __attribute__((naked)) nsresult CommonXPTCStub(void);
    5743DECL_NO_INLINE(extern "C", nsresult)
    5844CommonXPTCStubCWorker(nsXPTCStubBase *pThis, uint32_t idxMethod, uint64_t *pauGprArgs, uint64_t *pauFprArgs, uint64_t *puStackArgs);
    5945
    60 
    61 /**
    62  * All the stubs call this shared code w/ method index in w17.
    63  *
    64  * The naked attribute means pure inline assembly function.  clang complains
    65  * if we put C statements in it.  So, this exacty what we need here and for the
    66  * stubs.
    67  *
    68  * @note This could be static if we weren't afraid the compile would optimize it
    69  *       out.
    70  */
    71 extern "C" __attribute__((naked)) nsresult CommonXPTCStub(void)
    72 {
    73     __asm__ __volatile__(
    74         /* Prologue - reserve space for frame+link reg spill and the GPR and FPR arrays. */ "\
    75         sub     sp, sp, %[cbGPRandFPRs] + 16 \n\
    76         stp     x29, x30, [sp, %[cbGPRandFPRs]] \n\
    77         add     x29, sp, %[cbGPRandFPRs] \n\
    78         .cfi_def_cfa        x29, 16 \n\
    79         .cfi_rel_offset     x30, -8 \n\
    80         .cfi_rel_offset     x29, -16 \n\
     46/*
     47 * clang supports the naked attribute on arm64 whereas gcc does not, so we have to resort to this ugliness
     48 * in order to support both and not require a separate assembly file so we need only one set of defines...
     49 * Luckily this abormination is contained in this file.
     50 */
     51__asm__(
     52    "BEGINCODE \n"
     53    "BEGINPROC_HIDDEN CommonXPTCStub\n"
     54    ".cfi_startproc\n"
     55    /* Prologue - reserve space for frame+link reg spill and the GPR and FPR arrays. */ "\
     56    sub     sp, sp,        #" RT_XSTR(SZ_ARGS_IN_GPRS_AND_FPRS) " + 16 \n\
     57    stp     x29, x30, [sp, #" RT_XSTR(SZ_ARGS_IN_GPRS_AND_FPRS) "] \n\
     58    add     x29, sp,       #" RT_XSTR(SZ_ARGS_IN_GPRS_AND_FPRS) "\n\
     59    .cfi_def_cfa        x29, 16 \n\
     60    .cfi_rel_offset     x30, -8 \n\
     61    .cfi_rel_offset     x29, -16 \n\
    8162"
    82         /* reserve stack space for the integer and floating point registers and save them: */ "\
    83         \n\
    84         stp     x0, x1, [sp, #0] \n\
    85         stp     x2, x3, [sp, #16] \n\
    86         stp     x4, x5, [sp, #32] \n\
    87         stp     x6, x7, [sp, #48] \n\
    88         \n\
    89         stp     d0, d1, [sp, %[cbGPRs]] \n\
    90         stp     d2, d3, [sp, %[cbGPRs] + 16] \n\
    91         stp     d4, d5, [sp, %[cbGPRs] + 32] \n\
    92         stp     d6, d7, [sp, %[cbGPRs] + 48] \n\
     63    /* reserve stack space for the integer and floating point registers and save them: */ "\
     64    \n\
     65    stp     x0, x1, [sp, #0] \n\
     66    stp     x2, x3, [sp, #16] \n\
     67    stp     x4, x5, [sp, #32] \n\
     68    stp     x6, x7, [sp, #48] \n\
     69    \n\
     70    stp     d0, d1, [sp, #" RT_XSTR(SZ_ARGS_IN_GPRS) "] \n\
     71    stp     d2, d3, [sp, #" RT_XSTR(SZ_ARGS_IN_GPRS) " + 16] \n\
     72    stp     d4, d5, [sp, #" RT_XSTR(SZ_ARGS_IN_GPRS) " + 32] \n\
     73    stp     d6, d7, [sp, #" RT_XSTR(SZ_ARGS_IN_GPRS) " + 48] \n\
    9374\n"
    94         /* Call the C worker. We keep x0 as is.
    95            Set w1 to the w17 method index from the stubs. */ "\
    96         mov     w1, w17 \n\
    97         mov     x2, sp \n\
    98         add     x3, sp, %[cbGPRs] \n\
    99         add     x4, sp, %[cbGPRandFPRs] + 16 \n\
    100         bl      " NAME_PREFIX_STR "CommonXPTCStubCWorker \n\
     75    /* Call the C worker. We keep x0 as is.
     76       Set w1 to the w17 method index from the stubs. */ "\
     77    mov     w1, w17 \n\
     78    mov     x2, sp \n\
     79    add     x3, sp, #" RT_XSTR(SZ_ARGS_IN_GPRS) "\n\
     80    add     x4, sp, #" RT_XSTR(SZ_ARGS_IN_GPRS_AND_FPRS) " + 16 \n\
     81    bl      " NAME_PREFIX_STR "CommonXPTCStubCWorker \n\
    10182"
    102         /* Epilogue (clang does not emit the .cfi's here, so drop them too?): */ "\
    103         ldp     x29, x30, [sp, %[cbGPRandFPRs]] \n\
    104         add     sp, sp, %[cbGPRandFPRs] + 16 \n\
    105         .cfi_def_cfa sp, 0 \n\
    106         .cfi_restore x29 \n\
    107         .cfi_restore x30 \n\
    108         ret \n\
    109 "   :
    110     : [cbGPRandFPRs] "i" (NUM_ARGS_IN_GPRS * 8 + NUM_ARGS_IN_FPRS * 8)
    111     , [cbGPRs] "i" (NUM_ARGS_IN_GPRS * 8)
    112     :);
    113 }
     83    /* Epilogue (clang does not emit the .cfi's here, so drop them too?): */ "\
     84    ldp     x29, x30, [sp, #" RT_XSTR(SZ_ARGS_IN_GPRS_AND_FPRS) "] \n\
     85    add     sp, sp,        #" RT_XSTR(SZ_ARGS_IN_GPRS_AND_FPRS) " + 16 \n\
     86    .cfi_def_cfa sp, 0 \n\
     87    .cfi_restore x29 \n\
     88    .cfi_restore x30 \n\
     89    ret \n"
     90    ".cfi_endproc\n"
     91);
    11492
    11593#define STUB_ENTRY(n) \
    116     __attribute__((naked)) nsresult nsXPTCStubBase::Stub##n() \
    117     { \
    118         __asm__ __volatile__ ("mov  w17, #" #n "\n\t"  \
    119                               "b    " NAME_PREFIX_STR "CommonXPTCStub\n\t"); \
    120     }
     94    asm("BEGINCODE\n" \
     95        ".if    " #n " < 10\n" \
     96        "BEGINPROC _ZN14nsXPTCStubBase5Stub" #n "Ev\n" \
     97        ".elseif    " #n " < 100\n" \
     98        "BEGINPROC _ZN14nsXPTCStubBase6Stub" #n "Ev\n" \
     99        ".elseif    " #n " < 1000\n" \
     100        "BEGINPROC _ZN14nsXPTCStubBase7Stub" #n "Ev\n" \
     101        ".else\n" \
     102        ".err   \"stub number " #n " >= 1000 not yet supported\"\n" \
     103        ".endif\n" \
     104        "mov  w17, #" #n "\n" \
     105        "b    " NAME_PREFIX_STR "CommonXPTCStub\n" \
     106        ".if    " #n " < 10\n" \
     107        "    .size " NAME_PREFIX_STR "_ZN14nsXPTCStubBase5Stub" #n "Ev,.-" NAME_PREFIX_STR "_ZN14nsXPTCStubBase5Stub" #n "Ev\n" \
     108        ".elseif    " #n " < 100\n" \
     109        "    .size " NAME_PREFIX_STR "_ZN14nsXPTCStubBase6Stub" #n "Ev,.-" NAME_PREFIX_STR "_ZN14nsXPTCStubBase6Stub" #n "Ev\n" \
     110        ".else\n" \
     111        "    .size " NAME_PREFIX_STR "_ZN14nsXPTCStubBase7Stub" #n "Ev,.-" NAME_PREFIX_STR "_ZN14nsXPTCStubBase7Stub" #n "Ev\n" \
     112        ".endif");
    121113
    122114#define SENTINEL_ENTRY(n) \
Note: See TracChangeset for help on using the changeset viewer.

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