基於PPC64架構 Linux 核心訊號處理過程棧處理分析
handle_rt_signal64主要負責訊號處理棧處理分析,如下圖所示
int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; unsigned long newsp = 0; unsigned long oldsp = 0; long err = 0; /* 從regs->gpr[1]讀取當前棧指標,往下增長sizeof(*frame),0x960Byte */ frame = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*frame), 0); if (unlikely(frame == NULL)) goto badframe; err |= __put_user(&frame->info, &frame->pinfo); err |= __put_user(&frame->uc, &frame->puc); err |= copy_siginfo_to_user(&frame->info, &ksig->info); if (err) goto badframe; /* 個人增加的除錯程式碼,純粹列印 */ oldsp = regs->gpr[1]; /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); /* 儲存當前sp到使用者棧,後續需要從這裡恢復原來的內容 */ err |= __save_altstack(&frame->uc.uc_stack, regs->gpr[1]); #ifdef CONFIG_PPC_TRANSACTIONAL_MEM if (MSR_TM_ACTIVE(regs->msr)) { /* The ucontext_t passed to userland points to the second * ucontext_t (for transactional state) with its uc_link ptr. */ err |= __put_user(&frame->uc_transact, &frame->uc.uc_link); err |= setup_tm_sigcontexts(&frame->uc.uc_mcontext, &frame->uc_transact.uc_mcontext, regs, ksig->sig, NULL, (unsigned long)ksig->ka.sa.sa_handler); } else #endif { err |= __put_user(0, &frame->uc.uc_link); /* 儲存當前訊號上下文到使用者棧空間,後續需要從這裡恢復原來的內容 */ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, ksig->sig, NULL, (unsigned long)ksig->ka.sa.sa_handler, 1); } err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); if (err) goto badframe; /* Make sure signal handler doesn't get spurious FP exceptions */ current->thread.fp_state.fpscr = 0; /* Set up to return from userspace. */ if (vdso64_rt_sigtramp && current->mm->context.vdso_base) { /* link是函式返回地址LR,訊號處理handle執行return後地址,此處使用VDSO */ regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp; } else { err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); if (err) goto badframe; regs->link = (unsigned long) &frame->tramp[0]; } /* Allocate a dummy caller frame for the signal handler. */ /* 在frame再往下構建一個128B的虛擬棧,個人認為是作為安全空隙,避免被踩?*/ newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; err |= put_user(regs->gpr[1], (unsigned long __user *)newsp); /* Set up "regs" so we "return" to the signal handler. */ if (is_elf2_task()) { regs->nip = (unsigned long) ksig->ka.sa.sa_handler; regs->gpr[12] = regs->nip; } else { /* Handler is *really* a pointer to the function descriptor for * the signal routine. The first entry in the function * descriptor is the entry address of signal and the second * entry is the TOC value we need to use. */ func_descr_t __user *funct_desc_ptr = (func_descr_t __user *) ksig->ka.sa.sa_handler; /* 設定regs->nip為使用者訊號處理函式地址,一旦從核心返回,直接執行 */ err |= get_user(regs->nip, &funct_desc_ptr->entry); err |= get_user(regs->gpr[2], &funct_desc_ptr->toc); } /* enter the signal handler in native-endian mode */ regs->msr &= ~MSR_LE; regs->msr |= (MSR_KERNEL & MSR_LE); /* 設定使用者訊號處理函式的棧地址 */ regs->gpr[1] = newsp; /* 訊號處理函式的第一個入參,訊號值 */ regs->gpr[3] = ksig->sig; regs->result = 0; if (ksig->ka.sa.sa_flags & SA_SIGINFO) { /* 如果指定SA_SIGINFO,訊號處理函式的第二個入參 */ err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo); /* 如果指定SA_SIGINFO,訊號處理函式的第三個入參 */ err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc); regs->gpr[6] = (unsigned long) frame; } else { regs->gpr[4] = (unsigned long)&frame->uc.uc_mcontext; } if (err) goto badframe; /* 除錯列印原來的oldsp,frame,newsp, 新的link,新的nip */ pr_info("oldsp=%#lx, oldsp=%#lx, frame=%#lx, newsp=%#lx, regs->link=%#lx,regs->nip=%#lx", oldsp, frame, newsp, regs->link,regs->nip); return 0; badframe: if (show_unhandled_signals) printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, current->comm, current->pid, "setup_rt_frame", (long)frame, regs->nip, regs->link); return 1; }
在handle_rt_signal64增加了列印後,測試用例註冊一個訊號,訊號處理函式使用嵌入彙編方式讀取R1暫存器(當前SP),
從當前SP開始列印一堆資料,如下所示。當前SP地址是0x3ffffe75d1c0與newsp又相差144B,為什麼呢?請繼續往下看。
oldsp=0x3ffffe75dc30, frame=0x3ffffe75d2d0, newsp=0x3ffffe75d250, regs->link=0x3fff8a740478, regs->nip=0x10000964 add=0x3ffffe75d1c0, val=0x3ffffe75d250 add=0x3ffffe75d1c8, val=0x3d8 add=0x3ffffe75d1d0, val=0x100009e4 add=0x3ffffe75d1d8, val=0x400000010 add=0x3ffffe75d1e0, val=0x1474e5500 add=0x3ffffe75d1e8, val=0x100192d8 add=0x3ffffe75d1f0, val=0x600000020 add=0x3ffffe75d1f8, val=0x3ffffe75d1f0 add=0x3ffffe75d200, val=0x3ffffe75d1f0 add=0x3ffffe75d208, val=0x27 add=0x3ffffe75d210, val=0 add=0x3ffffe75d218, val=0x3ffffe75d210 add=0x3ffffe75d220, val=0x3ffffe75d210 add=0x3ffffe75d228, val=0x3ffffe75d1c0 add=0x3ffffe75d230, val=0xe01040200 add=0x3ffffe75d238, val=0x3ffffe75d1c0 add=0x3ffffe75d240, val=0x67406c2d820a1180 add=0x3ffffe75d248, val=0xffffffff add=0x3ffffe75d250, val=0x3ffffe75dc30 add=0x3ffffe75d258, val=0x2200c081290a042 add=0x3ffffe75d260, val=0x3fff8a740478 add=0x3ffffe75d268, val=0xcc28013980000a0a add=0x3ffffe75d270, val=0xc28081240818440 add=0x3ffffe75d278, val=0x8008518000000044 add=0x3ffffe75d280, val=0xcd042041d add=0x3ffffe75d288, val=0x80003018b5000001 add=0x3ffffe75d290, val=0x1041090022100260 add=0x3ffffe75d298, val=0x4712a92850000501 add=0x3ffffe75d2a0, val=0x440980482000028 add=0x3ffffe75d2a8, val=0x240020054e01000 add=0x3ffffe75d2b0, val=0x80164430c11002 add=0x3ffffe75d2b8, val=0x1c00021004240000 add=0x3ffffe75d2c0, val=0x80018000f90a380 add=0x3ffffe75d2c8, val=0x4406280080012010 add=0x3ffffe75d2d0, val=0 add=0x3ffffe75d2d8, val=0 add=0x3ffffe75d2e0, val=0 add=0x3ffffe75d2e8, val=0x2fe75d9e8 add=0x3ffffe75d2f0, val=0 add=0x3ffffe75d2f8, val=0 add=0x3ffffe75d300, val=0 add=0x3ffffe75d308, val=0x3fff8a77ea10 add=0x3ffffe75d310, val=0x3ffffe75d7e0 add=0x3ffffe75d318, val=0x3fff8a534ec8 add=0x3ffffe75d320, val=0x5 add=0x3ffffe75d328, val=0x3ffffe75d7b0 add=0x3ffffe75d330, val=0x3ffffe75d9f8 add=0x3ffffe75d338, val=0x3fff8a77b4d8 add=0x3ffffe75d340, val=0x3ffffe75d810 add=0x3ffffe75d348, val=0x3fff8a55fe10 add=0x3ffffe75d350, val=0x1 add=0x3ffffe75d358, val=0x3fff8a5361fb add=0x3ffffe75d360, val=0x10 add=0x3ffffe75d368, val=0x3ffffe75d9c0 add=0x3ffffe75d370, val=0x3ffffe75d3f0 add=0x3ffffe75d378, val=0x420042228a70de10 add=0x3ffffe75d380, val=0x3fff8a7592e0 add=0x3ffffe75d388, val=0x3fff8a57eae4 add=0x3ffffe75d390, val=0x18 add=0x3ffffe75d398, val=0xcfe75d9c0 add=0x3ffffe75d3a0, val=0x10011260 add=0x3ffffe75d3a8, val=0x480042228a73de00 add=0x3ffffe75d3b0, val=0x3ffffe75d3b8 add=0x3ffffe75d3b8, val=0xa2 add=0x3ffffe75d3c0, val=0x3ffffe75dc30 add=0x3ffffe75d3c8, val=0x3fff8a727c10 add=0x3ffffe75d3d0, val=0x4 add=0x3ffffe75d3d8, val=0x3ffffe75de38 add=0x3ffffe75d3e0, val=0x88000248 add=0x3ffffe75d3e8, val=0x4000 add=0x3ffffe75d3f0, val=0x3fff8a5c3ef8 add=0x3ffffe75d3f8, val=0x8202f000 add=0x3ffffe75d400, val=0 add=0x3ffffe75d408, val=0 add=0x3ffffe75d410, val=0 add=0x3ffffe75d418, val=0 add=0x3ffffe75d420, val=0x3fff8a780750 add=0x3ffffe75d428, val=0 add=0x3ffffe75d430, val=0 add=0x3ffffe75d438, val=0 add=0x3ffffe75d440, val=0 add=0x3ffffe75d448, val=0 add=0x3ffffe75d450, val=0 add=0x3ffffe75d458, val=0 add=0x3ffffe75d460, val=0 add=0x3ffffe75d468, val=0 add=0x3ffffe75d470, val=0 add=0x3ffffe75d478, val=0 add=0x3ffffe75d480, val=0 add=0x3ffffe75d488, val=0 add=0x3ffffe75d490, val=0x3fff8a77ee20 add=0x3ffffe75d498, val=0x3ffffe75dd38 add=0x3ffffe75d4a0, val=0x10000 add=0x3ffffe75d4a8, val=0x3ffffe75ddb8 add=0x3ffffe75d4b0, val=0xffffffff add=0x3ffffe75d4b8, val=0x3fff8a648754 add=0x3ffffe75d4c0, val=0x8202d000 add=0x3ffffe75d4c8, val=0x3ffffe75de38 add=0x3ffffe75d4d0, val=0 add=0x3ffffe75d4d8, val=0x3fff8a64854c add=0x3ffffe75d4e0, val=0 add=0x3ffffe75d4e8, val=0x98000248 add=0x3ffffe75d4f0, val=0x1 add=0x3ffffe75d4f8, val=0xc00 add=0x3ffffe75d500, val=0x3fff8a648440 add=0x3ffffe75d508, val=0 add=0x3ffffe75d510, val=0xfffffffffffffffc add=0x3ffffe75d518, val=0x3fff8a781b10 add=0x3ffffe75d520, val=0 add=0x3ffffe75d528, val=0x3fff8a781ae8 add=0x3ffffe75d530, val=0x3ffffe75d6a0 add=0x3ffffe75d538, val=0 add=0x3ffffe75d540, val=0 add=0x3ffffe75d548, val=0 add=0x3ffffe75d550, val=0 add=0x3ffffe75d558, val=0 add=0x3ffffe75d560, val=0 add=0x3ffffe75d568, val=0 add=0x3ffffe75d570, val=0 add=0x3ffffe75d578, val=0 add=0x3ffffe75d580, val=0 add=0x3ffffe75d588, val=0 add=0x3ffffe75d590, val=0 add=0x3ffffe75d598, val=0 add=0x3ffffe75d5a0, val=0 add=0x3ffffe75d5a8, val=0 add=0x3ffffe75d5b0, val=0 add=0x3ffffe75d5b8, val=0 add=0x3ffffe75d5c0, val=0 add=0x3ffffe75d5c8, val=0 add=0x3ffffe75d5d0, val=0 add=0x3ffffe75d5d8, val=0 add=0x3ffffe75d5e0, val=0 add=0x3ffffe75d5e8, val=0 add=0x3ffffe75d5f0, val=0 add=0x3ffffe75d5f8, val=0 add=0x3ffffe75d600, val=0 add=0x3ffffe75d608, val=0 add=0x3ffffe75d610, val=0 add=0x3ffffe75d618, val=0 add=0x3ffffe75d620, val=0 add=0x3ffffe75d628, val=0 add=0x3ffffe75d630, val=0 add=0x3ffffe75d638, val=0xfff8000000000000 add=0x3ffffe75d640, val=0x3ffffe75d650 add=0x3ffffe75d648, val=0x3fff8a77b000 add=0x3ffffe75d650, val=0 add=0x3ffffe75d658, val=0 add=0x3ffffe75d660, val=0 add=0x3ffffe75d668, val=0 add=0x3ffffe75d670, val=0 add=0x3ffffe75d678, val=0 add=0x3ffffe75d680, val=0 add=0x3ffffe75d688, val=0 add=0x3ffffe75d690, val=0 add=0x3ffffe75d698, val=0 add=0x3ffffe75d6a0, val=0 add=0x3ffffe75d6a8, val=0 add=0x3ffffe75d6b0, val=0 add=0x3ffffe75d6b8, val=0 add=0x3ffffe75d6c0, val=0 add=0x3ffffe75d6c8, val=0 add=0x3ffffe75d6d0, val=0 add=0x3ffffe75d6d8, val=0 add=0x3ffffe75d6e0, val=0 add=0x3ffffe75d6e8, val=0 add=0x3ffffe75d6f0, val=0 add=0x3ffffe75d6f8, val=0 add=0x3ffffe75d700, val=0 add=0x3ffffe75d708, val=0 add=0x3ffffe75d710, val=0 add=0x3ffffe75d718, val=0 add=0x3ffffe75d720, val=0 add=0x3ffffe75d728, val=0 add=0x3ffffe75d730, val=0 add=0x3ffffe75d738, val=0 add=0x3ffffe75d740, val=0x404040404040404 add=0x3ffffe75d748, val=0x404040404040404 add=0x3ffffe75d750, val=0x1020304050607 add=0x3ffffe75d758, val=0x8090a0b0c0d0e0f add=0x3ffffe75d760, val=0 add=0x3ffffe75d768, val=0x3fff8a77eea0 add=0x3ffffe75d770, val=0 add=0x3ffffe75d778, val=0 add=0x3ffffe75d780, val=0 add=0x3ffffe75d788, val=0 add=0x3ffffe75d790, val=0 add=0x3ffffe75d798, val=0 add=0x3ffffe75d7a0, val=0 add=0x3ffffe75d7a8, val=0 add=0x3ffffe75d7b0, val=0 add=0x3ffffe75d7b8, val=0 add=0x3ffffe75d7c0, val=0 add=0x3ffffe75d7c8, val=0 add=0x3ffffe75d7d0, val=0 add=0x3ffffe75d7d8, val=0 add=0x3ffffe75d7e0, val=0 add=0x3ffffe75d7e8, val=0 add=0x3ffffe75d7f0, val=0 add=0x3ffffe75d7f8, val=0 add=0x3ffffe75d800, val=0 add=0x3ffffe75d808, val=0 add=0x3ffffe75d810, val=0 add=0x3ffffe75d818, val=0 add=0x3ffffe75d820, val=0 add=0x3ffffe75d828, val=0 add=0x3ffffe75d830, val=0 add=0x3ffffe75d838, val=0 add=0x3ffffe75d840, val=0 add=0x3ffffe75d848, val=0 add=0x3ffffe75d850, val=0 add=0x3ffffe75d858, val=0x10000 add=0x3ffffe75d860, val=0xffffffff00000000 add=0x3ffffe75d868, val=0x3fff8a779000 add=0x3ffffe75d870, val=0x3fff8a779750 add=0x3ffffe75d878, val=0xf add=0x3ffffe75d880, val=0x3ffffe75d920 add=0x3ffffe75d888, val=0x3ffffe75d940 add=0x3ffffe75d890, val=0x3fff8a747448 add=0x3ffffe75d898, val=0x3fff8a780d60 add=0x3ffffe75d8a0, val=0x3ffffe75d920 add=0x3ffffe75d8a8, val=0xffffffff add=0x3ffffe75d8b0, val=0 add=0x3ffffe75d8b8, val=0 add=0x3ffffe75d8c0, val=0 add=0x3ffffe75d8c8, val=0 add=0x3ffffe75d8d0, val=0 add=0x3ffffe75d8d8, val=0 add=0x3ffffe75d8e0, val=0 add=0x3ffffe75d8e8, val=0 add=0x3ffffe75d8f0, val=0 add=0x3ffffe75d8f8, val=0 add=0x3ffffe75d900, val=0 add=0x3ffffe75d908, val=0 add=0x3ffffe75d910, val=0x3fff8a5a9e08 add=0x3ffffe75d918, val=0x1b9708 add=0x3ffffe75d920, val=0x3fff8a567000 add=0x3ffffe75d928, val=0x3fff8a720708 add=0x3ffffe75d930, val=0x3ffffe75dee8 add=0x3ffffe75d938, val=0x3fff8a77b000 add=0x3ffffe75d940, val=0x3ffffe75d9f0 add=0x3ffffe75d948, val=0x22000482fe75d950 add=0x3ffffe75d950, val=0x3fff8a75af4c add=0x3ffffe75d958, val=0x420222448a77d718 add=0x3ffffe75d960, val=0x3fff8a756ffc add=0x3ffffe75d968, val=0 add=0x3ffffe75d970, val=0x3ffffe75da10 add=0x3ffffe75d978, val=0x3fff8a788278 add=0x3ffffe75d980, val=0x3fff8a7803c8 add=0x3ffffe75d988, val=0x3fff8a788278 add=0x3ffffe75d990, val=0x3ffffe75da10 add=0x3ffffe75d998, val=0x3ffffe75d9a8 add=0x3ffffe75d9a0, val=0x3ffffe75d2d0 add=0x3ffffe75d9a8, val=0xc00000000 add=0x3ffffe75d9b0, val=0xfffffffe8a747448 add=0x3ffffe75d9b8, val=0 add=0x3ffffe75d9c0, val=0 add=0x3ffffe75d9c8, val=0x3ffffe75dbd0 add=0x3ffffe75d9d0, val=0x3fff8a780cd0 add=0x3ffffe75d9d8, val=0x3fff8a7803c8 add=0x3ffffe75d9e0, val=0x3ffffe75dee8 add=0x3ffffe75d9e8, val=0x105cf61e add=0x3ffffe75d9f0, val=0x7aa add=0x3ffffe75d9f8, val=0x3fff8a77ba70 add=0x3ffffe75da00, val=0x2 add=0x3ffffe75da08, val=0x3fff8a77b000 add=0x3ffffe75da10, val=0x3ffffe75db80 add=0x3ffffe75da18, val=0x10033000 add=0x3ffffe75da20, val=0x3fff8a754530 add=0x3ffffe75da28, val=0x3ffffe75db70 add=0x3ffffe75da30, val=0x3fff8a77da90 add=0x3ffffe75da38, val=0x1 add=0x3ffffe75da40, val=0x3ffffe75db88 add=0x3ffffe75da48, val=0x3fff8a77d718 add=0x3ffffe75da50, val=0x1 add=0x3ffffe75da58, val=0x3fff8a77bbf0 add=0x3ffffe75da60, val=0x3fff8a714900 add=0x3ffffe75da68, val=0x3ffffe75dbd0 add=0x3ffffe75da70, val=0x3ffffe75dbf0 add=0x3ffffe75da78, val=0x3ffffe75dbd0 add=0x3ffffe75da80, val=0x3ffffe75dc30 add=0x3ffffe75da88, val=0x3ffffe75daa0 add=0x3ffffe75da90, val=0x3ffffe75daa8 add=0x3ffffe75da98, val=0x3fff8a721728 add=0x3ffffe75daa0, val=0 add=0x3ffffe75daa8, val=0 add=0x3ffffe75dab0, val=0 add=0x3ffffe75dab8, val=0 add=0x3ffffe75dac0, val=0 add=0x3ffffe75dac8, val=0 add=0x3ffffe75dad0, val=0x3fff8a77ee20 add=0x3ffffe75dad8, val=0x3fff8a76a5d0 add=0x3ffffe75dae0, val=0x3fff8a56a8b4 add=0x3ffffe75dae8, val=0 add=0x3ffffe75daf0, val=0 add=0x3ffffe75daf8, val=0 add=0x3ffffe75db00, val=0 add=0x3ffffe75db08, val=0 add=0x3ffffe75db10, val=0x3fff8a7803c8 add=0x3ffffe75db18, val=0x3ffffe75dc60 add=0x3ffffe75db20, val=0x3fff8a7818c0 add=0x3ffffe75db28, val=0x1 add=0x3ffffe75db30, val=0x3ffffe75dc78 add=0x3ffffe75db38, val=0x3fff8a781548 add=0x3ffffe75db40, val=0x1 add=0x3ffffe75db48, val=0x3fff8a77bab8 add=0x3ffffe75db50, val=0x3ffffe75dd80 add=0x3ffffe75db58, val=0x10000447 add=0x3ffffe75db60, val=0 add=0x3ffffe75db68, val=0x3fff8a7818c0 add=0x3ffffe75db70, val=0x105cf61e add=0x3ffffe75db78, val=0x3ffffe75db80 add=0x3ffffe75db80, val=0x3ffffe75dd10 add=0x3ffffe75db88, val=0x22042444ffffffff add=0x3ffffe75db90, val=0x3fff8a754d7c add=0x3ffffe75db98, val=0 add=0x3ffffe75dba0, val=0x30 add=0x3ffffe75dba8, val=0x5b add=0x3ffffe75dbb0, val=0x6e add=0x3ffffe75dbb8, val=0x77 add=0x3ffffe75dbc0, val=0x3ffffe75dc78 add=0x3ffffe75dbc8, val=0 add=0x3ffffe75dbd0, val=0x3ffffe75dc60 add=0x3ffffe75dbd8, val=0 add=0x3ffffe75dbe0, val=0 add=0x3ffffe75dbe8, val=0 add=0x3ffffe75dbf0, val=0 add=0x3ffffe75dbf8, val=0 add=0x3ffffe75dc00, val=0 add=0x3ffffe75dc08, val=0x3fff8a77ee20 add=0x3ffffe75dc10, val=0x3ffffe75dd38 add=0x3ffffe75dc18, val=0x10000 add=0x3ffffe75dc20, val=0x3ffffe75ddb8 add=0x3ffffe75dc28, val=0xffffffff add=0x3ffffe75dc30, val=0x3ffffe75de70 add=0x3ffffe75dc38, val=0x3fff8a77ee20 add=0x3ffffe75dc40, val=0x3ffffe75dee0 add=0x3ffffe75dc48, val=0x8 add=0x3ffffe75dc50, val=0x3ffffe75dee8 add=0x3ffffe75dc58, val=0x3fff8a70e9c8 add=0x3ffffe75dc60, val=0x3fff8a576750 add=0x3ffffe75dc68, val=0x3fff8a77b000 add=0x3ffffe75dc70, val=0x3fff8a616b9c add=0x3ffffe75dc78, val=0xffffffff
其中:oldspp與frame相差0x960B, frame與newsp=128B, regs->link=0x3fff8a740478, regs->nip=0x10000964,NIP指向訊號處理函式地址(如下反彙編所示地址0x10000964)
回答上面的問題,當前SP地址是0x3ffffe75d1c0與newsp又相差144B,為什麼呢?
看反彙編程式碼10000970: f8 21 ff 71 stdu r1,-144(r1),可以看到r1又往下增長了144B了(我們的列印在此行之後)。
0000000010000964 <.sig_handler>: 10000964: 7c 08 02 a6 mflr r0 10000968: f8 01 00 10 std r0,16(r1) 1000096c: fb e1 ff f8 std r31,-8(r1) 10000970: f8 21 ff 71 stdu r1,-144(r1) 10000974: 7c 3f 0b 78 mr r31,r1 10000978: 7c 69 1b 78 mr r9,r3 1000097c: 91 3f 00 c0 stw r9,192(r31) 10000980: 39 20 00 00 li r9,0 10000984: 91 3f 00 70 stw r9,112(r31) 10000988: 39 20 00 00 li r9,0 1000098c: f9 3f 00 78 std r9,120(r31) 10000990: 7c 29 0b 78 mr r9,r1 10000994: f9 3f 00 78 std r9,120(r31)
其中:regs->link=0x3fff8a740478用於使用VDSO機制,從本程序maps可以看出VDSO可以看出vdso64_rt_sigtramp的地址是0x0478;regs->nip=0x10000964指向TEXT段的訊號處理函式。
[email protected]:/proc/2033# cat maps
10000000-10001000 r-xp 00000000 00:16 2291 /var/volatile/timer
10011000-10012000 rw-p 00001000 00:16 2291 /var/volatile/timer
10012000-10033000 rw-p 00000000 00:00 0 [heap]
3fff8a532000-3fff8a550000 r-xp 00000000 01:00 9891 /lib64/libpthread-2.20.so
3fff8a550000-3fff8a55f000 ---p 0001e000 01:00 9891 /lib64/libpthread-2.20.so
3fff8a55f000-3fff8a560000 r--p 0001d000 01:00 9891 /lib64/libpthread-2.20.so
3fff8a560000-3fff8a562000 rw-p 0001e000 01:00 9891 /lib64/libpthread-2.20.so
3fff8a562000-3fff8a567000 rw-p 00000000 00:00 0
3fff8a567000-3fff8a6fb000 r-xp 00000000 01:00 9909 /lib64/libc-2.20.so
3fff8a6fb000-3fff8a70a000 ---p 00194000 01:00 9909 /lib64/libc-2.20.so
3fff8a70a000-3fff8a70e000 r--p 00193000 01:00 9909 /lib64/libc-2.20.so
3fff8a70e000-3fff8a721000 rw-p 00197000 01:00 9909 /lib64/libc-2.20.so
3fff8a721000-3fff8a725000 rw-p 00000000 00:00 0
3fff8a725000-3fff8a72e000 r-xp 00000000 01:00 9906 /lib64/librt-2.20.so
3fff8a72e000-3fff8a73d000 ---p 00009000 01:00 9906 /lib64/librt-2.20.so
3fff8a73d000-3fff8a73e000 r--p 00008000 01:00 9906 /lib64/librt-2.20.so
3fff8a73e000-3fff8a73f000 rw-p 00009000 01:00 9906 /lib64/librt-2.20.so
3fff8a73f000-3fff8a740000 rw-p 00000000 00:00 0
3fff8a740000-3fff8a743000 r-xp 00000000 00:00 0 [vdso]
3fff8a747000-3fff8a76f000 r-xp 00000000 01:00 9930 /lib64/ld-2.20.so
3fff8a779000-3fff8a77d000 rw-p 00000000 00:00 0
3fff8a77d000-3fff8a77e000 rw-p 00000000 00:00 0
3fff8a77e000-3fff8a77f000 r--p 00027000 01:00 9930 /lib64/ld-2.20.so
3fff8a77f000-3fff8a782000 rw-p 00028000 01:00 9930 /lib64/ld-2.20.so
3ffffe73e000-3ffffe75f000 rw-p 00000000 00:00 0 [stack]
[email protected]:/proc/2033#
regs->link=0x3fff8a740478用於使用VDSO機制,究竟是執行什麼程式碼呢?
原來是以下程式碼,從以下程式碼看出,addi r1, r1, __SIGNAL_FRAMESIZE又把newsp改為到frame。注意當前r1是由於訊號處理函式結束blr返回後自動已經改為newsp(r1+144B)了。
V_FUNCTION_BEGIN(__kernel_sigtramp_rt64)
.Lsigrt_start = . - 4
addi r1, r1, __SIGNAL_FRAMESIZE
li r0,__NR_rt_sigreturn
sc
.Lsigrt_end:
V_FUNCTION_END(__kernel_sigtramp_rt64)
通過sc系統呼叫,執行以下程式碼
int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7, unsigned long r8,
struct pt_regs *regs)
{
/* 當前gpr[1]就是上次frame,frame結構體第一個元素就是uc,因此強轉換沒有問題 */
struct ucontext __user *uc = (struct ucontext __user *)regs->gpr[1];
sigset_t set;
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
unsigned long msr;
#endif
/* Always make any pending restarted system calls return -EINTR */
current->restart_block.fn = do_no_restart_syscall;
if (!access_ok(VERIFY_READ, uc, sizeof(*uc)))
goto badframe;
if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
goto badframe;
set_current_blocked(&set);
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
if (__get_user(msr, &uc->uc_mcontext.gp_regs[PT_MSR]))
goto badframe;
if (MSR_TM_ACTIVE(msr)) {
/* We recheckpoint on return. */
struct ucontext __user *uc_transact;
if (__get_user(uc_transact, &uc->uc_link))
goto badframe;
if (restore_tm_sigcontexts(regs, &uc->uc_mcontext,
&uc_transact->uc_mcontext))
goto badframe;
}
else
/* Fall through, for non-TM restore */
#endif
/* 恢復訊號上下文 */
if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext))
goto badframe;
/* 恢復棧指標內容 */
if (restore_altstack(&uc->uc_stack))
goto badframe;
set_thread_flag(TIF_RESTOREALL);
return 0;
badframe:
if (show_unhandled_signals)
printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
current->comm, current->pid, "rt_sigreturn",
(long)uc, regs->nip, regs->link);
force_sig(SIGSEGV, current);
return 0;
}
總結:核心的訊號處理機制效率並不高,因為__kernel_sigtramp_rt64返回再次進入核心時,核心從使用者態棧空間還原出原始的pt_regs,準備返回使用者態時,又重新檢測有沒有pending訊號,一旦有,又得執行訊號處理函式又需要構建frame,不停地迴圈,因此效率堪憂。
有空再補充一個棧變化圖。