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 ---