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>
@@ -19,11 +19,11 @@
* CDDL HEADER END
*/
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2017, Joyent, Inc. All rights reserved.
+ * Copyright 2019 Joyent, Inc.
*/
#include <sys/asm_linkage.h>
#if defined(__lint)
@@ -89,12 +89,10 @@
/*
* This file contains the stubs routines for modules which can be autoloaded.
*/
-#if defined(__amd64)
-
/*
* See the 'struct mod_modinfo' definition to see what this declaration
* is trying to achieve here.
*/
#define MODULE(module,namespace) \
@@ -128,11 +126,12 @@
leaq fcnname/**/_info(%rip), %rax; \
cmpl $0, MODS_FLAG(%rax); /* weak? */ \
je stubs_common_code; /* not weak */ \
testb $MODS_INSTALLED, MODS_FLAG(%rax); /* installed? */ \
jne stubs_common_code; /* yes, do the mod_hold */ \
- jmp *MODS_RETFCN(%rax); /* no, jump to retfcn */ \
+ movq MODS_RETFCN(%rax), %rax; /* no, load retfcn */ \
+ INDIRECT_JMP_REG(rax); /* no, jump to retfcn */ \
SET_SIZE(fcnname); \
.data; \
.align CPTRSIZE; \
.type fcnname/**/_info, @object; \
fcnname/**/_info: \
@@ -146,14 +145,16 @@
#define STUB_NO_UNLOADABLE(module, fcnname, install_fcn, retfcn, weak) \
ENTRY(fcnname); \
leaq fcnname/**/_info(%rip), %rax; \
testb $MODS_INSTALLED, MODS_FLAG(%rax); /* installed? */ \
je 5f; /* no */ \
- jmp *(%rax); /* yes, jump to install_fcn */ \
+ movq MODS_INSTFCN(%rax), %rax; /* yes, load install_fcn */ \
+ INDIRECT_JMP_REG(rax); /* yes, jump to install_fcn */ \
5: testb $MODS_WEAK, MODS_FLAG(%rax); /* weak? */ \
je stubs_common_code; /* no, do mod load */ \
- jmp *MODS_RETFCN(%rax); /* yes, jump to retfcn */ \
+ movq MODS_RETFCN(%rax), %rax; /* yes, load retfcn */ \
+ INDIRECT_JMP_REG(rax); /* yes, jump to retfcn */ \
SET_SIZE(fcnname); \
.data; \
.align CPTRSIZE; \
.type fcnname/**/_info, @object; \
fcnname/**/_info: \
@@ -188,11 +189,11 @@
movq %r15, %rdi
call mod_hold_stub /* mod_hold_stub(mod_stub_info *) */
cmpl $-1, %eax /* error? */
jne .L1
movq 0x18(%r15), %rax
- call *%rax
+ INDIRECT_CALL_REG(rax)
addq $0x30, %rsp
jmp .L2
.L1:
/*
* copy MAXNARG == 10 incoming arguments
@@ -217,11 +218,12 @@
movl $MAXNARG - 6 + 3, %r11d
pushq (%rsp, %r11, 8)
pushq (%rsp, %r11, 8)
pushq (%rsp, %r11, 8)
pushq (%rsp, %r11, 8)
- call *(%r15) /* call the stub fn(arg, ..) */
+ movq (%r15), %rax
+ INDIRECT_CALL_REG(rax) /* call the stub fn(arg, ..) */
addq $0x20, %rsp /* pop off last 4 args */
pushq %rax /* save any return values */
pushq %rdx
movq %r15, %rdi
call mod_release_stub /* release hold on module */
@@ -231,138 +233,10 @@
popq %r15
leave
ret
SET_SIZE(stubs_common_code)
-#elif defined(__i386)
-
-/*
- * See the 'struct mod_modinfo' definition to see what this declaration
- * is trying to achieve here.
- */
-#define MODULE(module,namespace) \
- .data; \
-module/**/_modname: \
- .string "namespace/module"; \
- SET_SIZE(module/**/_modname); \
- .align CPTRSIZE; \
- .globl module/**/_modinfo; \
- .type module/**/_modinfo, @object; \
-module/**/_modinfo: \
- .long module/**/_modname; \
- .long 0 /* storage for modctl pointer */
-
- /* then mod_stub_info structures follow until a mods_func_adr is 0 */
-
-/* this puts a 0 where the next mods_func_adr would be */
-#define END_MODULE(module) \
- .data; \
- .align CPTRSIZE; \
- .long 0; \
- SET_SIZE(module/**/_modinfo)
-
-/*
- * The data section in the stub_common macro is the
- * mod_stub_info structure for the stub function
- */
-
-/*
- * The flag MODS_INSTALLED is stored in the stub data and is used to
- * indicate if a module is installed and initialized. This flag is used
- * instead of the mod_stub_info->mods_modinfo->mod_installed flag
- * to minimize the number of pointer de-references for each function
- * call (and also to avoid possible TLB misses which could be induced
- * by dereferencing these pointers.)
- */
-
-#define STUB_COMMON(module, fcnname, install_fcn, retfcn, weak) \
- ENTRY(fcnname); \
- leal fcnname/**/_info, %eax; \
- cmpl $0, MODS_FLAG(%eax); /* weak? */ \
- je stubs_common_code; /* not weak */ \
- testb $MODS_INSTALLED, MODS_FLAG(%eax); /* installed? */ \
- jne stubs_common_code; /* yes, do the mod_hold */ \
- jmp *MODS_RETFCN(%eax); /* no, just jump to retfcn */ \
- SET_SIZE(fcnname); \
- .data; \
- .align CPTRSIZE; \
- .type fcnname/**/_info, @object; \
-fcnname/**/_info: \
- .long install_fcn; \
- .long module/**/_modinfo; \
- .long fcnname; \
- .long retfcn; \
- .long weak; \
- SET_SIZE(fcnname/**/_info)
-
-#define STUB_NO_UNLOADABLE(module, fcnname, install_fcn, retfcn, weak) \
- ENTRY(fcnname); \
- leal fcnname/**/_info, %eax; \
- testb $MODS_INSTALLED, MODS_FLAG(%eax); /* installed? */ \
- je 5f; /* no */ \
- jmp *(%eax); /* yes, just jump to install_fcn */ \
-5: testb $MODS_WEAK, MODS_FLAG(%eax); /* weak? */ \
- je stubs_common_code; /* no, do mod load */ \
- jmp *MODS_RETFCN(%eax); /* yes, just jump to retfcn */ \
- SET_SIZE(fcnname); \
- .data; \
- .align CPTRSIZE; \
- .type fcnname/**/_info, @object; \
-fcnname/**/_info: \
- .long install_fcn; /* 0 */ \
- .long module/**/_modinfo; /* 0x4 */ \
- .long fcnname; /* 0x8 */ \
- .long retfcn; /* 0xc */ \
- .long weak; /* 0x10 */ \
- SET_SIZE(fcnname/**/_info)
-
-/*
- * We branch here with the fcnname_info pointer in %eax
- */
- ENTRY_NP(stubs_common_code)
- .globl mod_hold_stub
- .globl mod_release_stub
- pushl %esi
- movl %eax, %esi / save the info pointer
- pushl %eax
- call mod_hold_stub / mod_hold_stub(mod_stub_info *)
- popl %ecx
- cmpl $-1, %eax / error?
- jne .L1
- movl MODS_RETFCN(%esi), %eax
- call *%eax
- popl %esi / yes, return error (panic?)
- ret
-.L1:
- movl $MAXNARG+1, %ecx
- / copy incoming arguments
- pushl (%esp, %ecx, 4) / push MAXNARG times
- pushl (%esp, %ecx, 4)
- pushl (%esp, %ecx, 4)
- pushl (%esp, %ecx, 4)
- pushl (%esp, %ecx, 4)
- pushl (%esp, %ecx, 4)
- pushl (%esp, %ecx, 4)
- pushl (%esp, %ecx, 4)
- pushl (%esp, %ecx, 4)
- pushl (%esp, %ecx, 4)
- call *(%esi) / call the stub function(arg1,arg2, ...)
- add $_MUL(MAXNARG, 4), %esp / pop off MAXNARG arguments
- pushl %eax / save any return values from the stub
- pushl %edx
- pushl %esi
- call mod_release_stub / release hold on module
- addl $4, %esp
- popl %edx / restore return values
- popl %eax
-.L2:
- popl %esi
- ret
- SET_SIZE(stubs_common_code)
-
-#endif /* __i386 */
-
#define STUB(module, fcnname, retfcn) \
STUB_COMMON(module, fcnname, mod_hold_stub, retfcn, 0)
/*
* "weak stub", don't load on account of this call
@@ -1408,14 +1282,12 @@
*/
#ifndef ELFEXEC_MODULE
MODULE(elfexec,exec);
STUB(elfexec, elfexec, nomod_einval);
STUB(elfexec, mapexec_brand, nomod_einval);
-#if defined(__amd64)
STUB(elfexec, elf32exec, nomod_einval);
STUB(elfexec, mapexec32_brand, nomod_einval);
-#endif
END_MODULE(elfexec);
#endif
/*
* Stub(s) for APIX module.
@@ -1424,11 +1296,13 @@
MODULE(apix,mach);
WSTUB(apix, apix_loaded, nomod_zero);
END_MODULE(apix);
#endif
-/ this is just a marker for the area of text that contains stubs
+/*
+ * this is just a marker for the area of text that contains stubs
+ */
ENTRY_NP(stubs_end)
nop
#endif /* lint */