亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: gcc中內(nèi)嵌匯編 [打印本頁(yè)]

作者: xiaojsj    時(shí)間: 2013-11-07 12:09
標(biāo)題: gcc中內(nèi)嵌匯編
各位大牛,幫忙解析下,如下代碼的含義:
在這里先拜謝了。!

#define __get_user_asm_word(x,addr,err)                                \
        __asm__ __volatile__(                                        \
        "1:        " TUSER(ldr) "        %1,[%2],#0\n"                        \
        "2:\n"                                                        \
        "        .pushsection .fixup,\"ax\"\n"                        \
        "        .align        2\n"                                        \
        "3:        mov        %0, %3\n"                                \
        "        mov        %1, #0\n"                                \
        "        b        2b\n"                                        \
        "        .popsection\n"                                        \
        "        .pushsection __ex_table,\"a\"\n"                \
        "        .align        3\n"                                        \
        "        .long        1b, 3b\n"                                \
        "        .popsection"                                        \
        : "+r" (err), "=&r" (x)                                        \
        : "r" (addr), "i" (-EFAULT)                                \
        : "cc")

作者: asuka2001    時(shí)間: 2013-11-07 13:08
本帖最后由 asuka2001 于 2013-11-07 13:16 編輯

回復(fù) 1# xiaojsj

對(duì)內(nèi)嵌匯編不算特別熟,大概解釋下:

%0對(duì)應(yīng)err, %1對(duì)應(yīng)x,%2對(duì)應(yīng)addr, %3對(duì)應(yīng) -EFAULT
        "1:        " TUSER(ldr) "        %1,[%2],#0\n"                        \
        "2:\n"                                                        \
這一段是實(shí)際的讀取指令,相當(dāng)于 ldr x, [addr], #0,從地址addr處讀取,并保存到x
        "        .pushsection .fixup,\"ax\"\n"                        \
        "        .align        2\n"                                        \
        "3:        mov        %0, %3\n"                                \
        "        mov        %1, #0\n"                                \
        "        b        2b\n"                                        \
        "        .popsection\n"                                        \
.pushsection到 .popsection之間的代碼不放到上面那條實(shí)際讀取指令之后,而是要求gcc放到 fixup段去,它的功能實(shí)際上就是

err = -EFAULT
goto 2:
        "        .pushsection __ex_table,\"a\"\n"                \
        "        .align        3\n"                                        \
        "        .long        1b, 3b\n"                                \
        "        .popsection"                                        \
同樣,.pushsection到 .popsection之間的代碼不放到上面那條實(shí)際讀取指令之后,要求gcc放到 __ext_table段去,它是保存了兩個(gè)地址,其含義相當(dāng)于

struct exception_table_entry
{
        unsigned long insn, fixup;
} entry;
entry.insn = 1:
entry.fixup = 3:

然后把 entry添加到 exception_table中去,如果對(duì)其感興趣,可以查看 search_exception_table()

1:, 2:, 3:代表的是標(biāo)號(hào)所處的指令的地址。




   
作者: asuka2001    時(shí)間: 2013-11-07 13:15
回復(fù) 1# xiaojsj

其中后面這2大堆就是一個(gè)意思,一旦我們執(zhí)行第一條指令出現(xiàn)了 page fault,這個(gè)時(shí)候異常處理流程就會(huì)使用導(dǎo)致異常出現(xiàn)的指令的地址去搜索 exception_table

這個(gè)時(shí)候就能找到我們所保存的 struct exception_table_entry entry,然后異常處理流程會(huì)跳轉(zhuǎn)到 entry.fixup去執(zhí)行。

我們的entry.fixup指向的是標(biāo)號(hào) 3:所處的指令,也就是說(shuō)向 err賦值為 -EFAULT,跳轉(zhuǎn)回標(biāo)號(hào) 2:所處的指令,也就是相當(dāng)于從第一條指令后面繼續(xù)執(zhí)行了。


   
作者: xiaojsj    時(shí)間: 2013-11-08 09:25
明白了,謝謝哈,你講的很清楚。回復(fù) 3# asuka2001


   
作者: xiaojsj    時(shí)間: 2013-11-08 09:41
我另外還有如下一個(gè)問(wèn)題:
就是當(dāng)去取用戶空間地址上的數(shù)據(jù)時(shí),如果這個(gè)時(shí)候還真就發(fā)生了異常(譬如這個(gè)時(shí)候該段地址已經(jīng)不在內(nèi)存中),那程序最終會(huì)跑到異常處理代碼中去,并且通過(guò)返回值說(shuō)明剛才的讀取指令發(fā)生了錯(cuò)誤。

我的疑問(wèn)就是:當(dāng)異常發(fā)生后,知道了要讀取的用戶空間地址不在內(nèi)存,為什么不把該地址的內(nèi)容加載到內(nèi)存,從而避免只是簡(jiǎn)單的錯(cuò)誤返回呢?
如果是錯(cuò)誤返回了,是不是此次系統(tǒng)調(diào)用就失敗了?
那如果該用戶空間的地址真不在內(nèi)存了,那該系統(tǒng)調(diào)用,是不是就會(huì)一直都失敗呢?
回復(fù) 3# asuka2001


   
作者: asuka2001    時(shí)間: 2013-11-08 10:52
回復(fù) 5# xiaojsj

讓你誤解了,這里我是為了說(shuō)明后面兩段代碼的作用,只以用戶空間程序傳給了內(nèi)核非法的虛擬地址為例:即虛擬地址不在合法的 vma中,也不在用戶?蓴U(kuò)展區(qū)域。

我省略了一些其他的“合法” page fault流程:比如用戶空間的頁(yè)被 swap out,mmap的區(qū)域或者分配的內(nèi)存還未實(shí)際建立頁(yè)表項(xiàng)等。
   
作者: xiaojsj    時(shí)間: 2013-11-09 09:35
那如果是后面你說(shuō)的兩種情況之一:
                 a: 比如用戶空間的頁(yè)被 swap out,
                 b: mmap的區(qū)域或者分配的內(nèi)存還未實(shí)際建立頁(yè)表項(xiàng)等
這個(gè)時(shí)候又恰巧,有系統(tǒng)調(diào)用,從用戶空間讀取數(shù)據(jù)到內(nèi)核空間,會(huì)發(fā)生什么?

能大概把這個(gè)情景模式分析一下嗎?
謝謝!




回復(fù) 6# asuka2001


   
作者: asuka2001    時(shí)間: 2013-11-11 13:35
回復(fù) 7# xiaojsj

這些情況都是可以在當(dāng)前進(jìn)程的 mm中查找到合法的 vma:
被 swap out的就讀回來(lái)。

mmap的就通過(guò) vm_operations_struct->fault() 去讀取內(nèi)容好了。如果是文件,那么一般就會(huì)調(diào)用到 filemap_fault(),然后從 vma找到對(duì)應(yīng)的 address_space,已經(jīng)在 page cache里的,建立個(gè)頁(yè)表映射過(guò)去就是,沒(méi)有的就調(diào)用 address_space->a_ops->readpage()讀取到 page cache,然后同上。

沒(méi)實(shí)際分配內(nèi)存的,通過(guò)頁(yè)分配器分配物理頁(yè)框,填好頁(yè)表。

然后直接返回到你執(zhí)行的指令處繼續(xù)運(yùn)行就OK。

詳細(xì)細(xì)節(jié)我也沒(méi)有去研究,你如果有興趣,也可以直接去看代碼

1. 向量跳轉(zhuǎn)表位于 arch/arm/kernel/entry_armv.S中的 __vectors_start與 __vectors_end間,page fault對(duì)應(yīng)的是 vector_dabt

2. early_trap_init() [arch/arm/kernel/traps.c]負(fù)責(zé)將向量跳轉(zhuǎn)表搬運(yùn)到0xFFFF0000

3. 根據(jù) CPU所處模式,page fault跳轉(zhuǎn)到對(duì)應(yīng)的 __dabt_usr, __dabt_svc, 或者 __dabt_invalid [arch/arm/kernel/entry_armv.S]

4. __dabt_usr, __dabt_svc均調(diào)用 dabt_helper [arch/arm/kernel/entry_armv.S], 注意這里 r2保存有 pt_regs

5. dabt_helper會(huì)跳轉(zhuǎn)到 CPU_DABORT_HANDLER,這個(gè)宏在 arch/arm/include/asm中根據(jù) CPU型號(hào)定義, 如 v7_early_abort() [arch/arm/mm/abort_ev7.S]

6. v7_early_abort()讀取 cpsr寄存器, 將 FAR (Fault Address Register), FSR (Fault Status Register)保存到 r0, r1; 然后調(diào)用 do_DataAbort() [arch/arm/mm/fault.c]

7. 現(xiàn)在進(jìn)入 c代碼調(diào)用鏈

do_DataAbort(): 根據(jù) fsr查詢對(duì)應(yīng)的異常處理函數(shù)表 fsr_info[]
        inf->fn(): 調(diào)用該處理函數(shù)
                do_page_fault()
                        __do_page_fault()
                                handle_mm_fault()

從 handle_mm_fault() [mm/memory.c]開(kāi)始脫離體系相關(guān)代碼

handle_mm_fault()
        handle_pte_fault()
                do_linear_fault()
                do_anonymous_page()
                do_nonlinear_fault()
                do_swap_page()

   
作者: xiaojsj    時(shí)間: 2013-11-11 19:51

謝謝!·
回復(fù) 8# asuka2001


   




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2