0xc020f4bc <yosemite_setup_arch+160>: lwz r10,12(r29)
0xc020f4c0 <yosemite_setup_arch+164>: lis r9,-16352
0xc020f4c4 <yosemite_setup_arch+168>: stw r0,8068(r11)
0xc020f4c8 <yosemite_setup_arch+172>: lwz r0,84(r26)
0xc020f4cc <yosemite_setup_arch+176>: stw r10,8136(r9)
0xc020f4d0 <yosemite_setup_arch+180>: mtctr r0
0xc020f4d4 <yosemite_setup_arch+184>: bctrl
0xc020f4d8 <yosemite_setup_arch+188>: li r5,64
0xc020f4dc <yosemite_setup_arch+192>: mr r31,r3
0xc020f4e0 <yosemite_setup_arch+196>: lis r4,-4288
0xc020f4e4 <yosemite_setup_arch+200>: li r3,0
0xc020f4e8 <yosemite_setup_arch+204>: bl 0xc000c0f8
<ioremap64>
End of assembler dump.
(gdb)
Once again, we need not be PowerPC assembly language experts to understand what is happening here. Notice the labels associated with the PowerPC bl instruction. This is a function call in PowerPC mnemonics. The symbolic function labels are the important data points. After a cursory analysis, we see several function calls near the start of this assembler listing:
Address | Function |
---|---|
0xc020f438 | ocp_get_one_device() |
0xc020f45c | memcpy() |
0xc020f474 | ocp_get_one_device() |
0xc020f48c | memcpy() |
0xc020f4ac | ibm440gx_get_clocks() |
Listing 14-9 reproduces portions of the source file yosemite.c. Correlating the functions we found in the gdb disassemble output, we see those labels occurring in the function yosemite_set_emacdata(), around the line numbers reported by gdb when the breakpoint at yosemite_setup_arch() was encountered. The key to understanding the anomaly is to notice the subroutine call at the very start of yosemite_setup_arch(). The compiler has inlined the call to yosemite_set_emacdata() instead of generating a function call, as would be expected by simple inspection of the source code. This inlining produced the mismatch in the line numbers when gdb hit the breakpoint. Even though the yosemite_set_emacdata() function was not declared using the inline keyword, GCC inlined the function as a performance optimization.
Listing 14-9. Portions of Source File yosemite.c
109 static void __init yosemite_set_emacdata(void)
110 {
111 struct ocp_def *def;
112 struct ocp_func_emac_data *emacdata;
113
114 /* Set mac_addr and phy mode for each EMAC */
115
116 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
117 emacdata = def->additions;
118 memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
119 emacdata->phy_mode = PHY_MODE_RMII;
120
121 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1);
122 emacdata = def->additions;
123 memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6);
124 emacdata->phy_mode = PHY_MODE_RMII;
125 }
126
...
304
305 static void __init
306 yosemite_setup_arch(void)
307 {
308 yosemite_set_emacdata();
309
310 ibm440gx_get_clocks(&clocks, YOSEMITE_SYSCLK, 6 * 1843200);
311 ocp_sys_info.opb_bus_freq = clocks.opb;
312
313 /* init to some ~sane value until calibrate_delay() runs */
314 loops_per_jiffy = 50000000/HZ;
315
316 /* Setup PCI host bridge */
317 yosemite_setup_hose();
318
319 #ifdef CONFIG_BLK_DEV_INITRD
320 if (initrd_start)
321 ROOT_DEV = Root_RAM0;
322 else
323 #endif
324 #ifdef CONFIG_ROOT_NFS
325 ROOT_DEV = Root_NFS;
326 #else
327 ROOT_DEV = Root_HDA1;
328 #endif
329