📄 entry.s
字号:
blink tr0, ZERO/* * __kernel_size_t __clear_user(void *addr, __kernel_size_t size) * * Inputs: * (r2) target address * (r3) size in bytes * * Ouputs: * (*r2) zero-ed target data * (r2) non-zero-ed bytes */ .global __clear_user__clear_user: pta ___clear_user_exit, tr1 pta ___clear_user1, tr0 beq/u r3, r63, tr1___clear_user1: st.b r2, 0, ZERO /* Fault address */ addi r2, 1, r2 addi r3, -1, r3 /* No real fixup required */ bne r3, ZERO, tr0___clear_user_exit: or r3, ZERO, r2 ptabs LINK, tr0 blink tr0, ZERO/* * int __strncpy_from_user(unsigned long __dest, unsigned long __src, * int __count) * * Inputs: * (r2) target address * (r3) source address * (r4) maximum size in bytes * * Ouputs: * (*r2) copied data * (r2) -EFAULT (in case of faulting) * copied data (otherwise) */ .global __strncpy_from_user__strncpy_from_user: pta ___strncpy_from_user1, tr0 pta ___strncpy_from_user_done, tr1 or r4, ZERO, r5 /* r5 = original count */ beq/u r4, r63, tr1 /* early exit if r4==0 */ movi -(EFAULT), r6 /* r6 = reply, no real fixup */ or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */___strncpy_from_user1: ld.b r3, 0, r7 /* Fault address: only in reading */ st.b r2, 0, r7 addi r2, 1, r2 addi r3, 1, r3 beq/u ZERO, r7, tr1 addi r4, -1, r4 /* return real number of copied bytes */ bne/l ZERO, r4, tr0___strncpy_from_user_done: sub r5, r4, r6 /* If done, return copied */___strncpy_from_user_exit: or r6, ZERO, r2 ptabs LINK, tr0 blink tr0, ZERO/* * extern long __strnlen_user(const char *__s, long __n) * * Inputs: * (r2) source address * (r3) source size in bytes * * Ouputs: * (r2) -EFAULT (in case of faulting) * string length (otherwise) */ .global __strnlen_user__strnlen_user: pta ___strnlen_user_set_reply, tr0 pta ___strnlen_user1, tr1 or ZERO, ZERO, r5 /* r5 = counter */ movi -(EFAULT), r6 /* r6 = reply, no real fixup */ or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */ beq r3, ZERO, tr0___strnlen_user1: ldx.b r2, r5, r7 /* Fault address: only in reading */ addi r3, -1, r3 /* No real fixup */ addi r5, 1, r5 beq r3, ZERO, tr0 bne r7, ZERO, tr1! The line below used to be active. This meant led to a junk byte lying between each pair! of entries in the argv & envp structures in memory. Whilst the program saw the right data! via the argv and envp arguments to main, it meant the 'flat' representation visible through! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example.! addi r5, 1, r5 /* Include '\0' */___strnlen_user_set_reply: or r5, ZERO, r6 /* If done, return counter */___strnlen_user_exit: or r6, ZERO, r2 ptabs LINK, tr0 blink tr0, ZERO/* * extern long __get_user_asm_?(void *val, long addr) * * Inputs: * (r2) dest address * (r3) source address (in User Space) * * Ouputs: * (r2) -EFAULT (faulting) * 0 (not faulting) */ .global __get_user_asm_b__get_user_asm_b: or r2, ZERO, r4 movi -(EFAULT), r2 /* r2 = reply, no real fixup */___get_user_asm_b1: ld.b r3, 0, r5 /* r5 = data */ st.b r4, 0, r5 or ZERO, ZERO, r2___get_user_asm_b_exit: ptabs LINK, tr0 blink tr0, ZERO .global __get_user_asm_w__get_user_asm_w: or r2, ZERO, r4 movi -(EFAULT), r2 /* r2 = reply, no real fixup */___get_user_asm_w1: ld.w r3, 0, r5 /* r5 = data */ st.w r4, 0, r5 or ZERO, ZERO, r2___get_user_asm_w_exit: ptabs LINK, tr0 blink tr0, ZERO .global __get_user_asm_l__get_user_asm_l: or r2, ZERO, r4 movi -(EFAULT), r2 /* r2 = reply, no real fixup */___get_user_asm_l1: ld.l r3, 0, r5 /* r5 = data */ st.l r4, 0, r5 or ZERO, ZERO, r2___get_user_asm_l_exit: ptabs LINK, tr0 blink tr0, ZERO .global __get_user_asm_q__get_user_asm_q: or r2, ZERO, r4 movi -(EFAULT), r2 /* r2 = reply, no real fixup */___get_user_asm_q1: ld.q r3, 0, r5 /* r5 = data */ st.q r4, 0, r5 or ZERO, ZERO, r2___get_user_asm_q_exit: ptabs LINK, tr0 blink tr0, ZERO/* * extern long __put_user_asm_?(void *pval, long addr) * * Inputs: * (r2) kernel pointer to value * (r3) dest address (in User Space) * * Ouputs: * (r2) -EFAULT (faulting) * 0 (not faulting) */ .global __put_user_asm_b__put_user_asm_b: ld.b r2, 0, r4 /* r4 = data */ movi -(EFAULT), r2 /* r2 = reply, no real fixup */___put_user_asm_b1: st.b r3, 0, r4 or ZERO, ZERO, r2___put_user_asm_b_exit: ptabs LINK, tr0 blink tr0, ZERO .global __put_user_asm_w__put_user_asm_w: ld.w r2, 0, r4 /* r4 = data */ movi -(EFAULT), r2 /* r2 = reply, no real fixup */___put_user_asm_w1: st.w r3, 0, r4 or ZERO, ZERO, r2___put_user_asm_w_exit: ptabs LINK, tr0 blink tr0, ZERO .global __put_user_asm_l__put_user_asm_l: ld.l r2, 0, r4 /* r4 = data */ movi -(EFAULT), r2 /* r2 = reply, no real fixup */___put_user_asm_l1: st.l r3, 0, r4 or ZERO, ZERO, r2___put_user_asm_l_exit: ptabs LINK, tr0 blink tr0, ZERO .global __put_user_asm_q__put_user_asm_q: ld.q r2, 0, r4 /* r4 = data */ movi -(EFAULT), r2 /* r2 = reply, no real fixup */___put_user_asm_q1: st.q r3, 0, r4 or ZERO, ZERO, r2___put_user_asm_q_exit: ptabs LINK, tr0 blink tr0, ZEROpanic_stash_regs: /* The idea is : when we get an unhandled panic, we dump the registers to a known memory location, the just sit in a tight loop. This allows the human to look at the memory region through the GDB session (assuming the debug module's SHwy initiator isn't locked up or anything), to hopefully analyze the cause of the panic. */ /* On entry, former r15 (SP) is in DCR former r0 is at resvec_saved_area + 0 former r1 is at resvec_saved_area + 8 former tr0 is at resvec_saved_area + 32 DCR is the only register whose value is lost altogether. */ movi 0xffffffff80000000, r0 ! phy of dump area ld.q SP, 0x000, r1 ! former r0 st.q r0, 0x000, r1 ld.q SP, 0x008, r1 ! former r1 st.q r0, 0x008, r1 st.q r0, 0x010, r2 st.q r0, 0x018, r3 st.q r0, 0x020, r4 st.q r0, 0x028, r5 st.q r0, 0x030, r6 st.q r0, 0x038, r7 st.q r0, 0x040, r8 st.q r0, 0x048, r9 st.q r0, 0x050, r10 st.q r0, 0x058, r11 st.q r0, 0x060, r12 st.q r0, 0x068, r13 st.q r0, 0x070, r14 getcon dcr, r14 st.q r0, 0x078, r14 st.q r0, 0x080, r16 st.q r0, 0x088, r17 st.q r0, 0x090, r18 st.q r0, 0x098, r19 st.q r0, 0x0a0, r20 st.q r0, 0x0a8, r21 st.q r0, 0x0b0, r22 st.q r0, 0x0b8, r23 st.q r0, 0x0c0, r24 st.q r0, 0x0c8, r25 st.q r0, 0x0d0, r26 st.q r0, 0x0d8, r27 st.q r0, 0x0e0, r28 st.q r0, 0x0e8, r29 st.q r0, 0x0f0, r30 st.q r0, 0x0f8, r31 st.q r0, 0x100, r32 st.q r0, 0x108, r33 st.q r0, 0x110, r34 st.q r0, 0x118, r35 st.q r0, 0x120, r36 st.q r0, 0x128, r37 st.q r0, 0x130, r38 st.q r0, 0x138, r39 st.q r0, 0x140, r40 st.q r0, 0x148, r41 st.q r0, 0x150, r42 st.q r0, 0x158, r43 st.q r0, 0x160, r44 st.q r0, 0x168, r45 st.q r0, 0x170, r46 st.q r0, 0x178, r47 st.q r0, 0x180, r48 st.q r0, 0x188, r49 st.q r0, 0x190, r50 st.q r0, 0x198, r51 st.q r0, 0x1a0, r52 st.q r0, 0x1a8, r53 st.q r0, 0x1b0, r54 st.q r0, 0x1b8, r55 st.q r0, 0x1c0, r56 st.q r0, 0x1c8, r57 st.q r0, 0x1d0, r58 st.q r0, 0x1d8, r59 st.q r0, 0x1e0, r60 st.q r0, 0x1e8, r61 st.q r0, 0x1f0, r62 st.q r0, 0x1f8, r63 ! bogus, but for consistency's sake... ld.q SP, 0x020, r1 ! former tr0 st.q r0, 0x200, r1 gettr tr1, r1 st.q r0, 0x208, r1 gettr tr2, r1 st.q r0, 0x210, r1 gettr tr3, r1 st.q r0, 0x218, r1 gettr tr4, r1 st.q r0, 0x220, r1 gettr tr5, r1 st.q r0, 0x228, r1 gettr tr6, r1 st.q r0, 0x230, r1 gettr tr7, r1 st.q r0, 0x238, r1 getcon sr, r1 getcon ssr, r2 getcon pssr, r3 getcon spc, r4 getcon pspc, r5 getcon intevt, r6 getcon expevt, r7 getcon pexpevt, r8 getcon tra, r9 getcon tea, r10 getcon kcr0, r11 getcon kcr1, r12 getcon vbr, r13 getcon resvec, r14 st.q r0, 0x240, r1 st.q r0, 0x248, r2 st.q r0, 0x250, r3 st.q r0, 0x258, r4 st.q r0, 0x260, r5 st.q r0, 0x268, r6 st.q r0, 0x270, r7 st.q r0, 0x278, r8 st.q r0, 0x280, r9 st.q r0, 0x288, r10 st.q r0, 0x290, r11 st.q r0, 0x298, r12 st.q r0, 0x2a0, r13 st.q r0, 0x2a8, r14 getcon SPC,r2 getcon SSR,r3 getcon EXPEVT,r4 /* Prepare to jump to C - physical address */ movi panic_handler-CONFIG_CACHED_MEMORY_OFFSET, r1 ori r1, 1, r1 ptabs r1, tr0 getcon DCR, SP blink tr0, ZERO nop nop nop nop/* * --- Signal Handling Section *//* * extern long long _sa_default_rt_restorer * extern long long _sa_default_restorer * * or, better, * * extern void _sa_default_rt_restorer(void) * extern void _sa_default_restorer(void) * * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn() * from user space. Copied into user space by signal management. * Both must be quad aligned and 2 quad long (4 instructions). * */ .balign 8 .global sa_default_rt_restorersa_default_rt_restorer: movi 0x10, r9 shori __NR_rt_sigreturn, r9 trapa r9 nop .balign 8 .global sa_default_restorersa_default_restorer: movi 0x10, r9 shori __NR_sigreturn, r9 trapa r9 nop/* * --- __ex_table Section *//* * User Access Exception Table. */ .section __ex_table, "a" .global asm_uaccess_start /* Just a marker */asm_uaccess_start: .long ___copy_user1, ___copy_user_exit .long ___copy_user2, ___copy_user_exit .long ___clear_user1, ___clear_user_exit .long ___strncpy_from_user1, ___strncpy_from_user_exit .long ___strnlen_user1, ___strnlen_user_exit .long ___get_user_asm_b1, ___get_user_asm_b_exit .long ___get_user_asm_w1, ___get_user_asm_w_exit .long ___get_user_asm_l1, ___get_user_asm_l_exit .long ___get_user_asm_q1, ___get_user_asm_q_exit .long ___put_user_asm_b1, ___put_user_asm_b_exit .long ___put_user_asm_w1, ___put_user_asm_w_exit .long ___put_user_asm_l1, ___put_user_asm_l_exit .long ___put_user_asm_q1, ___put_user_asm_q_exit .global asm_uaccess_end /* Just a marker */asm_uaccess_end:/* * --- .text.init Section */ .section .text.init, "ax"/* * void trap_init (void) * */ .global trap_inittrap_init: addi SP, -24, SP /* Room to save r28/r29/r30 */ st.q SP, 0, r28 st.q SP, 8, r29 st.q SP, 16, r30 /* Set VBR and RESVEC */ movi LVBR_block, r19 andi r19, -4, r19 /* reset MMUOFF + reserved */ /* For RESVEC exceptions we force the MMU off, which means we need the physical address. */ movi LRESVEC_block-CONFIG_CACHED_MEMORY_OFFSET, r20 andi r20, -4, r20 /* reset reserved */ ori r20, 1, r20 /* set MMUOFF */ putcon r19, VBR putcon r20, RESVEC /* Sanity check */ movi LVBR_block_end, r21 andi r21, -4, r21 movi BLOCK_SIZE, r29 /* r29 = expected size */ or r19, ZERO, r30 add r19, r29, r19 /* * Ugly, but better loop forever now than crash afterwards. * We should print a message, but if we touch LVBR or * LRESVEC blocks we should not be surprised if we get stuck * in trap_init(). */ pta trap_init_loop, tr1 gettr tr1, r28 /* r28 = trap_init_loop */ sub r21, r30, r30 /* r30 = actual size */ /* * VBR/RESVEC handlers overlap by being bigger than * allowed. Very bad. Just loop forever. * (r28) panic/loop address * (r29) expected size * (r30) actual size */trap_init_loop: bne r19, r21, tr1 /* Now that exception vectors are set up reset SR.BL */ getcon SR, r22 movi SR_UNBLOCK_EXC, r23 and r22, r23, r22 putcon r22, SR addi SP, 24, SP ptabs LINK, tr0 blink tr0, ZERO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -