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

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3238 | 回復: 8
打印 上一主題 下一主題

[內(nèi)核入門] gcc中內(nèi)嵌匯編 [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2013-11-07 12:09 |只看該作者 |倒序瀏覽
各位大牛,幫忙解析下,如下代碼的含義:
在這里先拜謝了!。

#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")

論壇徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技術(shù)圖書徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44雙子座
日期:2013-12-27 12:32:29雙子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
2 [報告]
發(fā)表于 2013-11-07 13:08 |只看該作者
本帖最后由 asuka2001 于 2013-11-07 13:16 編輯

回復 1# xiaojsj

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

%0對應err, %1對應x,%2對應addr, %3對應 -EFAULT
        "1:        " TUSER(ldr) "        %1,[%2],#0\n"                        \
        "2:\n"                                                        \
這一段是實際的讀取指令,相當于 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之間的代碼不放到上面那條實際讀取指令之后,而是要求gcc放到 fixup段去,它的功能實際上就是

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

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

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

1:, 2:, 3:代表的是標號所處的指令的地址。




   

論壇徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技術(shù)圖書徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44雙子座
日期:2013-12-27 12:32:29雙子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
3 [報告]
發(fā)表于 2013-11-07 13:15 |只看該作者
回復 1# xiaojsj

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

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

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


   

論壇徽章:
0
4 [報告]
發(fā)表于 2013-11-08 09:25 |只看該作者
明白了,謝謝哈,你講的很清楚。回復 3# asuka2001


   

論壇徽章:
0
5 [報告]
發(fā)表于 2013-11-08 09:41 |只看該作者
我另外還有如下一個問題:
就是當去取用戶空間地址上的數(shù)據(jù)時,如果這個時候還真就發(fā)生了異常(譬如這個時候該段地址已經(jīng)不在內(nèi)存中),那程序最終會跑到異常處理代碼中去,并且通過返回值說明剛才的讀取指令發(fā)生了錯誤。

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


   

論壇徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技術(shù)圖書徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44雙子座
日期:2013-12-27 12:32:29雙子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
6 [報告]
發(fā)表于 2013-11-08 10:52 |只看該作者
回復 5# xiaojsj

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

我省略了一些其他的“合法” page fault流程:比如用戶空間的頁被 swap out,mmap的區(qū)域或者分配的內(nèi)存還未實際建立頁表項等。
   

論壇徽章:
0
7 [報告]
發(fā)表于 2013-11-09 09:35 |只看該作者
那如果是后面你說的兩種情況之一:
                 a: 比如用戶空間的頁被 swap out,
                 b: mmap的區(qū)域或者分配的內(nèi)存還未實際建立頁表項等
這個時候又恰巧,有系統(tǒng)調(diào)用,從用戶空間讀取數(shù)據(jù)到內(nèi)核空間,會發(fā)生什么?

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




回復 6# asuka2001


   

論壇徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技術(shù)圖書徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44雙子座
日期:2013-12-27 12:32:29雙子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
8 [報告]
發(fā)表于 2013-11-11 13:35 |只看該作者
回復 7# xiaojsj

這些情況都是可以在當前進程的 mm中查找到合法的 vma:
被 swap out的就讀回來。

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

沒實際分配內(nèi)存的,通過頁分配器分配物理頁框,填好頁表。

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

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

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

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

3. 根據(jù) CPU所處模式,page fault跳轉(zhuǎn)到對應的 __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會跳轉(zhuǎn)到 CPU_DABORT_HANDLER,這個宏在 arch/arm/include/asm中根據(jù) CPU型號定義, 如 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)在進入 c代碼調(diào)用鏈

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

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

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

   

論壇徽章:
0
9 [報告]
發(fā)表于 2013-11-11 19:51 |只看該作者

謝謝!·
回復 8# asuka2001


   
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP