Last chapter link entry : https://blog.csdn.net/qq_16933601/article/details/104327937
In the last chapter , We analyzed oops Of PC In which function did the value go wrong

This chapter analyzes the function calling process through stack information

1. In the last chapter oops The stack information is shown in the figure below :

 Insert picture description here
9fe0: Represents the original top of the stack SP Register location
9e80: On behalf of the function error SP Register location

2. Let's first analyze the stack information in the figure above , And what kind of process ?

2.1 The kernel is mainly through STMDB and LDMIA Assemble commands to load and unload

(STMDB and LDMIA Assembly Command Reference : http://www.cnblogs.com/lifexy/p/7363208.html)

Every time the kernel enters a function, it passes through STMDB, Put the content value of the last function at the top of the stack sp, And then the top of the stack sp-4.

When something goes wrong with a function in the kernel , The kernel goes through LDMIA, Top the stack sp Print out , And then the top of the stack sp+4, Until we get to the top of the original stack

2.2 Let's look at the picture below 3 Take a function as an example :

 Insert picture description here
if c() When something goes wrong with the function , The kernel will print b() The contents of the function (0x03,LR), Print a() The contents of the function (0x02,LR), until sp Up to the top of the stack

among lr value , Represents the calling relationship of each function

3. Next, we will take the above chapter oops The stack information in

In the last chapter , We find PC value bf000078 stay 26th_segmentfault Driver module first_drv_open() Error in function .

3.1 First look first_drv_open() function , find STMDB On stack lr value , To determine which function is called

 Insert picture description here
As shown in the figure above ,first_drv_open() In the function , adopt stmdb sp!, {r4, r5, fp, ip, lr, pc} Put in 6 It's worth ,
therefore , Return to the value of the previous function lr =c008d888
In the previous chapter , Then we analyze that :
The virtual address of the kernel is c0004000~c03cebf4, therefore c008d888 In a function in the kernel

3.2 Then disassemble the kernel

In the root directory of the kernel source code :

# arm-none-linux-gnueabi-objdump -D vmlinux > vmlinux.txt      //-D: Disassemble all segments     vmlinux: Uncompressed kernel 

3.3 open vmlinux.txt

As shown in the figure below , Search for c008d888:
 Insert picture description here
Turn up , find c008d888 In function chrdev_open() Next :
 Insert picture description here
As shown in the figure above , chrdev_open() Function saved 10 It's worth , therefore , Return to the value of the previous function lr= c0089e48

3.4 Continue to search c0089e48:

 Insert picture description here
Turn up , find c0089e48 In function __dentry_open () Next :
 Insert picture description here
As shown in the figure above , __dentry_open() Function saved 10 It's worth , therefore , Second value lr= c0089f64

3.5 Continue to search c0089f64:

 Insert picture description here
Turn up , find c0089f64 In function nameidata_to_filp() Next :
 Insert picture description here
As shown in the figure above , nameidata_to_filp Function saved 6 It's worth , therefore , Second value lr= c0089fb8

4. Finally, it is concluded that , The calling process of stack information is as follows :

ret_fast_syscall()->
sys_open()->
do_sys_open()->
do_filp_open()->
nameidata_to_filp()->
chrdev_open()->
first_drv_open();