probe-finder.c (95a3e4c4e21de1920a2ddb54bfc57c0af7e2561e) | probe-finder.c (016f262e4fb10c6ecff709317098912f94a21efa) |
---|---|
1/* 2 * probe-finder.c : C expression to kprobe event converter 3 * 4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 172 unchanged lines hidden (view full) --- 181 for (i = 0; i < nfiles; i++) { 182 src = dwarf_filesrc(files, i, NULL, NULL); 183 if (strtailcmp(src, fname) == 0) 184 break; 185 } 186 return src; 187} 188 | 1/* 2 * probe-finder.c : C expression to kprobe event converter 3 * 4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 172 unchanged lines hidden (view full) --- 181 for (i = 0; i < nfiles; i++) { 182 src = dwarf_filesrc(files, i, NULL, NULL); 183 if (strtailcmp(src, fname) == 0) 184 break; 185 } 186 return src; 187} 188 |
189/* Compare diename and tname */ 190static bool die_compare_name(Dwarf_Die *dw_die, const char *tname) 191{ 192 const char *name; 193 name = dwarf_diename(dw_die); 194 DIE_IF(name == NULL); 195 return strcmp(tname, name); 196} 197 198/* Get entry pc(or low pc, 1st entry of ranges) of the die */ 199static Dwarf_Addr die_get_entrypc(Dwarf_Die *dw_die) 200{ 201 Dwarf_Addr epc; 202 int ret; 203 204 ret = dwarf_entrypc(dw_die, &epc); 205 DIE_IF(ret == -1); 206 return epc; 207} 208 209/* Return values for die_find callbacks */ 210enum { 211 DIE_FIND_CB_FOUND = 0, /* End of Search */ 212 DIE_FIND_CB_CHILD = 1, /* Search only children */ 213 DIE_FIND_CB_SIBLING = 2, /* Search only siblings */ 214 DIE_FIND_CB_CONTINUE = 3, /* Search children and siblings */ 215}; 216 217/* Search a child die */ 218static Dwarf_Die *die_find_child(Dwarf_Die *rt_die, 219 int (*callback)(Dwarf_Die *, void *), 220 void *data, Dwarf_Die *die_mem) 221{ 222 Dwarf_Die child_die; 223 int ret; 224 225 ret = dwarf_child(rt_die, die_mem); 226 if (ret != 0) 227 return NULL; 228 229 do { 230 ret = callback(die_mem, data); 231 if (ret == DIE_FIND_CB_FOUND) 232 return die_mem; 233 234 if ((ret & DIE_FIND_CB_CHILD) && 235 die_find_child(die_mem, callback, data, &child_die)) { 236 memcpy(die_mem, &child_die, sizeof(Dwarf_Die)); 237 return die_mem; 238 } 239 } while ((ret & DIE_FIND_CB_SIBLING) && 240 dwarf_siblingof(die_mem, die_mem) == 0); 241 242 return NULL; 243} 244 |
|
189struct __addr_die_search_param { 190 Dwarf_Addr addr; 191 Dwarf_Die *die_mem; 192}; 193 194static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) 195{ 196 struct __addr_die_search_param *ad = data; --- 15 unchanged lines hidden (view full) --- 212 ad.die_mem = die_mem; 213 /* dwarf_getscopes can't find subprogram. */ 214 if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0)) 215 return NULL; 216 else 217 return die_mem; 218} 219 | 245struct __addr_die_search_param { 246 Dwarf_Addr addr; 247 Dwarf_Die *die_mem; 248}; 249 250static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) 251{ 252 struct __addr_die_search_param *ad = data; --- 15 unchanged lines hidden (view full) --- 268 ad.die_mem = die_mem; 269 /* dwarf_getscopes can't find subprogram. */ 270 if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0)) 271 return NULL; 272 else 273 return die_mem; 274} 275 |
220/* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */ 221static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 222 Dwarf_Die *die_mem) | 276/* die_find callback for inline function search */ 277static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) |
223{ | 278{ |
224 Dwarf_Die child_die; 225 int ret; | 279 Dwarf_Addr *addr = data; |
226 | 280 |
227 ret = dwarf_child(sp_die, die_mem); 228 if (ret != 0) 229 return NULL; | 281 if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine && 282 dwarf_haspc(die_mem, *addr)) 283 return DIE_FIND_CB_FOUND; |
230 | 284 |
231 do { 232 if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine && 233 dwarf_haspc(die_mem, addr)) 234 return die_mem; 235 236 if (die_find_inlinefunc(die_mem, addr, &child_die)) { 237 memcpy(die_mem, &child_die, sizeof(Dwarf_Die)); 238 return die_mem; 239 } 240 } while (dwarf_siblingof(die_mem, die_mem) == 0); 241 242 return NULL; | 285 return DIE_FIND_CB_CONTINUE; |
243} 244 | 286} 287 |
245/* Compare diename and tname */ 246static bool die_compare_name(Dwarf_Die *dw_die, const char *tname) | 288/* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */ 289static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 290 Dwarf_Die *die_mem) |
247{ | 291{ |
248 const char *name; 249 name = dwarf_diename(dw_die); 250 DIE_IF(name == NULL); 251 return strcmp(tname, name); | 292 return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); |
252} 253 | 293} 294 |
254/* Get entry pc(or low pc, 1st entry of ranges) of the die */ 255static Dwarf_Addr die_get_entrypc(Dwarf_Die *dw_die) | 295static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) |
256{ | 296{ |
257 Dwarf_Addr epc; 258 int ret; | 297 const char *name = data; 298 int tag; |
259 | 299 |
260 ret = dwarf_entrypc(dw_die, &epc); 261 DIE_IF(ret == -1); 262 return epc; | 300 tag = dwarf_tag(die_mem); 301 if ((tag == DW_TAG_formal_parameter || 302 tag == DW_TAG_variable) && 303 (die_compare_name(die_mem, name) == 0)) 304 return DIE_FIND_CB_FOUND; 305 306 return DIE_FIND_CB_CONTINUE; |
263} 264 | 307} 308 |
265/* Get a variable die */ | 309/* Find a variable called 'name' */ |
266static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name, 267 Dwarf_Die *die_mem) 268{ | 310static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name, 311 Dwarf_Die *die_mem) 312{ |
269 Dwarf_Die child_die; 270 int tag; 271 int ret; 272 273 ret = dwarf_child(sp_die, die_mem); 274 if (ret != 0) 275 return NULL; 276 277 do { 278 tag = dwarf_tag(die_mem); 279 if ((tag == DW_TAG_formal_parameter || 280 tag == DW_TAG_variable) && 281 (die_compare_name(die_mem, name) == 0)) 282 return die_mem; 283 284 if (die_find_variable(die_mem, name, &child_die)) { 285 memcpy(die_mem, &child_die, sizeof(Dwarf_Die)); 286 return die_mem; 287 } 288 } while (dwarf_siblingof(die_mem, die_mem) == 0); 289 290 return NULL; | 313 return die_find_child(sp_die, __die_find_variable_cb, (void *)name, 314 die_mem); |
291} 292 293/* 294 * Probe finder related functions 295 */ 296 297/* Show a location */ 298static void show_location(Dwarf_Op *op, struct probe_finder *pf) --- 529 unchanged lines hidden --- | 315} 316 317/* 318 * Probe finder related functions 319 */ 320 321/* Show a location */ 322static void show_location(Dwarf_Op *op, struct probe_finder *pf) --- 529 unchanged lines hidden --- |