Print this page
11787 Kernel needs to be built with retpolines
11788 Kernel needs to generally use RSB stuffing
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: John Levon <john.levon@joyent.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2017, Joyent, Inc. All rights reserved.
  25  */
  26 
  27 #include <sys/asm_linkage.h>
  28 
  29 #if defined(__lint)
  30 
  31 char stubs_base[1], stubs_end[1];
  32 
  33 #else   /* __lint */
  34 
  35 #include "assym.h"
  36 
  37 /*
  38  * !!!!!!!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!!!!!!
  39  *
  40  *      For functions which are either STUBs or WSTUBs the actual function
  41  *      need to be called using 'call' instruction because of preamble and
  42  *      postamble (i.e mod_hold_stub and mod_release_stub) around the
  43  *      function call. Due to this we need to copy arguments for the
  44  *      real function. On Intel we can't tell how many arguments are there


  74  * The old version is
  75  *      #define mac(a) "a"
  76  *
  77  * For some reason, the 5.0 preprocessor isn't happy with the above usage.
  78  * For now, we're not using these ansi features.
  79  *
  80  * The reason is that "the 5.0 ANSI preprocessor" is built into the compiler
  81  * and is a tokenizing preprocessor. This means, when confronted by something
  82  * other than C token generation rules, strange things occur. In this case,
  83  * when confronted by an assembly file, it would turn the token ".globl" into
  84  * two tokens "." and "globl". For this reason, the traditional, non-ANSI
  85  * preprocessor is used on assembly files.
  86  *
  87  * It would be desirable to have a non-tokenizing cpp (accp?) to use for this.
  88  */
  89 
  90 /*
  91  * This file contains the stubs routines for modules which can be autoloaded.
  92  */
  93 
  94 #if defined(__amd64)
  95 
  96 /*
  97  * See the 'struct mod_modinfo' definition to see what this declaration
  98  * is trying to achieve here.
  99  */
 100 #define MODULE(module,namespace)        \
 101         .data;                          \
 102 module/**/_modname:                     \
 103         .string "namespace/module";     \
 104         SET_SIZE(module/**/_modname);   \
 105         .align  CPTRSIZE;               \
 106         .globl  module/**/_modinfo;     \
 107         .type   module/**/_modinfo, @object;    \
 108 module/**/_modinfo:                     \
 109         .quad   module/**/_modname;     \
 110         .quad   0       /* storage for modctl pointer */
 111 
 112         /* then mod_stub_info structures follow until a mods_func_adr is 0 */
 113 
 114 /* this puts a 0 where the next mods_func_adr would be */
 115 #define END_MODULE(module)              \
 116         .data;                          \
 117         .align  CPTRSIZE;               \
 118         .quad 0;                        \
 119         SET_SIZE(module/**/_modinfo)
 120 
 121 /*
 122  * The data section in the stub_common macro is the
 123  * mod_stub_info structure for the stub function
 124  */
 125 
 126 #define STUB_COMMON(module, fcnname, install_fcn, retfcn, weak)         \
 127         ENTRY(fcnname);                                                 \
 128         leaq    fcnname/**/_info(%rip), %rax;                           \
 129         cmpl    $0, MODS_FLAG(%rax);                    /* weak? */     \
 130         je      stubs_common_code;                      /* not weak */  \
 131         testb   $MODS_INSTALLED, MODS_FLAG(%rax);       /* installed? */ \
 132         jne     stubs_common_code;              /* yes, do the mod_hold */ \
 133         jmp     *MODS_RETFCN(%rax);             /* no, jump to retfcn */ \

 134         SET_SIZE(fcnname);                                              \
 135         .data;                                                          \
 136         .align   CPTRSIZE;                                              \
 137         .type   fcnname/**/_info, @object;                              \
 138 fcnname/**/_info:                                                       \
 139         .quad   install_fcn;            /* 0 */                         \
 140         .quad   module/**/_modinfo;     /* 0x8 */                       \
 141         .quad   fcnname;                /* 0x10 */                      \
 142         .quad   retfcn;                 /* 0x18 */                      \
 143         .long   weak;                   /* 0x20 */                      \
 144         SET_SIZE(fcnname/**/_info)
 145 
 146 #define STUB_NO_UNLOADABLE(module, fcnname, install_fcn, retfcn, weak)  \
 147         ENTRY(fcnname);                                                 \
 148         leaq    fcnname/**/_info(%rip), %rax;                           \
 149         testb   $MODS_INSTALLED, MODS_FLAG(%rax); /* installed? */      \
 150         je      5f;                     /* no */                        \
 151         jmp     *(%rax);                /* yes, jump to install_fcn */  \

 152 5:      testb   $MODS_WEAK, MODS_FLAG(%rax);    /* weak? */             \
 153         je      stubs_common_code;      /* no, do mod load */           \
 154         jmp     *MODS_RETFCN(%rax);     /* yes, jump to retfcn */       \

 155         SET_SIZE(fcnname);                                              \
 156         .data;                                                          \
 157         .align  CPTRSIZE;                                               \
 158         .type   fcnname/**/_info, @object;                              \
 159 fcnname/**/_info:                                                       \
 160         .quad   install_fcn;            /* 0 */                         \
 161         .quad   module/**/_modinfo;     /* 0x8 */                       \
 162         .quad   fcnname;                /* 0x10 */                      \
 163         .quad   retfcn;                 /* 0x18 */                      \
 164         .long   weak;                   /* 0x20 */                      \
 165         SET_SIZE(fcnname/**/_info)
 166 
 167 /*
 168  * We branch here with the fcnname_info pointer in %rax
 169  */
 170         ENTRY_NP(stubs_common_code)
 171         .globl  mod_hold_stub
 172         .globl  mod_release_stub
 173         pushq   %rbp
 174         movq    %rsp, %rbp
 175         subq    $0x10, %rsp
 176         movq    %r15, (%rsp)            /* (caller saved) */
 177         movq    %rax, %r15              /* stash the fcnname_info pointer */
 178         /*
 179          * save incoming register arguments
 180          */
 181         pushq   %rdi
 182         pushq   %rsi
 183         pushq   %rdx
 184         pushq   %rcx
 185         pushq   %r8
 186         pushq   %r9
 187         /* (next 4 args, if any, are already on the stack above %rbp) */
 188         movq    %r15, %rdi
 189         call    mod_hold_stub           /* mod_hold_stub(mod_stub_info *) */
 190         cmpl    $-1, %eax               /* error? */
 191         jne     .L1
 192         movq    0x18(%r15), %rax
 193         call    *%rax
 194         addq    $0x30, %rsp
 195         jmp     .L2
 196 .L1:
 197         /*
 198          * copy MAXNARG == 10 incoming arguments
 199          */
 200         popq    %r9
 201         popq    %r8
 202         popq    %rcx
 203         popq    %rdx
 204         popq    %rsi
 205         popq    %rdi
 206         /*
 207          * stack:
 208          *      arg9            0x38(%rsp)
 209          *      arg8            0x30(%rsp)
 210          *      arg7            0x28(%rsp)
 211          *      arg6            0x20(%rsp)
 212          *      saved %rip      0x18(%rsp)
 213          *      saved %rbp      0x10(%rsp)
 214          *      <pad>             0x8(%rsp)
 215          *      saved %r15      0x0(%rsp)
 216          */
 217         movl    $MAXNARG - 6 + 3, %r11d
 218         pushq   (%rsp, %r11, 8)
 219         pushq   (%rsp, %r11, 8)
 220         pushq   (%rsp, %r11, 8)
 221         pushq   (%rsp, %r11, 8)
 222         call    *(%r15)                 /* call the stub fn(arg, ..) */

 223         addq    $0x20, %rsp             /* pop off last 4 args */
 224         pushq   %rax                    /* save any return values */
 225         pushq   %rdx
 226         movq    %r15, %rdi
 227         call    mod_release_stub        /* release hold on module */
 228         popq    %rdx                    /* restore return values */
 229         popq    %rax
 230 .L2:
 231         popq    %r15
 232         leave
 233         ret
 234         SET_SIZE(stubs_common_code)
 235 
 236 #elif defined(__i386)
 237 
 238 /*
 239  * See the 'struct mod_modinfo' definition to see what this declaration
 240  * is trying to achieve here.
 241  */
 242 #define MODULE(module,namespace)        \
 243         .data;                          \
 244 module/**/_modname:                     \
 245         .string "namespace/module";     \
 246         SET_SIZE(module/**/_modname);   \
 247         .align  CPTRSIZE;               \
 248         .globl  module/**/_modinfo;     \
 249         .type   module/**/_modinfo, @object;    \
 250 module/**/_modinfo:                     \
 251         .long   module/**/_modname;     \
 252         .long   0       /* storage for modctl pointer */
 253 
 254         /* then mod_stub_info structures follow until a mods_func_adr is 0 */
 255 
 256 /* this puts a 0 where the next mods_func_adr would be */
 257 #define END_MODULE(module)              \
 258         .data;                          \
 259         .align  CPTRSIZE;               \
 260         .long 0;                        \
 261         SET_SIZE(module/**/_modinfo)
 262 
 263 /*
 264  * The data section in the stub_common macro is the
 265  * mod_stub_info structure for the stub function
 266  */
 267 
 268 /*      
 269  * The flag MODS_INSTALLED is stored in the stub data and is used to
 270  * indicate if a module is installed and initialized.  This flag is used
 271  * instead of the mod_stub_info->mods_modinfo->mod_installed flag
 272  * to minimize the number of pointer de-references for each function
 273  * call (and also to avoid possible TLB misses which could be induced
 274  * by dereferencing these pointers.)
 275  */     
 276 
 277 #define STUB_COMMON(module, fcnname, install_fcn, retfcn, weak)         \
 278         ENTRY(fcnname);                                                 \
 279         leal    fcnname/**/_info, %eax;                                 \
 280         cmpl    $0, MODS_FLAG(%eax);    /* weak? */                     \
 281         je      stubs_common_code;      /* not weak */                  \
 282         testb   $MODS_INSTALLED, MODS_FLAG(%eax); /* installed? */      \
 283         jne     stubs_common_code;      /* yes, do the mod_hold */      \
 284         jmp     *MODS_RETFCN(%eax);     /* no, just jump to retfcn */   \
 285         SET_SIZE(fcnname);                                              \
 286         .data;                                                          \
 287         .align   CPTRSIZE;                                              \
 288         .type   fcnname/**/_info, @object;                              \
 289 fcnname/**/_info:                                                       \
 290         .long   install_fcn;                                            \
 291         .long   module/**/_modinfo;                                     \
 292         .long   fcnname;                                                \
 293         .long   retfcn;                                                 \
 294         .long   weak;                                                   \
 295         SET_SIZE(fcnname/**/_info)
 296         
 297 #define STUB_NO_UNLOADABLE(module, fcnname, install_fcn, retfcn, weak)  \
 298         ENTRY(fcnname);                                                 \
 299         leal    fcnname/**/_info, %eax;                                 \
 300         testb   $MODS_INSTALLED, MODS_FLAG(%eax); /* installed? */      \
 301         je      5f;             /* no */                                \
 302         jmp     *(%eax);        /* yes, just jump to install_fcn */     \
 303 5:      testb   $MODS_WEAK, MODS_FLAG(%eax);    /* weak? */             \
 304         je      stubs_common_code;      /* no, do mod load */           \
 305         jmp     *MODS_RETFCN(%eax);     /* yes, just jump to retfcn */  \
 306         SET_SIZE(fcnname);                                              \
 307         .data;                                                          \
 308         .align  CPTRSIZE;                                               \
 309         .type   fcnname/**/_info, @object;                              \
 310 fcnname/**/_info:                                                       \
 311         .long   install_fcn;            /* 0 */                         \
 312         .long   module/**/_modinfo;     /* 0x4 */                       \
 313         .long   fcnname;                /* 0x8 */                       \
 314         .long   retfcn;                 /* 0xc */                       \
 315         .long   weak;                   /* 0x10 */                      \
 316         SET_SIZE(fcnname/**/_info)
 317 
 318 /*
 319  * We branch here with the fcnname_info pointer in %eax
 320  */
 321         ENTRY_NP(stubs_common_code)
 322         .globl  mod_hold_stub
 323         .globl  mod_release_stub
 324         pushl   %esi
 325         movl    %eax, %esi              / save the info pointer
 326         pushl   %eax
 327         call    mod_hold_stub           / mod_hold_stub(mod_stub_info *)
 328         popl    %ecx
 329         cmpl    $-1, %eax               / error?
 330         jne     .L1
 331         movl    MODS_RETFCN(%esi), %eax
 332         call    *%eax   
 333         popl    %esi                    / yes, return error (panic?)
 334         ret
 335 .L1:
 336         movl    $MAXNARG+1, %ecx
 337         / copy incoming arguments
 338         pushl   (%esp, %ecx, 4)         / push MAXNARG times
 339         pushl   (%esp, %ecx, 4)
 340         pushl   (%esp, %ecx, 4)
 341         pushl   (%esp, %ecx, 4)
 342         pushl   (%esp, %ecx, 4)
 343         pushl   (%esp, %ecx, 4)
 344         pushl   (%esp, %ecx, 4)
 345         pushl   (%esp, %ecx, 4)
 346         pushl   (%esp, %ecx, 4)
 347         pushl   (%esp, %ecx, 4)
 348         call    *(%esi)                 / call the stub function(arg1,arg2, ...)
 349         add     $_MUL(MAXNARG, 4), %esp / pop off MAXNARG arguments
 350         pushl   %eax                    / save any return values from the stub
 351         pushl   %edx
 352         pushl   %esi
 353         call    mod_release_stub        / release hold on module
 354         addl    $4, %esp
 355         popl    %edx                    / restore return values
 356         popl    %eax
 357 .L2:
 358         popl    %esi
 359         ret
 360         SET_SIZE(stubs_common_code)
 361 
 362 #endif  /* __i386 */
 363 
 364 #define STUB(module, fcnname, retfcn)   \
 365     STUB_COMMON(module, fcnname, mod_hold_stub, retfcn, 0)
 366 
 367 /*
 368  * "weak stub", don't load on account of this call
 369  */
 370 #define WSTUB(module, fcnname, retfcn)  \
 371     STUB_COMMON(module, fcnname, retfcn, retfcn, MODS_WEAK)
 372 
 373 /*
 374  * "non-unloadable stub", don't bother 'holding' module if it's already loaded
 375  * since the module cannot be unloaded.
 376  *
 377  * User *MUST* guarantee the module is not unloadable (no _fini routine).
 378  */
 379 #define NO_UNLOAD_STUB(module, fcnname, retfcn) \
 380     STUB_NO_UNLOADABLE(module, fcnname,  retfcn, retfcn, MODS_NOUNLOAD)
 381 
 382 /*
 383  * "weak stub" for non-unloadable module, don't load on account of this call


1393         NO_UNLOAD_STUB(ksocket, ksocket_recvmsg, nomod_minus_one);
1394         NO_UNLOAD_STUB(ksocket, ksocket_send, nomod_minus_one);
1395         NO_UNLOAD_STUB(ksocket, ksocket_sendto, nomod_minus_one);
1396         NO_UNLOAD_STUB(ksocket, ksocket_sendmsg, nomod_minus_one);
1397         NO_UNLOAD_STUB(ksocket, ksocket_ioctl, nomod_minus_one);
1398         NO_UNLOAD_STUB(ksocket, ksocket_setcallbacks, nomod_minus_one);
1399         NO_UNLOAD_STUB(ksocket, ksocket_hold, nomod_minus_one);
1400         NO_UNLOAD_STUB(ksocket, ksocket_rele, nomod_minus_one);
1401         NO_UNLOAD_STUB(ksocket, ksocket_shutdown, nomod_minus_one);
1402         NO_UNLOAD_STUB(ksocket, ksocket_close, nomod_minus_one);
1403         END_MODULE(ksocket);
1404 #endif
1405 
1406 /*
1407  * Stubs for elfexec
1408  */
1409 #ifndef ELFEXEC_MODULE
1410         MODULE(elfexec,exec);
1411         STUB(elfexec, elfexec,          nomod_einval);
1412         STUB(elfexec, mapexec_brand,    nomod_einval);
1413 #if defined(__amd64)
1414         STUB(elfexec, elf32exec,        nomod_einval);
1415         STUB(elfexec, mapexec32_brand,  nomod_einval);
1416 #endif
1417         END_MODULE(elfexec);
1418 #endif
1419 
1420 /*
1421  * Stub(s) for APIX module.
1422  */
1423 #ifndef APIX_MODULE
1424         MODULE(apix,mach);
1425         WSTUB(apix, apix_loaded, nomod_zero);
1426         END_MODULE(apix);
1427 #endif
1428 
1429 / this is just a marker for the area of text that contains stubs 


1430 
1431         ENTRY_NP(stubs_end)
1432         nop
1433 
1434 #endif  /* lint */


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2019 Joyent, Inc.
  25  */
  26 
  27 #include <sys/asm_linkage.h>
  28 
  29 #if defined(__lint)
  30 
  31 char stubs_base[1], stubs_end[1];
  32 
  33 #else   /* __lint */
  34 
  35 #include "assym.h"
  36 
  37 /*
  38  * !!!!!!!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!!!!!!
  39  *
  40  *      For functions which are either STUBs or WSTUBs the actual function
  41  *      need to be called using 'call' instruction because of preamble and
  42  *      postamble (i.e mod_hold_stub and mod_release_stub) around the
  43  *      function call. Due to this we need to copy arguments for the
  44  *      real function. On Intel we can't tell how many arguments are there


  74  * The old version is
  75  *      #define mac(a) "a"
  76  *
  77  * For some reason, the 5.0 preprocessor isn't happy with the above usage.
  78  * For now, we're not using these ansi features.
  79  *
  80  * The reason is that "the 5.0 ANSI preprocessor" is built into the compiler
  81  * and is a tokenizing preprocessor. This means, when confronted by something
  82  * other than C token generation rules, strange things occur. In this case,
  83  * when confronted by an assembly file, it would turn the token ".globl" into
  84  * two tokens "." and "globl". For this reason, the traditional, non-ANSI
  85  * preprocessor is used on assembly files.
  86  *
  87  * It would be desirable to have a non-tokenizing cpp (accp?) to use for this.
  88  */
  89 
  90 /*
  91  * This file contains the stubs routines for modules which can be autoloaded.
  92  */
  93 


  94 /*
  95  * See the 'struct mod_modinfo' definition to see what this declaration
  96  * is trying to achieve here.
  97  */
  98 #define MODULE(module,namespace)        \
  99         .data;                          \
 100 module/**/_modname:                     \
 101         .string "namespace/module";     \
 102         SET_SIZE(module/**/_modname);   \
 103         .align  CPTRSIZE;               \
 104         .globl  module/**/_modinfo;     \
 105         .type   module/**/_modinfo, @object;    \
 106 module/**/_modinfo:                     \
 107         .quad   module/**/_modname;     \
 108         .quad   0       /* storage for modctl pointer */
 109 
 110         /* then mod_stub_info structures follow until a mods_func_adr is 0 */
 111 
 112 /* this puts a 0 where the next mods_func_adr would be */
 113 #define END_MODULE(module)              \
 114         .data;                          \
 115         .align  CPTRSIZE;               \
 116         .quad 0;                        \
 117         SET_SIZE(module/**/_modinfo)
 118 
 119 /*
 120  * The data section in the stub_common macro is the
 121  * mod_stub_info structure for the stub function
 122  */
 123 
 124 #define STUB_COMMON(module, fcnname, install_fcn, retfcn, weak)         \
 125         ENTRY(fcnname);                                                 \
 126         leaq    fcnname/**/_info(%rip), %rax;                           \
 127         cmpl    $0, MODS_FLAG(%rax);                    /* weak? */     \
 128         je      stubs_common_code;                      /* not weak */  \
 129         testb   $MODS_INSTALLED, MODS_FLAG(%rax);       /* installed? */ \
 130         jne     stubs_common_code;              /* yes, do the mod_hold */ \
 131         movq    MODS_RETFCN(%rax), %rax;        /* no, load retfcn */   \
 132         INDIRECT_JMP_REG(rax);                  /* no, jump to retfcn */ \
 133         SET_SIZE(fcnname);                                              \
 134         .data;                                                          \
 135         .align   CPTRSIZE;                                              \
 136         .type   fcnname/**/_info, @object;                              \
 137 fcnname/**/_info:                                                       \
 138         .quad   install_fcn;            /* 0 */                         \
 139         .quad   module/**/_modinfo;     /* 0x8 */                       \
 140         .quad   fcnname;                /* 0x10 */                      \
 141         .quad   retfcn;                 /* 0x18 */                      \
 142         .long   weak;                   /* 0x20 */                      \
 143         SET_SIZE(fcnname/**/_info)
 144 
 145 #define STUB_NO_UNLOADABLE(module, fcnname, install_fcn, retfcn, weak)  \
 146         ENTRY(fcnname);                                                 \
 147         leaq    fcnname/**/_info(%rip), %rax;                           \
 148         testb   $MODS_INSTALLED, MODS_FLAG(%rax); /* installed? */      \
 149         je      5f;                     /* no */                        \
 150         movq    MODS_INSTFCN(%rax), %rax; /* yes, load install_fcn */   \
 151         INDIRECT_JMP_REG(rax);          /* yes, jump to install_fcn */  \
 152 5:      testb   $MODS_WEAK, MODS_FLAG(%rax);    /* weak? */             \
 153         je      stubs_common_code;      /* no, do mod load */           \
 154         movq    MODS_RETFCN(%rax), %rax; /* yes, load retfcn */         \
 155         INDIRECT_JMP_REG(rax);          /* yes, jump to retfcn */       \
 156         SET_SIZE(fcnname);                                              \
 157         .data;                                                          \
 158         .align  CPTRSIZE;                                               \
 159         .type   fcnname/**/_info, @object;                              \
 160 fcnname/**/_info:                                                       \
 161         .quad   install_fcn;            /* 0 */                         \
 162         .quad   module/**/_modinfo;     /* 0x8 */                       \
 163         .quad   fcnname;                /* 0x10 */                      \
 164         .quad   retfcn;                 /* 0x18 */                      \
 165         .long   weak;                   /* 0x20 */                      \
 166         SET_SIZE(fcnname/**/_info)
 167 
 168 /*
 169  * We branch here with the fcnname_info pointer in %rax
 170  */
 171         ENTRY_NP(stubs_common_code)
 172         .globl  mod_hold_stub
 173         .globl  mod_release_stub
 174         pushq   %rbp
 175         movq    %rsp, %rbp
 176         subq    $0x10, %rsp
 177         movq    %r15, (%rsp)            /* (caller saved) */
 178         movq    %rax, %r15              /* stash the fcnname_info pointer */
 179         /*
 180          * save incoming register arguments
 181          */
 182         pushq   %rdi
 183         pushq   %rsi
 184         pushq   %rdx
 185         pushq   %rcx
 186         pushq   %r8
 187         pushq   %r9
 188         /* (next 4 args, if any, are already on the stack above %rbp) */
 189         movq    %r15, %rdi
 190         call    mod_hold_stub           /* mod_hold_stub(mod_stub_info *) */
 191         cmpl    $-1, %eax               /* error? */
 192         jne     .L1
 193         movq    0x18(%r15), %rax
 194         INDIRECT_CALL_REG(rax)
 195         addq    $0x30, %rsp
 196         jmp     .L2
 197 .L1:
 198         /*
 199          * copy MAXNARG == 10 incoming arguments
 200          */
 201         popq    %r9
 202         popq    %r8
 203         popq    %rcx
 204         popq    %rdx
 205         popq    %rsi
 206         popq    %rdi
 207         /*
 208          * stack:
 209          *      arg9            0x38(%rsp)
 210          *      arg8            0x30(%rsp)
 211          *      arg7            0x28(%rsp)
 212          *      arg6            0x20(%rsp)
 213          *      saved %rip      0x18(%rsp)
 214          *      saved %rbp      0x10(%rsp)
 215          *      <pad>             0x8(%rsp)
 216          *      saved %r15      0x0(%rsp)
 217          */
 218         movl    $MAXNARG - 6 + 3, %r11d
 219         pushq   (%rsp, %r11, 8)
 220         pushq   (%rsp, %r11, 8)
 221         pushq   (%rsp, %r11, 8)
 222         pushq   (%rsp, %r11, 8)
 223         movq    (%r15), %rax
 224         INDIRECT_CALL_REG(rax)          /* call the stub fn(arg, ..) */
 225         addq    $0x20, %rsp             /* pop off last 4 args */
 226         pushq   %rax                    /* save any return values */
 227         pushq   %rdx
 228         movq    %r15, %rdi
 229         call    mod_release_stub        /* release hold on module */
 230         popq    %rdx                    /* restore return values */
 231         popq    %rax
 232 .L2:
 233         popq    %r15
 234         leave
 235         ret
 236         SET_SIZE(stubs_common_code)
 237 
































































































































 238 #define STUB(module, fcnname, retfcn)   \
 239     STUB_COMMON(module, fcnname, mod_hold_stub, retfcn, 0)
 240 
 241 /*
 242  * "weak stub", don't load on account of this call
 243  */
 244 #define WSTUB(module, fcnname, retfcn)  \
 245     STUB_COMMON(module, fcnname, retfcn, retfcn, MODS_WEAK)
 246 
 247 /*
 248  * "non-unloadable stub", don't bother 'holding' module if it's already loaded
 249  * since the module cannot be unloaded.
 250  *
 251  * User *MUST* guarantee the module is not unloadable (no _fini routine).
 252  */
 253 #define NO_UNLOAD_STUB(module, fcnname, retfcn) \
 254     STUB_NO_UNLOADABLE(module, fcnname,  retfcn, retfcn, MODS_NOUNLOAD)
 255 
 256 /*
 257  * "weak stub" for non-unloadable module, don't load on account of this call


1267         NO_UNLOAD_STUB(ksocket, ksocket_recvmsg, nomod_minus_one);
1268         NO_UNLOAD_STUB(ksocket, ksocket_send, nomod_minus_one);
1269         NO_UNLOAD_STUB(ksocket, ksocket_sendto, nomod_minus_one);
1270         NO_UNLOAD_STUB(ksocket, ksocket_sendmsg, nomod_minus_one);
1271         NO_UNLOAD_STUB(ksocket, ksocket_ioctl, nomod_minus_one);
1272         NO_UNLOAD_STUB(ksocket, ksocket_setcallbacks, nomod_minus_one);
1273         NO_UNLOAD_STUB(ksocket, ksocket_hold, nomod_minus_one);
1274         NO_UNLOAD_STUB(ksocket, ksocket_rele, nomod_minus_one);
1275         NO_UNLOAD_STUB(ksocket, ksocket_shutdown, nomod_minus_one);
1276         NO_UNLOAD_STUB(ksocket, ksocket_close, nomod_minus_one);
1277         END_MODULE(ksocket);
1278 #endif
1279 
1280 /*
1281  * Stubs for elfexec
1282  */
1283 #ifndef ELFEXEC_MODULE
1284         MODULE(elfexec,exec);
1285         STUB(elfexec, elfexec,          nomod_einval);
1286         STUB(elfexec, mapexec_brand,    nomod_einval);

1287         STUB(elfexec, elf32exec,        nomod_einval);
1288         STUB(elfexec, mapexec32_brand,  nomod_einval);

1289         END_MODULE(elfexec);
1290 #endif
1291 
1292 /*
1293  * Stub(s) for APIX module.
1294  */
1295 #ifndef APIX_MODULE
1296         MODULE(apix,mach);
1297         WSTUB(apix, apix_loaded, nomod_zero);
1298         END_MODULE(apix);
1299 #endif
1300 
1301 /*
1302  * this is just a marker for the area of text that contains stubs
1303  */
1304 
1305         ENTRY_NP(stubs_end)
1306         nop
1307 
1308 #endif  /* lint */