[英]What is exactly happening in Linux page table pointers dereferencing?
我正在尝试研究Linux内核中的页表遍历。 我使用标准方式浏览页表以查找PFN(例如,不是实际代码):
pgd_t *pgd; pte_t *ptep; pte_t pte; pud_t *pud; pmd_t *pmd;
struct page *pagePtr = NULL;
struct mm_struct *mm = current->mm;
pgd = pgd_offset(mm, addr);
pud = getPud(pgd, addr);
pmd = pmd_offset(pud, addr);
ptep = pte_offset_map(pmd, addr);
size_t pfn = pte_pfn(pte);
该系统是
CPU:Intel(R)Core(TM)i7-3770
CPU @ 3.40 GHz
操作系统:Linux Fedora版本22(二十二)内核:4.4.4-200.fc22.x86_64
我试图了解pgd指针如何解除对pud指针的引用。 我将简单的代码放入getPud函数中:
noinline pud_t *getPud(pgd_t *pgdPtr, unsigned long addr).
{
return pud_offset(pgdPtr, addr);
}
并尝试通过objdump进行分解
00000000000000b0 <getPud>:
b0: e8 00 00 00 00 callq b5 <getPud+0x5>
b5: 55 push %rbp
b6: 48 8b 3f mov (%rdi),%rdi
b9: 48 89 e5 mov %rsp,%rbp
bc: ff 14 25 00 00 00 00 callq *0x0
c3: 48 c1 ee 1b shr $0x1b,%rsi
c7: 48 ba 00 00 00 00 00 movabs $0xffff880000000000,%rdx
ce: 88 ff ff
d1: 81 e6 f8 0f 00 00 and $0xff8,%esi
d7: 48 01 d6 add %rdx,%rsi
da: 48 ba 00 f0 ff ff ff movabs $0x3ffffffff000,%rdx
e1: 3f 00 00
e4: 48 21 d0 and %rdx,%rax
e7: 48 01 f0 add %rsi,%rax
ea: 5d pop %rbp
eb: c3 retq
ec: 0f 1f 40 00 nopl 0x0(%rax)
我的汇编知识不足以理解callq *0x0
类的callq *0x0
有人可以说明一下getPud中发生的事情吗?
谢谢
谢尔盖
更新1
我使用objdump反汇编了创建用于浏览页表的LKM(cpes.ko)模块。
>objdump -dr ./cpes.ko
./cpes.ko: file format elf64-x86-64
Disassembly of section .text:
00000000000000b0 <getPud>:
b0: e8 00 00 00 00 callq b5 <getPud+0x5>
b1: R_X86_64_PC32 __fentry__-0x4
b5: 55 push %rbp
b6: 48 8b 3f mov (%rdi),%rdi
b9: 48 89 e5 mov %rsp,%rbp
bc: ff 14 25 00 00 00 00 callq *0x0
bf: R_X86_64_32S pv_mmu_ops+0xf8
c3: 48 c1 ee 1b shr $0x1b,%rsi
c7: 48 ba 00 00 00 00 00 movabs $0xffff880000000000,%rdx
ce: 88 ff ff
d1: 81 e6 f8 0f 00 00 and $0xff8,%esi
d7: 48 01 d6 add %rdx,%rsi
da: 48 ba 00 f0 ff ff ff movabs $0x3ffffffff000,%rdx
e1: 3f 00 00
e4: 48 21 d0 and %rdx,%rax
e7: 48 01 f0 add %rsi,%rax
ea: 5d pop %rbp
eb: c3 retq
ec: 0f 1f 40 00 nopl 0x0(%rax)
您正在查看.o
反汇编,对吗? 不是最终的链接二进制文件? 0x0
地址只是链接器将填充的占位符。(这是通过静态/全局函数指针进行的内存间接调用)。 pud_offset
已内联到您的函数中。
尝试使用objdump -dr
或-dR
来显示重定位条目以及反汇编输出。
或者更好的方法是,查看gcc -S
输出以获取符号名称。 ( -fverbose-asm
有时会很有帮助)。 弄清楚,在命令行make
构建你的文件,并修改它使用-S -o-
代替-c
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.