219 * not, we jump back into the normal syscall path and pretend
220 * nothing happened. %l1 contains the syscall we're invoking.
221 */
222 set XXX_emulation_table, %g3;
223 ldn [%g3], %g3;
224 add %g3, %l1, %g3;
225 ldub [%g3], %g3;
226 brz %g3, _exit;
227 nop;
228
229 /*
230 * Find the address of the userspace handler.
231 * cpu->cpu_thread->t_procp->p_brand_data->spd_handler.
232 */
233 #if defined(sun4v)
234 /* restore the alternate global registers after incrementing %gl */
235 mov %l3, %g2;
236 #endif /* sun4v */
237 ldn [%g2 + CPU_THREAD], %g3; /* get thread ptr */
238 ldn [%g3 + T_PROCP], %g4; /* get proc ptr */
239 ldn [%g4 + P_BRAND_DATA], %g5; /* get brand data ptr */
240 ldn [%g5 + SPD_HANDLER], %g5; /* get userland brnd hdlr ptr */
241 brz %g5, _exit; /* has it been set? */
242 nop;
243
244 /*
245 * Make sure this isn't an agent lwp. We can't do syscall
246 * interposition for system calls made by a agent lwp. See
247 * the block comments in the top of the brand emulation library
248 * for more information.
249 */
250 ldn [%g4 + P_AGENTTP], %g4; /* get agent thread ptr */
251 cmp %g3, %g4; /* is this an agent thread? */
252 be,pn %xcc, _exit; /* if so don't emulate */
253 nop;
254
255 /*
256 * Now the magic happens. Grab the trap return address and then
257 * reset it to point to the user space handler. When we execute
258 * the 'done' instruction, we will jump into our handler instead of
259 * the user's code. We also stick the old return address in %g5,
|
219 * not, we jump back into the normal syscall path and pretend
220 * nothing happened. %l1 contains the syscall we're invoking.
221 */
222 set XXX_emulation_table, %g3;
223 ldn [%g3], %g3;
224 add %g3, %l1, %g3;
225 ldub [%g3], %g3;
226 brz %g3, _exit;
227 nop;
228
229 /*
230 * Find the address of the userspace handler.
231 * cpu->cpu_thread->t_procp->p_brand_data->spd_handler.
232 */
233 #if defined(sun4v)
234 /* restore the alternate global registers after incrementing %gl */
235 mov %l3, %g2;
236 #endif /* sun4v */
237 ldn [%g2 + CPU_THREAD], %g3; /* get thread ptr */
238 ldn [%g3 + T_PROCP], %g4; /* get proc ptr */
239 ldn [%g4 + __P_BRAND_DATA], %g5; /* get brand data ptr */
240 ldn [%g5 + SPD_HANDLER], %g5; /* get userland brnd hdlr ptr */
241 brz %g5, _exit; /* has it been set? */
242 nop;
243
244 /*
245 * Make sure this isn't an agent lwp. We can't do syscall
246 * interposition for system calls made by a agent lwp. See
247 * the block comments in the top of the brand emulation library
248 * for more information.
249 */
250 ldn [%g4 + P_AGENTTP], %g4; /* get agent thread ptr */
251 cmp %g3, %g4; /* is this an agent thread? */
252 be,pn %xcc, _exit; /* if so don't emulate */
253 nop;
254
255 /*
256 * Now the magic happens. Grab the trap return address and then
257 * reset it to point to the user space handler. When we execute
258 * the 'done' instruction, we will jump into our handler instead of
259 * the user's code. We also stick the old return address in %g5,
|