Linux页表指针解引用中到底发生了什么?
我试图研究Linux内核中的页表遍历。我使用标准的方式遍历页面表来查找PFN(例如,不是实际的代码): 系统是 CPU:Intel(R)Core(TM)i7-3770 CPU@3.40GHz OS:LinuxFedoraRelease22内核:4.4.4-200.fc22.x86_64 我试图理解pgd指针是如何解引用到pud指针的。我将简单的代码放入getPud函数中:Linux页表指针解引用中到底发生了什么?,linux,assembly,linux-kernel,page-tables,Linux,Assembly,Linux Kernel,Page Tables,我试图研究Linux内核中的页表遍历。我使用标准的方式遍历页面表来查找PFN(例如,不是实际的代码): 系统是 CPU:Intel(R)Core(TM)i7-3770 CPU@3.40GHz OS:LinuxFedoraRelease22内核:4.4.4-200.fc22.x86_64 我试图理解pgd指针是如何解引用到pud指针的。我将简单的代码放入getPud函数中: noinline pud_t *getPud(pgd_t *pgdPtr, unsigned long addr). {
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)
最好查一下来源。正如您所看到的,这里有一些魔力。您看到的是
.o
的反汇编,对吗?不是最终链接的二进制文件?0x0
地址只是链接器将填充的占位符。(这是通过静态/全局函数指针进行的内存间接调用)pud_offset
正在内联到您的函数中
尝试objdump-dr
或-dr
在反汇编输出中显示重定位条目
或者更好的方法是,查看
gcc-S
输出以获得符号名称。(-fverbose asm
有时很有用)。找出使用make
构建文件的命令行,并将其修改为使用-S-o-
而不是-c
谢谢您的评论。我用反汇编细节更新开始主题。这是否意味着呼叫*0x0意味着呼叫pv\u mmu\u ops?这个pv\u mmu\u ops
做什么?为什么内核使用如此复杂的过程来进行解引用?Sergey@shs_sf:注意0xf8
与pv\u mmu\u ops
的偏移量,这是重新定位的一部分。函数指针的结构在内核中非常常见。e、 文件系统通过调用一个函数来注册自己,以供内核的其余部分使用,该函数向内核中跟踪所有可用文件系统的部分注册函数指针的结构。装载该FS类型的FS操作会导致通过这些函数指针进行调用。
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)
>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)