?? math_emulate.c
字號:
/* passed* linux/kernel/math/math_emulate.c** (C) 1991 Linus Torvalds*//*
注意:signal.c和fork.c文件的編譯選項內不能有vc變量優化選項/Og,因為這兩個文件
內的函數參數內包含了函數返回地址等內容。如果加了/Og選項,編譯器就會在認為
這些參數不再使用后占用該內存,導致函數返回時出錯。
math/math_emulate.c照理也應該這樣,不過好像它沒有把eip等參數優化掉:)
*/
#include <set_seg.h>
/** This directory should contain the math-emulation code.* Currently only results in a signal.*//** 該目錄里應該包含數學仿真代碼。目前僅產生一個信號。*/#include <signal.h> // 信號頭文件。定義信號符號常量,信號結構以及信號操作函數原型。#include <linux/sched.h> // 調度程序頭文件,定義了任務結構task_struct、初始任務0 的數據,// 還有一些有關描述符參數設置和獲取的嵌入式匯編函數宏語句。#include <linux/kernel.h> // 內核頭文件。含有一些內核常用函數的原形定義。#include <asm/segment.h> // 段操作頭文件。定義了有關段寄存器操作的嵌入式匯編函數。//// 協處理器仿真函數。// 中斷處理程序調用的C 函數,參見(kernel/math/system_call.s,169 行)。voidmath_emulate (long edi, long esi, long ebp, long sys_call_ret, long eax, long ebx, long ecx, long edx, unsigned short fs, unsigned short es, unsigned short ds, unsigned long eip, unsigned short cs, unsigned long eflags, unsigned short ss, unsigned long esp){ unsigned char first, second;/* 0x0007 means user code space *//* 0x0007 表示用戶代碼空間 */// 選擇符0x000F 表示在局部描述符表中描述符索引值=1,即代碼空間。如果段寄存器cs 不等于0x000F// 則表示cs 一定是內核代碼選擇符,是在內核代碼空間,則出錯,顯示此時的cs:eip 值,并顯示信息// “內核中需要數學仿真”,然后進入死機狀態。 if (cs != 0x000F) { printk ("math_emulate: %04x:%08x\n\r", cs, eip); panic ("Math emulation needed in kernel"); }// 取用戶數據區堆棧數據first 和second,顯示這些數據,并給進程設置浮點異常信號SIGFPE。 first = get_fs_byte ((char *) ((*&eip)++)); second = get_fs_byte ((char *) ((*&eip)++)); printk ("%04x:%08x %02x %02x\n\r", cs, eip - 2, first, second); current->signal |= 1 << (SIGFPE - 1);}//// 協處理器出錯處理函數。// 中斷處理程序調用的C 函數,參見(kernel/math/system_call.s,145 行)。voidmath_error (void){// 協處理器指令。(以非等待形式)清除所有異常標志、忙標志和狀態字位7。// __asm__ ("fnclex");
_asm fnclex;// 如果上個任務使用過協處理器,則向上個任務發送協處理器異常信號。 if (last_task_used_math) last_task_used_math->signal |= 1 << (SIGFPE - 1);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -