static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
/* Attempt an OF style match first */
if (of_driver_match_device(dev, drv))
return 1;
/* Then try to match against the id table */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0); <<===panic 在这里,通过上面的汇编看得出来r0是入口参数 const char *cs, 对应这里的实参是pdev->name, 说明pdev->name是一个无效的地址,所以trigger panic
}
/* match against the id table first */
if (pdrv->id_table)
c032d688: e5914038 ldr r4, [r1, #56]
* and compare it against the name of the driver. Return whether they match
* or not.
*/
static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
c032d68c: e2405008 sub r5, r0, #8 ; 0x8 <==通过上面的的汇编看到r0实际上是platform_match的入口参数,这里通过,to-platform_device这个函数将dev下面存的平台数据取出来,然后送给r5,此时r5就是pdev的机构体,因为panic的前一刻r5的值没有被变过,所以我们可以在stack里面找出其值来。
struct platform_driver *pdrv = to_platform_driver(drv);
/* match against the id table first */
if (pdrv->id_table)
c032d690: e3540000 cmp r4, #0 ; 0x0
c032d694: 1a000006 bne c032d6b4 c032d698: ea00000d b c032d6d4 static const struct platform_device_id *platform_match_id(
const struct platform_device_id *id,
struct platform_device *pdev)
{
while (id->name[0]) {
if (strcmp(pdev->name, id->name) == 0) {
c032d69c: e5950000 ldr r0, [r5] <==注意看这里将r5的值取出来给r0,实际上也是pdev->name,所以通过这里看来第一次这里用到了这个内存单元的值是正确的,因为假设整个结构出问题的话,那么code运行到这里就应该出错了,所以排除第一种可能。
c032d6a0: ebfd5dbf bl c0284da4
c032d6a4: e3500000 cmp r0, #0 ; 0x0
pdev->id_entry = id;
c032d6a8: 05854168 streq r4, [r5, #360]
c032d6ac: 0a000005 beq c032d6c8 return id;
}
id++;
c032d6b0: e2844018 add r4, r4, #24 ; 0x18
static const struct platform_device_id *platform_match_id(
const struct platform_device_id *id,
struct platform_device *pdev)
{
while (id->name[0]) {
c032d6b4: e5d43000 ldrb r3, [r4]
if (strcmp(pdev->name, id->name) == 0) {
c032d6b8: e1a01004 mov r1, r4
static const struct platform_device_id *platform_match_id(
const struct platform_device_id *id,
struct platform_device *pdev)
{
while (id->name[0]) {
c032d6bc: e3530000 cmp r3, #0 ; 0x0
c032d6c0: 1afffff5 bne c032d69c pdev->id_entry = id;
return id;
}
id++;
}
return NULL;
c032d6c4: e1a04003 mov r4, r3
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
/* match against the id table first */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
c032d6c8: e2540000 subs r0, r4, #0 ; 0x0
c032d6cc: 13a00001 movne r0, #1 ; 0x1
c032d6d0: e8bd8070 pop {r4, r5, r6, pc}
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
c032d6d4: e5100008 ldr r0, [r0, #-8] <==这里是将 r0-8位置的内存的值取出来(一个pdev结构的指针)放到r0寄存器中,这里实际是在给strcmp 准备实参, 我们可以看下pdev这个结构体如下,name是结构体的第一个成员变量,那么pdev的指针实际上就是指向pdev->name, 那么通过这里看出pdev结构体来自r0-8的位置,因为我们上面有两种假设:一是pdev这个结构本身就出问题了,另外一个就是pdev里面的一个成员错了,继续往上推。
struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
..........
};
c032d6d8: e5911000 ldr r1, [r1]
c032d6dc: ebfd5db0 bl c0284da4 <==这里将跳转到strcmp执行相应的code
c032d6e0: e2700001 rsbs r0, r0, #1 ; 0x1 <==实际上c032d6e0就是panic时的LR
c032d6e4: 33a00000 movcc r0, #0 ; 0x0