Thanks for the reply of In pt_regs why the value of bp and sp differ so greatly and why bp is smaller than sp
I have found that the ecx stores the esp of stack when sysenter occurs.Then I write the code below
#include<stdio.h>
#include<unistd.h>
pid_t f0() {
int myEsp;
int myEbp;
pid_t pid = fork();
if (pid != 0) {
printf("\n");
asm("movl %%esp, %0\n" : "=rm"(myEsp));
printf("esp is 0x%x\n", myEsp);
asm("movl %%ebp, %0\n" : "=rm"(myEbp));
printf("ebp is 0x%x\n", myEbp);
}
return pid;
}
pid_t f1() {
return f0();
}
pid_t f2() {
return f1();
}
int main(int argc, char* argv[]) {
sleep(5);
pid_t pid = f2();
int myEsp;
int myEbp;
if (pid != 0) {
printf("\n");
asm("movl %%esp, %0\n" : "=rm"(myEsp));
printf("esp is 0x%x\n", myEsp);
asm("movl %%ebp, %0\n" : "=rm"(myEbp));
printf("ebp is 0x%x\n", myEbp);
}
return 0;
}
then set breakpoint at sysexit in entry_SYSENTER_32 of arch/x86/entry/entry_32.S. When I run the above code in debuggable kernel, it stops at sysexit. then I run 'x/128x $ecx', the stack content is printed such as below. The stack content is what I expect as user space data.
(gdb) p/x $ebp
$18 = 0xb7ee5000
(gdb) x/128x $ecx
0xbf827f0c: 0xb7ee5000 0x00000000 0x00000000 0xb7d9bc33
0xbf827f1c: 0x00000001 0xbf828104 0xb7ee5000 0xbf827ff8
0xbf827f2c: 0xb7d9b7e2 0x00000000 0x00000000 0x00000000
0xbf827f3c: 0x00000000 0x00000000 0x00000000 0xbf827fa0
0xbf827f4c: 0x4d0d2200 0x00000080 0xb7ef065c 0xbf827fd4
0xbf827f5c: 0xb7ee5000 0xbf827fe4 0xffffffb4 0xbf827fe4
0xbf827f6c: 0xb7d9b72d 0x00000000 0x00000000 0xbf827f8c
0xbf827f7c: 0xbf827f9c 0x00000000 0x00000001 0xb7ef0490
0xbf827f8c: 0x00000005 0x00000000 0x00000000 0x00000000
0xbf827f9c: 0x00000000 0xb7f2f000 0x00000020 0x00000000
0xbf827fac: 0x4d0d2200 0xb7d9b6db 0x00000000 0x7fffffff
0xbf827fbc: 0x4d0d2200 0xbf827fe4 0xbf827fe4 0x00000000
0xbf827fcc: 0x004d2fcc 0xbf828104 0xb7f2eb80 0xbf827ff8(bp)fork?
0xbf827fdc: 0x004d01e4 0xb7f2f608 0x00000005 0x00000000
0xbf827fec: 0x4d0d2200 0x00000000 0x004d2fcc 0xbf828008(bp)f0
0xbf827ffc: 0x004d024b 0xbf828104 0xb7f2eb80 0xbf828018(bp)f1
0xbf82800c: 0x004d0262 0x00000005 0xb7f08f10 0xbf828038(bp)f2
0xbf82801c: 0x004d0293 0xbf828060 0xb7ef065c 0xb7ef0b00
0xbf82802c: 0x00000001 0xbf828050 0xb7ee5000 0xb7f2f020(bp)main
0xbf82803c: 0xb7ce0519 0xbf829f80 0x00000070 0xb7f2f000
0xbf82804c: 0xb7ce0519 0x00000001 0xbf828104 0xbf82810c
0xbf82805c: 0xbf828070 0xb7ee5000 0x004d0264 0x00000001
0xbf82806c: 0xbf828104 0xb7ee5000 0xbf828104 0xb7f2eb80
0xbf82807c: 0xb7f2f020 0x7614d39c 0xef1dd98c 0x00000000
0xbf82808c: 0x00000000 0x00000000 0xb7f2eb80 0xb7f2f020
0xbf82809c: 0x4d0d2200 0xb7f2fa40 0xb7ce04a6 0xb7ee5000
0xbf8280ac: 0xb7ce05f3 0x00000000 0x004d2ed0 0xbf82810c
0xbf8280bc: 0xb7f2f020 0x00000000 0x00000000 0xb7ce056d
0xbf8280cc: 0x004d2fcc 0x00000001 0x004d00a0 0x00000000
0xbf8280dc: 0x004d00cb 0x004d0264 0x00000001 0xbf828104
0xbf8280ec: 0x00000000 0x00000000 0xb7efca90 0xbf8280fc
0xbf8280fc: 0xb7f2fa40 0x00000001 0xbf829f80 0x00000000
In user space the function call order is main->f2->f1->f0->fork. I have found each ebp's position corresponding to each function, and tags them in above data.But the question is why there is too much stack content data above address 0xbf827fd8, the address which I supposed function fork's ebp is at. and the other question is where is __libc_fork's stack frame since I know fork called it in glibc. The last question is how the ebp get back on the right track as ebp and esp represents the range of each stack frame since the ebp's value is 0xb7ee5000 when I print it. Is there some storys in __kernel_vsyscall or vdso which leads to above result?
ps. the debuggable linux's version is linux-5.12.10
I have debugged a program, use 'stepi' to step into the deepest part of 'fork' routine,here is the code:
│<__kernel_vsyscall+1> push %edx
│<__kernel_vsyscall+2> push %ebp
│<__kernel_vsyscall+3> mov %esp,%ebp
>│<__kernel_vsyscall+5> sysenter
│<__kernel_vsyscall+7> int $0x80
│<__kernel_vsyscall+9> pop %ebp
│<__kernel_vsyscall+10> pop %edx
│<__kernel_vsyscall+11> pop %ecx
│<__kernel_vsyscall+12> ret