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
45 * on the stack so we have to either copy everything between esp and
46 * ebp or copy only a fixed number (MAXNARG - defined here) for
47 * all the stub functions. Currently we are using MAXNARG (it is a kludge
48 * but worth it?!).
49 *
50 * NOTE: Use NO_UNLOAD_STUBs if the module is NOT unloadable once it is
51 * loaded.
52 */
53 #define MAXNARG 10
54
55 /*
56 * WARNING: there is no check for forgetting to write END_MODULE,
57 * and if you do, the kernel will most likely crash. Be careful
58 *
59 * This file assumes that all of the contributions to the data segment
60 * will be contiguous in the output file, even though they are separated
61 * by pieces of text. This is safe for all assemblers I know of now...
62 */
63
64 /*
65 * This file uses ansi preprocessor features:
66 *
67 * 1. #define mac(a) extra_ ## a --> mac(x) expands to extra_a
68 * The old version of this is
69 * #define mac(a) extra_/.*.*./a
70 * but this fails if the argument has spaces "mac ( x )"
71 * (Ignore the dots above, I had to put them in to keep this a comment.)
72 *
73 * 2. #define mac(a) #a --> mac(x) expands to "x"
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; \
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)
|
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
45 * on the stack so we have to either copy everything between esp and
46 * ebp or copy only a fixed number (MAXNARG - defined here) for
47 * all the stub functions. Currently we are using MAXNARG (it is a kludge
48 * but worth it?!).
49 *
50 * NOTE: Use NO_UNLOAD_STUBs if the module is NOT unloadable once it is
51 * loaded.
52 */
53 #define MAXNARG 12
54
55 /*
56 * WARNING: there is no check for forgetting to write END_MODULE,
57 * and if you do, the kernel will most likely crash. Be careful
58 *
59 * This file assumes that all of the contributions to the data segment
60 * will be contiguous in the output file, even though they are separated
61 * by pieces of text. This is safe for all assemblers I know of now...
62 */
63
64 /*
65 * This file uses ansi preprocessor features:
66 *
67 * 1. #define mac(a) extra_ ## a --> mac(x) expands to extra_a
68 * The old version of this is
69 * #define mac(a) extra_/.*.*./a
70 * but this fails if the argument has spaces "mac ( x )"
71 * (Ignore the dots above, I had to put them in to keep this a comment.)
72 *
73 * 2. #define mac(a) #a --> mac(x) expands to "x"
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 6 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 == 12 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 pushq (%rsp, %r11, 8)
223 pushq (%rsp, %r11, 8)
224 call *(%r15) /* call the stub fn(arg, ..) */
225 addq $0x30, %rsp /* pop off last 6 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 #elif defined(__i386)
239
240 /*
241 * See the 'struct mod_modinfo' definition to see what this declaration
242 * is trying to achieve here.
243 */
244 #define MODULE(module,namespace) \
245 .data; \
323 ENTRY_NP(stubs_common_code)
324 .globl mod_hold_stub
325 .globl mod_release_stub
326 pushl %esi
327 movl %eax, %esi / save the info pointer
328 pushl %eax
329 call mod_hold_stub / mod_hold_stub(mod_stub_info *)
330 popl %ecx
331 cmpl $-1, %eax / error?
332 jne .L1
333 movl MODS_RETFCN(%esi), %eax
334 call *%eax
335 popl %esi / yes, return error (panic?)
336 ret
337 .L1:
338 movl $MAXNARG+1, %ecx
339 / copy incoming arguments
340 pushl (%esp, %ecx, 4) / push MAXNARG times
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 pushl (%esp, %ecx, 4)
349 pushl (%esp, %ecx, 4)
350 pushl (%esp, %ecx, 4)
351 pushl (%esp, %ecx, 4)
352 call *(%esi) / call the stub function(arg1,arg2, ...)
353 add $_MUL(MAXNARG, 4), %esp / pop off MAXNARG arguments
354 pushl %eax / save any return values from the stub
355 pushl %edx
356 pushl %esi
357 call mod_release_stub / release hold on module
358 addl $4, %esp
359 popl %edx / restore return values
360 popl %eax
361 .L2:
362 popl %esi
363 ret
364 SET_SIZE(stubs_common_code)
|