Commit 22c91aa23547a4363fd2a9ffddde95c899ac8aa0

Authored by Ingo Molnar

Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/g…

…it/jolsa/perf into perf/urgent

Pull perf/urgent fixes from Jiri Olsa:

 * Fix perf probe to find correct variable DIE (Masami Hiramatsu)

 * Fix a segfault in perf probe if asked for variable it doesn't find (Masami Hiramatsu)

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

Showing 2 changed files Inline Diff

tools/perf/util/dwarf-aux.c
1 /* 1 /*
2 * dwarf-aux.c : libdw auxiliary interfaces 2 * dwarf-aux.c : libdw auxiliary interfaces
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or 6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version. 7 * (at your option) any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 * 17 *
18 */ 18 */
19 19
20 #include <stdbool.h> 20 #include <stdbool.h>
21 #include "util.h" 21 #include "util.h"
22 #include "debug.h" 22 #include "debug.h"
23 #include "dwarf-aux.h" 23 #include "dwarf-aux.h"
24 24
25 /** 25 /**
26 * cu_find_realpath - Find the realpath of the target file 26 * cu_find_realpath - Find the realpath of the target file
27 * @cu_die: A DIE(dwarf information entry) of CU(compilation Unit) 27 * @cu_die: A DIE(dwarf information entry) of CU(compilation Unit)
28 * @fname: The tail filename of the target file 28 * @fname: The tail filename of the target file
29 * 29 *
30 * Find the real(long) path of @fname in @cu_die. 30 * Find the real(long) path of @fname in @cu_die.
31 */ 31 */
32 const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname) 32 const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
33 { 33 {
34 Dwarf_Files *files; 34 Dwarf_Files *files;
35 size_t nfiles, i; 35 size_t nfiles, i;
36 const char *src = NULL; 36 const char *src = NULL;
37 int ret; 37 int ret;
38 38
39 if (!fname) 39 if (!fname)
40 return NULL; 40 return NULL;
41 41
42 ret = dwarf_getsrcfiles(cu_die, &files, &nfiles); 42 ret = dwarf_getsrcfiles(cu_die, &files, &nfiles);
43 if (ret != 0) 43 if (ret != 0)
44 return NULL; 44 return NULL;
45 45
46 for (i = 0; i < nfiles; i++) { 46 for (i = 0; i < nfiles; i++) {
47 src = dwarf_filesrc(files, i, NULL, NULL); 47 src = dwarf_filesrc(files, i, NULL, NULL);
48 if (strtailcmp(src, fname) == 0) 48 if (strtailcmp(src, fname) == 0)
49 break; 49 break;
50 } 50 }
51 if (i == nfiles) 51 if (i == nfiles)
52 return NULL; 52 return NULL;
53 return src; 53 return src;
54 } 54 }
55 55
56 /** 56 /**
57 * cu_get_comp_dir - Get the path of compilation directory 57 * cu_get_comp_dir - Get the path of compilation directory
58 * @cu_die: a CU DIE 58 * @cu_die: a CU DIE
59 * 59 *
60 * Get the path of compilation directory of given @cu_die. 60 * Get the path of compilation directory of given @cu_die.
61 * Since this depends on DW_AT_comp_dir, older gcc will not 61 * Since this depends on DW_AT_comp_dir, older gcc will not
62 * embedded it. In that case, this returns NULL. 62 * embedded it. In that case, this returns NULL.
63 */ 63 */
64 const char *cu_get_comp_dir(Dwarf_Die *cu_die) 64 const char *cu_get_comp_dir(Dwarf_Die *cu_die)
65 { 65 {
66 Dwarf_Attribute attr; 66 Dwarf_Attribute attr;
67 if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL) 67 if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
68 return NULL; 68 return NULL;
69 return dwarf_formstring(&attr); 69 return dwarf_formstring(&attr);
70 } 70 }
71 71
72 /** 72 /**
73 * cu_find_lineinfo - Get a line number and file name for given address 73 * cu_find_lineinfo - Get a line number and file name for given address
74 * @cu_die: a CU DIE 74 * @cu_die: a CU DIE
75 * @addr: An address 75 * @addr: An address
76 * @fname: a pointer which returns the file name string 76 * @fname: a pointer which returns the file name string
77 * @lineno: a pointer which returns the line number 77 * @lineno: a pointer which returns the line number
78 * 78 *
79 * Find a line number and file name for @addr in @cu_die. 79 * Find a line number and file name for @addr in @cu_die.
80 */ 80 */
81 int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr, 81 int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr,
82 const char **fname, int *lineno) 82 const char **fname, int *lineno)
83 { 83 {
84 Dwarf_Line *line; 84 Dwarf_Line *line;
85 Dwarf_Addr laddr; 85 Dwarf_Addr laddr;
86 86
87 line = dwarf_getsrc_die(cu_die, (Dwarf_Addr)addr); 87 line = dwarf_getsrc_die(cu_die, (Dwarf_Addr)addr);
88 if (line && dwarf_lineaddr(line, &laddr) == 0 && 88 if (line && dwarf_lineaddr(line, &laddr) == 0 &&
89 addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) { 89 addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) {
90 *fname = dwarf_linesrc(line, NULL, NULL); 90 *fname = dwarf_linesrc(line, NULL, NULL);
91 if (!*fname) 91 if (!*fname)
92 /* line number is useless without filename */ 92 /* line number is useless without filename */
93 *lineno = 0; 93 *lineno = 0;
94 } 94 }
95 95
96 return *lineno ?: -ENOENT; 96 return *lineno ?: -ENOENT;
97 } 97 }
98 98
99 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data); 99 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data);
100 100
101 /** 101 /**
102 * cu_walk_functions_at - Walk on function DIEs at given address 102 * cu_walk_functions_at - Walk on function DIEs at given address
103 * @cu_die: A CU DIE 103 * @cu_die: A CU DIE
104 * @addr: An address 104 * @addr: An address
105 * @callback: A callback which called with found DIEs 105 * @callback: A callback which called with found DIEs
106 * @data: A user data 106 * @data: A user data
107 * 107 *
108 * Walk on function DIEs at given @addr in @cu_die. Passed DIEs 108 * Walk on function DIEs at given @addr in @cu_die. Passed DIEs
109 * should be subprogram or inlined-subroutines. 109 * should be subprogram or inlined-subroutines.
110 */ 110 */
111 int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, 111 int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
112 int (*callback)(Dwarf_Die *, void *), void *data) 112 int (*callback)(Dwarf_Die *, void *), void *data)
113 { 113 {
114 Dwarf_Die die_mem; 114 Dwarf_Die die_mem;
115 Dwarf_Die *sc_die; 115 Dwarf_Die *sc_die;
116 int ret = -ENOENT; 116 int ret = -ENOENT;
117 117
118 /* Inlined function could be recursive. Trace it until fail */ 118 /* Inlined function could be recursive. Trace it until fail */
119 for (sc_die = die_find_realfunc(cu_die, addr, &die_mem); 119 for (sc_die = die_find_realfunc(cu_die, addr, &die_mem);
120 sc_die != NULL; 120 sc_die != NULL;
121 sc_die = die_find_child(sc_die, __die_find_inline_cb, &addr, 121 sc_die = die_find_child(sc_die, __die_find_inline_cb, &addr,
122 &die_mem)) { 122 &die_mem)) {
123 ret = callback(sc_die, data); 123 ret = callback(sc_die, data);
124 if (ret) 124 if (ret)
125 break; 125 break;
126 } 126 }
127 127
128 return ret; 128 return ret;
129 129
130 } 130 }
131 131
132 /** 132 /**
133 * die_compare_name - Compare diename and tname 133 * die_compare_name - Compare diename and tname
134 * @dw_die: a DIE 134 * @dw_die: a DIE
135 * @tname: a string of target name 135 * @tname: a string of target name
136 * 136 *
137 * Compare the name of @dw_die and @tname. Return false if @dw_die has no name. 137 * Compare the name of @dw_die and @tname. Return false if @dw_die has no name.
138 */ 138 */
139 bool die_compare_name(Dwarf_Die *dw_die, const char *tname) 139 bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
140 { 140 {
141 const char *name; 141 const char *name;
142 name = dwarf_diename(dw_die); 142 name = dwarf_diename(dw_die);
143 return name ? (strcmp(tname, name) == 0) : false; 143 return name ? (strcmp(tname, name) == 0) : false;
144 } 144 }
145 145
146 /** 146 /**
147 * die_get_call_lineno - Get callsite line number of inline-function instance 147 * die_get_call_lineno - Get callsite line number of inline-function instance
148 * @in_die: a DIE of an inlined function instance 148 * @in_die: a DIE of an inlined function instance
149 * 149 *
150 * Get call-site line number of @in_die. This means from where the inline 150 * Get call-site line number of @in_die. This means from where the inline
151 * function is called. 151 * function is called.
152 */ 152 */
153 int die_get_call_lineno(Dwarf_Die *in_die) 153 int die_get_call_lineno(Dwarf_Die *in_die)
154 { 154 {
155 Dwarf_Attribute attr; 155 Dwarf_Attribute attr;
156 Dwarf_Word ret; 156 Dwarf_Word ret;
157 157
158 if (!dwarf_attr(in_die, DW_AT_call_line, &attr)) 158 if (!dwarf_attr(in_die, DW_AT_call_line, &attr))
159 return -ENOENT; 159 return -ENOENT;
160 160
161 dwarf_formudata(&attr, &ret); 161 dwarf_formudata(&attr, &ret);
162 return (int)ret; 162 return (int)ret;
163 } 163 }
164 164
165 /** 165 /**
166 * die_get_type - Get type DIE 166 * die_get_type - Get type DIE
167 * @vr_die: a DIE of a variable 167 * @vr_die: a DIE of a variable
168 * @die_mem: where to store a type DIE 168 * @die_mem: where to store a type DIE
169 * 169 *
170 * Get a DIE of the type of given variable (@vr_die), and store 170 * Get a DIE of the type of given variable (@vr_die), and store
171 * it to die_mem. Return NULL if fails to get a type DIE. 171 * it to die_mem. Return NULL if fails to get a type DIE.
172 */ 172 */
173 Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 173 Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
174 { 174 {
175 Dwarf_Attribute attr; 175 Dwarf_Attribute attr;
176 176
177 if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) && 177 if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) &&
178 dwarf_formref_die(&attr, die_mem)) 178 dwarf_formref_die(&attr, die_mem))
179 return die_mem; 179 return die_mem;
180 else 180 else
181 return NULL; 181 return NULL;
182 } 182 }
183 183
184 /* Get a type die, but skip qualifiers */ 184 /* Get a type die, but skip qualifiers */
185 static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 185 static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
186 { 186 {
187 int tag; 187 int tag;
188 188
189 do { 189 do {
190 vr_die = die_get_type(vr_die, die_mem); 190 vr_die = die_get_type(vr_die, die_mem);
191 if (!vr_die) 191 if (!vr_die)
192 break; 192 break;
193 tag = dwarf_tag(vr_die); 193 tag = dwarf_tag(vr_die);
194 } while (tag == DW_TAG_const_type || 194 } while (tag == DW_TAG_const_type ||
195 tag == DW_TAG_restrict_type || 195 tag == DW_TAG_restrict_type ||
196 tag == DW_TAG_volatile_type || 196 tag == DW_TAG_volatile_type ||
197 tag == DW_TAG_shared_type); 197 tag == DW_TAG_shared_type);
198 198
199 return vr_die; 199 return vr_die;
200 } 200 }
201 201
202 /** 202 /**
203 * die_get_real_type - Get a type die, but skip qualifiers and typedef 203 * die_get_real_type - Get a type die, but skip qualifiers and typedef
204 * @vr_die: a DIE of a variable 204 * @vr_die: a DIE of a variable
205 * @die_mem: where to store a type DIE 205 * @die_mem: where to store a type DIE
206 * 206 *
207 * Get a DIE of the type of given variable (@vr_die), and store 207 * Get a DIE of the type of given variable (@vr_die), and store
208 * it to die_mem. Return NULL if fails to get a type DIE. 208 * it to die_mem. Return NULL if fails to get a type DIE.
209 * If the type is qualifiers (e.g. const) or typedef, this skips it 209 * If the type is qualifiers (e.g. const) or typedef, this skips it
210 * and tries to find real type (structure or basic types, e.g. int). 210 * and tries to find real type (structure or basic types, e.g. int).
211 */ 211 */
212 Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 212 Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
213 { 213 {
214 do { 214 do {
215 vr_die = __die_get_real_type(vr_die, die_mem); 215 vr_die = __die_get_real_type(vr_die, die_mem);
216 } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef); 216 } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef);
217 217
218 return vr_die; 218 return vr_die;
219 } 219 }
220 220
221 /* Get attribute and translate it as a udata */ 221 /* Get attribute and translate it as a udata */
222 static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name, 222 static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
223 Dwarf_Word *result) 223 Dwarf_Word *result)
224 { 224 {
225 Dwarf_Attribute attr; 225 Dwarf_Attribute attr;
226 226
227 if (dwarf_attr(tp_die, attr_name, &attr) == NULL || 227 if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
228 dwarf_formudata(&attr, result) != 0) 228 dwarf_formudata(&attr, result) != 0)
229 return -ENOENT; 229 return -ENOENT;
230 230
231 return 0; 231 return 0;
232 } 232 }
233 233
234 /* Get attribute and translate it as a sdata */ 234 /* Get attribute and translate it as a sdata */
235 static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name, 235 static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name,
236 Dwarf_Sword *result) 236 Dwarf_Sword *result)
237 { 237 {
238 Dwarf_Attribute attr; 238 Dwarf_Attribute attr;
239 239
240 if (dwarf_attr(tp_die, attr_name, &attr) == NULL || 240 if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
241 dwarf_formsdata(&attr, result) != 0) 241 dwarf_formsdata(&attr, result) != 0)
242 return -ENOENT; 242 return -ENOENT;
243 243
244 return 0; 244 return 0;
245 } 245 }
246 246
247 /** 247 /**
248 * die_is_signed_type - Check whether a type DIE is signed or not 248 * die_is_signed_type - Check whether a type DIE is signed or not
249 * @tp_die: a DIE of a type 249 * @tp_die: a DIE of a type
250 * 250 *
251 * Get the encoding of @tp_die and return true if the encoding 251 * Get the encoding of @tp_die and return true if the encoding
252 * is signed. 252 * is signed.
253 */ 253 */
254 bool die_is_signed_type(Dwarf_Die *tp_die) 254 bool die_is_signed_type(Dwarf_Die *tp_die)
255 { 255 {
256 Dwarf_Word ret; 256 Dwarf_Word ret;
257 257
258 if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret)) 258 if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
259 return false; 259 return false;
260 260
261 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed || 261 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
262 ret == DW_ATE_signed_fixed); 262 ret == DW_ATE_signed_fixed);
263 } 263 }
264 264
265 /** 265 /**
266 * die_is_func_def - Ensure that this DIE is a subprogram and definition 266 * die_is_func_def - Ensure that this DIE is a subprogram and definition
267 * @dw_die: a DIE 267 * @dw_die: a DIE
268 * 268 *
269 * Ensure that this DIE is a subprogram and NOT a declaration. This 269 * Ensure that this DIE is a subprogram and NOT a declaration. This
270 * returns true if @dw_die is a function definition. 270 * returns true if @dw_die is a function definition.
271 **/ 271 **/
272 bool die_is_func_def(Dwarf_Die *dw_die) 272 bool die_is_func_def(Dwarf_Die *dw_die)
273 { 273 {
274 Dwarf_Attribute attr; 274 Dwarf_Attribute attr;
275 275
276 return (dwarf_tag(dw_die) == DW_TAG_subprogram && 276 return (dwarf_tag(dw_die) == DW_TAG_subprogram &&
277 dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL); 277 dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL);
278 } 278 }
279 279
280 /** 280 /**
281 * die_get_data_member_location - Get the data-member offset 281 * die_get_data_member_location - Get the data-member offset
282 * @mb_die: a DIE of a member of a data structure 282 * @mb_die: a DIE of a member of a data structure
283 * @offs: The offset of the member in the data structure 283 * @offs: The offset of the member in the data structure
284 * 284 *
285 * Get the offset of @mb_die in the data structure including @mb_die, and 285 * Get the offset of @mb_die in the data structure including @mb_die, and
286 * stores result offset to @offs. If any error occurs this returns errno. 286 * stores result offset to @offs. If any error occurs this returns errno.
287 */ 287 */
288 int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs) 288 int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
289 { 289 {
290 Dwarf_Attribute attr; 290 Dwarf_Attribute attr;
291 Dwarf_Op *expr; 291 Dwarf_Op *expr;
292 size_t nexpr; 292 size_t nexpr;
293 int ret; 293 int ret;
294 294
295 if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL) 295 if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
296 return -ENOENT; 296 return -ENOENT;
297 297
298 if (dwarf_formudata(&attr, offs) != 0) { 298 if (dwarf_formudata(&attr, offs) != 0) {
299 /* DW_AT_data_member_location should be DW_OP_plus_uconst */ 299 /* DW_AT_data_member_location should be DW_OP_plus_uconst */
300 ret = dwarf_getlocation(&attr, &expr, &nexpr); 300 ret = dwarf_getlocation(&attr, &expr, &nexpr);
301 if (ret < 0 || nexpr == 0) 301 if (ret < 0 || nexpr == 0)
302 return -ENOENT; 302 return -ENOENT;
303 303
304 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) { 304 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
305 pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n", 305 pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
306 expr[0].atom, nexpr); 306 expr[0].atom, nexpr);
307 return -ENOTSUP; 307 return -ENOTSUP;
308 } 308 }
309 *offs = (Dwarf_Word)expr[0].number; 309 *offs = (Dwarf_Word)expr[0].number;
310 } 310 }
311 return 0; 311 return 0;
312 } 312 }
313 313
314 /* Get the call file index number in CU DIE */ 314 /* Get the call file index number in CU DIE */
315 static int die_get_call_fileno(Dwarf_Die *in_die) 315 static int die_get_call_fileno(Dwarf_Die *in_die)
316 { 316 {
317 Dwarf_Sword idx; 317 Dwarf_Sword idx;
318 318
319 if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0) 319 if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0)
320 return (int)idx; 320 return (int)idx;
321 else 321 else
322 return -ENOENT; 322 return -ENOENT;
323 } 323 }
324 324
325 /* Get the declared file index number in CU DIE */ 325 /* Get the declared file index number in CU DIE */
326 static int die_get_decl_fileno(Dwarf_Die *pdie) 326 static int die_get_decl_fileno(Dwarf_Die *pdie)
327 { 327 {
328 Dwarf_Sword idx; 328 Dwarf_Sword idx;
329 329
330 if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0) 330 if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0)
331 return (int)idx; 331 return (int)idx;
332 else 332 else
333 return -ENOENT; 333 return -ENOENT;
334 } 334 }
335 335
336 /** 336 /**
337 * die_get_call_file - Get callsite file name of inlined function instance 337 * die_get_call_file - Get callsite file name of inlined function instance
338 * @in_die: a DIE of an inlined function instance 338 * @in_die: a DIE of an inlined function instance
339 * 339 *
340 * Get call-site file name of @in_die. This means from which file the inline 340 * Get call-site file name of @in_die. This means from which file the inline
341 * function is called. 341 * function is called.
342 */ 342 */
343 const char *die_get_call_file(Dwarf_Die *in_die) 343 const char *die_get_call_file(Dwarf_Die *in_die)
344 { 344 {
345 Dwarf_Die cu_die; 345 Dwarf_Die cu_die;
346 Dwarf_Files *files; 346 Dwarf_Files *files;
347 int idx; 347 int idx;
348 348
349 idx = die_get_call_fileno(in_die); 349 idx = die_get_call_fileno(in_die);
350 if (idx < 0 || !dwarf_diecu(in_die, &cu_die, NULL, NULL) || 350 if (idx < 0 || !dwarf_diecu(in_die, &cu_die, NULL, NULL) ||
351 dwarf_getsrcfiles(&cu_die, &files, NULL) != 0) 351 dwarf_getsrcfiles(&cu_die, &files, NULL) != 0)
352 return NULL; 352 return NULL;
353 353
354 return dwarf_filesrc(files, idx, NULL, NULL); 354 return dwarf_filesrc(files, idx, NULL, NULL);
355 } 355 }
356 356
357 357
358 /** 358 /**
359 * die_find_child - Generic DIE search function in DIE tree 359 * die_find_child - Generic DIE search function in DIE tree
360 * @rt_die: a root DIE 360 * @rt_die: a root DIE
361 * @callback: a callback function 361 * @callback: a callback function
362 * @data: a user data passed to the callback function 362 * @data: a user data passed to the callback function
363 * @die_mem: a buffer for result DIE 363 * @die_mem: a buffer for result DIE
364 * 364 *
365 * Trace DIE tree from @rt_die and call @callback for each child DIE. 365 * Trace DIE tree from @rt_die and call @callback for each child DIE.
366 * If @callback returns DIE_FIND_CB_END, this stores the DIE into 366 * If @callback returns DIE_FIND_CB_END, this stores the DIE into
367 * @die_mem and returns it. If @callback returns DIE_FIND_CB_CONTINUE, 367 * @die_mem and returns it. If @callback returns DIE_FIND_CB_CONTINUE,
368 * this continues to trace the tree. Optionally, @callback can return 368 * this continues to trace the tree. Optionally, @callback can return
369 * DIE_FIND_CB_CHILD and DIE_FIND_CB_SIBLING, those means trace only 369 * DIE_FIND_CB_CHILD and DIE_FIND_CB_SIBLING, those means trace only
370 * the children and trace only the siblings respectively. 370 * the children and trace only the siblings respectively.
371 * Returns NULL if @callback can't find any appropriate DIE. 371 * Returns NULL if @callback can't find any appropriate DIE.
372 */ 372 */
373 Dwarf_Die *die_find_child(Dwarf_Die *rt_die, 373 Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
374 int (*callback)(Dwarf_Die *, void *), 374 int (*callback)(Dwarf_Die *, void *),
375 void *data, Dwarf_Die *die_mem) 375 void *data, Dwarf_Die *die_mem)
376 { 376 {
377 Dwarf_Die child_die; 377 Dwarf_Die child_die;
378 int ret; 378 int ret;
379 379
380 ret = dwarf_child(rt_die, die_mem); 380 ret = dwarf_child(rt_die, die_mem);
381 if (ret != 0) 381 if (ret != 0)
382 return NULL; 382 return NULL;
383 383
384 do { 384 do {
385 ret = callback(die_mem, data); 385 ret = callback(die_mem, data);
386 if (ret == DIE_FIND_CB_END) 386 if (ret == DIE_FIND_CB_END)
387 return die_mem; 387 return die_mem;
388 388
389 if ((ret & DIE_FIND_CB_CHILD) && 389 if ((ret & DIE_FIND_CB_CHILD) &&
390 die_find_child(die_mem, callback, data, &child_die)) { 390 die_find_child(die_mem, callback, data, &child_die)) {
391 memcpy(die_mem, &child_die, sizeof(Dwarf_Die)); 391 memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
392 return die_mem; 392 return die_mem;
393 } 393 }
394 } while ((ret & DIE_FIND_CB_SIBLING) && 394 } while ((ret & DIE_FIND_CB_SIBLING) &&
395 dwarf_siblingof(die_mem, die_mem) == 0); 395 dwarf_siblingof(die_mem, die_mem) == 0);
396 396
397 return NULL; 397 return NULL;
398 } 398 }
399 399
400 struct __addr_die_search_param { 400 struct __addr_die_search_param {
401 Dwarf_Addr addr; 401 Dwarf_Addr addr;
402 Dwarf_Die *die_mem; 402 Dwarf_Die *die_mem;
403 }; 403 };
404 404
405 /* die_find callback for non-inlined function search */ 405 /* die_find callback for non-inlined function search */
406 static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) 406 static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
407 { 407 {
408 struct __addr_die_search_param *ad = data; 408 struct __addr_die_search_param *ad = data;
409 409
410 /* 410 /*
411 * Since a declaration entry doesn't has given pc, this always returns 411 * Since a declaration entry doesn't has given pc, this always returns
412 * function definition entry. 412 * function definition entry.
413 */ 413 */
414 if (dwarf_tag(fn_die) == DW_TAG_subprogram && 414 if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
415 dwarf_haspc(fn_die, ad->addr)) { 415 dwarf_haspc(fn_die, ad->addr)) {
416 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die)); 416 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
417 return DWARF_CB_ABORT; 417 return DWARF_CB_ABORT;
418 } 418 }
419 return DWARF_CB_OK; 419 return DWARF_CB_OK;
420 } 420 }
421 421
422 /** 422 /**
423 * die_find_realfunc - Search a non-inlined function at given address 423 * die_find_realfunc - Search a non-inlined function at given address
424 * @cu_die: a CU DIE which including @addr 424 * @cu_die: a CU DIE which including @addr
425 * @addr: target address 425 * @addr: target address
426 * @die_mem: a buffer for result DIE 426 * @die_mem: a buffer for result DIE
427 * 427 *
428 * Search a non-inlined function DIE which includes @addr. Stores the 428 * Search a non-inlined function DIE which includes @addr. Stores the
429 * DIE to @die_mem and returns it if found. Returns NULL if failed. 429 * DIE to @die_mem and returns it if found. Returns NULL if failed.
430 */ 430 */
431 Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 431 Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
432 Dwarf_Die *die_mem) 432 Dwarf_Die *die_mem)
433 { 433 {
434 struct __addr_die_search_param ad; 434 struct __addr_die_search_param ad;
435 ad.addr = addr; 435 ad.addr = addr;
436 ad.die_mem = die_mem; 436 ad.die_mem = die_mem;
437 /* dwarf_getscopes can't find subprogram. */ 437 /* dwarf_getscopes can't find subprogram. */
438 if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0)) 438 if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
439 return NULL; 439 return NULL;
440 else 440 else
441 return die_mem; 441 return die_mem;
442 } 442 }
443 443
444 /* die_find callback for inline function search */ 444 /* die_find callback for inline function search */
445 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) 445 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
446 { 446 {
447 Dwarf_Addr *addr = data; 447 Dwarf_Addr *addr = data;
448 448
449 if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine && 449 if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
450 dwarf_haspc(die_mem, *addr)) 450 dwarf_haspc(die_mem, *addr))
451 return DIE_FIND_CB_END; 451 return DIE_FIND_CB_END;
452 452
453 return DIE_FIND_CB_CONTINUE; 453 return DIE_FIND_CB_CONTINUE;
454 } 454 }
455 455
456 /** 456 /**
457 * die_find_top_inlinefunc - Search the top inlined function at given address 457 * die_find_top_inlinefunc - Search the top inlined function at given address
458 * @sp_die: a subprogram DIE which including @addr 458 * @sp_die: a subprogram DIE which including @addr
459 * @addr: target address 459 * @addr: target address
460 * @die_mem: a buffer for result DIE 460 * @die_mem: a buffer for result DIE
461 * 461 *
462 * Search an inlined function DIE which includes @addr. Stores the 462 * Search an inlined function DIE which includes @addr. Stores the
463 * DIE to @die_mem and returns it if found. Returns NULL if failed. 463 * DIE to @die_mem and returns it if found. Returns NULL if failed.
464 * Even if several inlined functions are expanded recursively, this 464 * Even if several inlined functions are expanded recursively, this
465 * doesn't trace it down, and returns the topmost one. 465 * doesn't trace it down, and returns the topmost one.
466 */ 466 */
467 Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 467 Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
468 Dwarf_Die *die_mem) 468 Dwarf_Die *die_mem)
469 { 469 {
470 return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); 470 return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
471 } 471 }
472 472
473 /** 473 /**
474 * die_find_inlinefunc - Search an inlined function at given address 474 * die_find_inlinefunc - Search an inlined function at given address
475 * @sp_die: a subprogram DIE which including @addr 475 * @sp_die: a subprogram DIE which including @addr
476 * @addr: target address 476 * @addr: target address
477 * @die_mem: a buffer for result DIE 477 * @die_mem: a buffer for result DIE
478 * 478 *
479 * Search an inlined function DIE which includes @addr. Stores the 479 * Search an inlined function DIE which includes @addr. Stores the
480 * DIE to @die_mem and returns it if found. Returns NULL if failed. 480 * DIE to @die_mem and returns it if found. Returns NULL if failed.
481 * If several inlined functions are expanded recursively, this trace 481 * If several inlined functions are expanded recursively, this trace
482 * it down and returns deepest one. 482 * it down and returns deepest one.
483 */ 483 */
484 Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 484 Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
485 Dwarf_Die *die_mem) 485 Dwarf_Die *die_mem)
486 { 486 {
487 Dwarf_Die tmp_die; 487 Dwarf_Die tmp_die;
488 488
489 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die); 489 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
490 if (!sp_die) 490 if (!sp_die)
491 return NULL; 491 return NULL;
492 492
493 /* Inlined function could be recursive. Trace it until fail */ 493 /* Inlined function could be recursive. Trace it until fail */
494 while (sp_die) { 494 while (sp_die) {
495 memcpy(die_mem, sp_die, sizeof(Dwarf_Die)); 495 memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
496 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, 496 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
497 &tmp_die); 497 &tmp_die);
498 } 498 }
499 499
500 return die_mem; 500 return die_mem;
501 } 501 }
502 502
503 struct __instance_walk_param { 503 struct __instance_walk_param {
504 void *addr; 504 void *addr;
505 int (*callback)(Dwarf_Die *, void *); 505 int (*callback)(Dwarf_Die *, void *);
506 void *data; 506 void *data;
507 int retval; 507 int retval;
508 }; 508 };
509 509
510 static int __die_walk_instances_cb(Dwarf_Die *inst, void *data) 510 static int __die_walk_instances_cb(Dwarf_Die *inst, void *data)
511 { 511 {
512 struct __instance_walk_param *iwp = data; 512 struct __instance_walk_param *iwp = data;
513 Dwarf_Attribute attr_mem; 513 Dwarf_Attribute attr_mem;
514 Dwarf_Die origin_mem; 514 Dwarf_Die origin_mem;
515 Dwarf_Attribute *attr; 515 Dwarf_Attribute *attr;
516 Dwarf_Die *origin; 516 Dwarf_Die *origin;
517 int tmp; 517 int tmp;
518 518
519 attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem); 519 attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem);
520 if (attr == NULL) 520 if (attr == NULL)
521 return DIE_FIND_CB_CONTINUE; 521 return DIE_FIND_CB_CONTINUE;
522 522
523 origin = dwarf_formref_die(attr, &origin_mem); 523 origin = dwarf_formref_die(attr, &origin_mem);
524 if (origin == NULL || origin->addr != iwp->addr) 524 if (origin == NULL || origin->addr != iwp->addr)
525 return DIE_FIND_CB_CONTINUE; 525 return DIE_FIND_CB_CONTINUE;
526 526
527 /* Ignore redundant instances */ 527 /* Ignore redundant instances */
528 if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) { 528 if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) {
529 dwarf_decl_line(origin, &tmp); 529 dwarf_decl_line(origin, &tmp);
530 if (die_get_call_lineno(inst) == tmp) { 530 if (die_get_call_lineno(inst) == tmp) {
531 tmp = die_get_decl_fileno(origin); 531 tmp = die_get_decl_fileno(origin);
532 if (die_get_call_fileno(inst) == tmp) 532 if (die_get_call_fileno(inst) == tmp)
533 return DIE_FIND_CB_CONTINUE; 533 return DIE_FIND_CB_CONTINUE;
534 } 534 }
535 } 535 }
536 536
537 iwp->retval = iwp->callback(inst, iwp->data); 537 iwp->retval = iwp->callback(inst, iwp->data);
538 538
539 return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE; 539 return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE;
540 } 540 }
541 541
542 /** 542 /**
543 * die_walk_instances - Walk on instances of given DIE 543 * die_walk_instances - Walk on instances of given DIE
544 * @or_die: an abstract original DIE 544 * @or_die: an abstract original DIE
545 * @callback: a callback function which is called with instance DIE 545 * @callback: a callback function which is called with instance DIE
546 * @data: user data 546 * @data: user data
547 * 547 *
548 * Walk on the instances of give @in_die. @in_die must be an inlined function 548 * Walk on the instances of give @in_die. @in_die must be an inlined function
549 * declartion. This returns the return value of @callback if it returns 549 * declartion. This returns the return value of @callback if it returns
550 * non-zero value, or -ENOENT if there is no instance. 550 * non-zero value, or -ENOENT if there is no instance.
551 */ 551 */
552 int die_walk_instances(Dwarf_Die *or_die, int (*callback)(Dwarf_Die *, void *), 552 int die_walk_instances(Dwarf_Die *or_die, int (*callback)(Dwarf_Die *, void *),
553 void *data) 553 void *data)
554 { 554 {
555 Dwarf_Die cu_die; 555 Dwarf_Die cu_die;
556 Dwarf_Die die_mem; 556 Dwarf_Die die_mem;
557 struct __instance_walk_param iwp = { 557 struct __instance_walk_param iwp = {
558 .addr = or_die->addr, 558 .addr = or_die->addr,
559 .callback = callback, 559 .callback = callback,
560 .data = data, 560 .data = data,
561 .retval = -ENOENT, 561 .retval = -ENOENT,
562 }; 562 };
563 563
564 if (dwarf_diecu(or_die, &cu_die, NULL, NULL) == NULL) 564 if (dwarf_diecu(or_die, &cu_die, NULL, NULL) == NULL)
565 return -ENOENT; 565 return -ENOENT;
566 566
567 die_find_child(&cu_die, __die_walk_instances_cb, &iwp, &die_mem); 567 die_find_child(&cu_die, __die_walk_instances_cb, &iwp, &die_mem);
568 568
569 return iwp.retval; 569 return iwp.retval;
570 } 570 }
571 571
572 /* Line walker internal parameters */ 572 /* Line walker internal parameters */
573 struct __line_walk_param { 573 struct __line_walk_param {
574 bool recursive; 574 bool recursive;
575 line_walk_callback_t callback; 575 line_walk_callback_t callback;
576 void *data; 576 void *data;
577 int retval; 577 int retval;
578 }; 578 };
579 579
580 static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data) 580 static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
581 { 581 {
582 struct __line_walk_param *lw = data; 582 struct __line_walk_param *lw = data;
583 Dwarf_Addr addr = 0; 583 Dwarf_Addr addr = 0;
584 const char *fname; 584 const char *fname;
585 int lineno; 585 int lineno;
586 586
587 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) { 587 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
588 fname = die_get_call_file(in_die); 588 fname = die_get_call_file(in_die);
589 lineno = die_get_call_lineno(in_die); 589 lineno = die_get_call_lineno(in_die);
590 if (fname && lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) { 590 if (fname && lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) {
591 lw->retval = lw->callback(fname, lineno, addr, lw->data); 591 lw->retval = lw->callback(fname, lineno, addr, lw->data);
592 if (lw->retval != 0) 592 if (lw->retval != 0)
593 return DIE_FIND_CB_END; 593 return DIE_FIND_CB_END;
594 } 594 }
595 } 595 }
596 if (!lw->recursive) 596 if (!lw->recursive)
597 /* Don't need to search recursively */ 597 /* Don't need to search recursively */
598 return DIE_FIND_CB_SIBLING; 598 return DIE_FIND_CB_SIBLING;
599 599
600 if (addr) { 600 if (addr) {
601 fname = dwarf_decl_file(in_die); 601 fname = dwarf_decl_file(in_die);
602 if (fname && dwarf_decl_line(in_die, &lineno) == 0) { 602 if (fname && dwarf_decl_line(in_die, &lineno) == 0) {
603 lw->retval = lw->callback(fname, lineno, addr, lw->data); 603 lw->retval = lw->callback(fname, lineno, addr, lw->data);
604 if (lw->retval != 0) 604 if (lw->retval != 0)
605 return DIE_FIND_CB_END; 605 return DIE_FIND_CB_END;
606 } 606 }
607 } 607 }
608 608
609 /* Continue to search nested inlined function call-sites */ 609 /* Continue to search nested inlined function call-sites */
610 return DIE_FIND_CB_CONTINUE; 610 return DIE_FIND_CB_CONTINUE;
611 } 611 }
612 612
613 /* Walk on lines of blocks included in given DIE */ 613 /* Walk on lines of blocks included in given DIE */
614 static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive, 614 static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive,
615 line_walk_callback_t callback, void *data) 615 line_walk_callback_t callback, void *data)
616 { 616 {
617 struct __line_walk_param lw = { 617 struct __line_walk_param lw = {
618 .recursive = recursive, 618 .recursive = recursive,
619 .callback = callback, 619 .callback = callback,
620 .data = data, 620 .data = data,
621 .retval = 0, 621 .retval = 0,
622 }; 622 };
623 Dwarf_Die die_mem; 623 Dwarf_Die die_mem;
624 Dwarf_Addr addr; 624 Dwarf_Addr addr;
625 const char *fname; 625 const char *fname;
626 int lineno; 626 int lineno;
627 627
628 /* Handle function declaration line */ 628 /* Handle function declaration line */
629 fname = dwarf_decl_file(sp_die); 629 fname = dwarf_decl_file(sp_die);
630 if (fname && dwarf_decl_line(sp_die, &lineno) == 0 && 630 if (fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
631 dwarf_entrypc(sp_die, &addr) == 0) { 631 dwarf_entrypc(sp_die, &addr) == 0) {
632 lw.retval = callback(fname, lineno, addr, data); 632 lw.retval = callback(fname, lineno, addr, data);
633 if (lw.retval != 0) 633 if (lw.retval != 0)
634 goto done; 634 goto done;
635 } 635 }
636 die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem); 636 die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem);
637 done: 637 done:
638 return lw.retval; 638 return lw.retval;
639 } 639 }
640 640
641 static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data) 641 static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
642 { 642 {
643 struct __line_walk_param *lw = data; 643 struct __line_walk_param *lw = data;
644 644
645 lw->retval = __die_walk_funclines(sp_die, true, lw->callback, lw->data); 645 lw->retval = __die_walk_funclines(sp_die, true, lw->callback, lw->data);
646 if (lw->retval != 0) 646 if (lw->retval != 0)
647 return DWARF_CB_ABORT; 647 return DWARF_CB_ABORT;
648 648
649 return DWARF_CB_OK; 649 return DWARF_CB_OK;
650 } 650 }
651 651
652 /** 652 /**
653 * die_walk_lines - Walk on lines inside given DIE 653 * die_walk_lines - Walk on lines inside given DIE
654 * @rt_die: a root DIE (CU, subprogram or inlined_subroutine) 654 * @rt_die: a root DIE (CU, subprogram or inlined_subroutine)
655 * @callback: callback routine 655 * @callback: callback routine
656 * @data: user data 656 * @data: user data
657 * 657 *
658 * Walk on all lines inside given @rt_die and call @callback on each line. 658 * Walk on all lines inside given @rt_die and call @callback on each line.
659 * If the @rt_die is a function, walk only on the lines inside the function, 659 * If the @rt_die is a function, walk only on the lines inside the function,
660 * otherwise @rt_die must be a CU DIE. 660 * otherwise @rt_die must be a CU DIE.
661 * Note that this walks not only dwarf line list, but also function entries 661 * Note that this walks not only dwarf line list, but also function entries
662 * and inline call-site. 662 * and inline call-site.
663 */ 663 */
664 int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data) 664 int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
665 { 665 {
666 Dwarf_Lines *lines; 666 Dwarf_Lines *lines;
667 Dwarf_Line *line; 667 Dwarf_Line *line;
668 Dwarf_Addr addr; 668 Dwarf_Addr addr;
669 const char *fname; 669 const char *fname;
670 int lineno, ret = 0; 670 int lineno, ret = 0;
671 Dwarf_Die die_mem, *cu_die; 671 Dwarf_Die die_mem, *cu_die;
672 size_t nlines, i; 672 size_t nlines, i;
673 673
674 /* Get the CU die */ 674 /* Get the CU die */
675 if (dwarf_tag(rt_die) != DW_TAG_compile_unit) 675 if (dwarf_tag(rt_die) != DW_TAG_compile_unit)
676 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL); 676 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL);
677 else 677 else
678 cu_die = rt_die; 678 cu_die = rt_die;
679 if (!cu_die) { 679 if (!cu_die) {
680 pr_debug2("Failed to get CU from given DIE.\n"); 680 pr_debug2("Failed to get CU from given DIE.\n");
681 return -EINVAL; 681 return -EINVAL;
682 } 682 }
683 683
684 /* Get lines list in the CU */ 684 /* Get lines list in the CU */
685 if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) { 685 if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) {
686 pr_debug2("Failed to get source lines on this CU.\n"); 686 pr_debug2("Failed to get source lines on this CU.\n");
687 return -ENOENT; 687 return -ENOENT;
688 } 688 }
689 pr_debug2("Get %zd lines from this CU\n", nlines); 689 pr_debug2("Get %zd lines from this CU\n", nlines);
690 690
691 /* Walk on the lines on lines list */ 691 /* Walk on the lines on lines list */
692 for (i = 0; i < nlines; i++) { 692 for (i = 0; i < nlines; i++) {
693 line = dwarf_onesrcline(lines, i); 693 line = dwarf_onesrcline(lines, i);
694 if (line == NULL || 694 if (line == NULL ||
695 dwarf_lineno(line, &lineno) != 0 || 695 dwarf_lineno(line, &lineno) != 0 ||
696 dwarf_lineaddr(line, &addr) != 0) { 696 dwarf_lineaddr(line, &addr) != 0) {
697 pr_debug2("Failed to get line info. " 697 pr_debug2("Failed to get line info. "
698 "Possible error in debuginfo.\n"); 698 "Possible error in debuginfo.\n");
699 continue; 699 continue;
700 } 700 }
701 /* Filter lines based on address */ 701 /* Filter lines based on address */
702 if (rt_die != cu_die) 702 if (rt_die != cu_die)
703 /* 703 /*
704 * Address filtering 704 * Address filtering
705 * The line is included in given function, and 705 * The line is included in given function, and
706 * no inline block includes it. 706 * no inline block includes it.
707 */ 707 */
708 if (!dwarf_haspc(rt_die, addr) || 708 if (!dwarf_haspc(rt_die, addr) ||
709 die_find_inlinefunc(rt_die, addr, &die_mem)) 709 die_find_inlinefunc(rt_die, addr, &die_mem))
710 continue; 710 continue;
711 /* Get source line */ 711 /* Get source line */
712 fname = dwarf_linesrc(line, NULL, NULL); 712 fname = dwarf_linesrc(line, NULL, NULL);
713 713
714 ret = callback(fname, lineno, addr, data); 714 ret = callback(fname, lineno, addr, data);
715 if (ret != 0) 715 if (ret != 0)
716 return ret; 716 return ret;
717 } 717 }
718 718
719 /* 719 /*
720 * Dwarf lines doesn't include function declarations and inlined 720 * Dwarf lines doesn't include function declarations and inlined
721 * subroutines. We have to check functions list or given function. 721 * subroutines. We have to check functions list or given function.
722 */ 722 */
723 if (rt_die != cu_die) 723 if (rt_die != cu_die)
724 /* 724 /*
725 * Don't need walk functions recursively, because nested 725 * Don't need walk functions recursively, because nested
726 * inlined functions don't have lines of the specified DIE. 726 * inlined functions don't have lines of the specified DIE.
727 */ 727 */
728 ret = __die_walk_funclines(rt_die, false, callback, data); 728 ret = __die_walk_funclines(rt_die, false, callback, data);
729 else { 729 else {
730 struct __line_walk_param param = { 730 struct __line_walk_param param = {
731 .callback = callback, 731 .callback = callback,
732 .data = data, 732 .data = data,
733 .retval = 0, 733 .retval = 0,
734 }; 734 };
735 dwarf_getfuncs(cu_die, __die_walk_culines_cb, &param, 0); 735 dwarf_getfuncs(cu_die, __die_walk_culines_cb, &param, 0);
736 ret = param.retval; 736 ret = param.retval;
737 } 737 }
738 738
739 return ret; 739 return ret;
740 } 740 }
741 741
742 struct __find_variable_param { 742 struct __find_variable_param {
743 const char *name; 743 const char *name;
744 Dwarf_Addr addr; 744 Dwarf_Addr addr;
745 }; 745 };
746 746
747 static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) 747 static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
748 { 748 {
749 struct __find_variable_param *fvp = data; 749 struct __find_variable_param *fvp = data;
750 Dwarf_Attribute attr;
750 int tag; 751 int tag;
751 752
752 tag = dwarf_tag(die_mem); 753 tag = dwarf_tag(die_mem);
753 if ((tag == DW_TAG_formal_parameter || 754 if ((tag == DW_TAG_formal_parameter ||
754 tag == DW_TAG_variable) && 755 tag == DW_TAG_variable) &&
755 die_compare_name(die_mem, fvp->name)) 756 die_compare_name(die_mem, fvp->name) &&
757 /* Does the DIE have location information or external instance? */
758 (dwarf_attr(die_mem, DW_AT_external, &attr) ||
759 dwarf_attr(die_mem, DW_AT_location, &attr)))
756 return DIE_FIND_CB_END; 760 return DIE_FIND_CB_END;
757
758 if (dwarf_haspc(die_mem, fvp->addr)) 761 if (dwarf_haspc(die_mem, fvp->addr))
759 return DIE_FIND_CB_CONTINUE; 762 return DIE_FIND_CB_CONTINUE;
760 else 763 else
761 return DIE_FIND_CB_SIBLING; 764 return DIE_FIND_CB_SIBLING;
762 } 765 }
763 766
764 /** 767 /**
765 * die_find_variable_at - Find a given name variable at given address 768 * die_find_variable_at - Find a given name variable at given address
766 * @sp_die: a function DIE 769 * @sp_die: a function DIE
767 * @name: variable name 770 * @name: variable name
768 * @addr: address 771 * @addr: address
769 * @die_mem: a buffer for result DIE 772 * @die_mem: a buffer for result DIE
770 * 773 *
771 * Find a variable DIE called @name at @addr in @sp_die. 774 * Find a variable DIE called @name at @addr in @sp_die.
772 */ 775 */
773 Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, 776 Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
774 Dwarf_Addr addr, Dwarf_Die *die_mem) 777 Dwarf_Addr addr, Dwarf_Die *die_mem)
775 { 778 {
776 struct __find_variable_param fvp = { .name = name, .addr = addr}; 779 struct __find_variable_param fvp = { .name = name, .addr = addr};
777 780
778 return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp, 781 return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
779 die_mem); 782 die_mem);
780 } 783 }
781 784
782 static int __die_find_member_cb(Dwarf_Die *die_mem, void *data) 785 static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
783 { 786 {
784 const char *name = data; 787 const char *name = data;
785 788
786 if ((dwarf_tag(die_mem) == DW_TAG_member) && 789 if ((dwarf_tag(die_mem) == DW_TAG_member) &&
787 die_compare_name(die_mem, name)) 790 die_compare_name(die_mem, name))
788 return DIE_FIND_CB_END; 791 return DIE_FIND_CB_END;
789 792
790 return DIE_FIND_CB_SIBLING; 793 return DIE_FIND_CB_SIBLING;
791 } 794 }
792 795
793 /** 796 /**
794 * die_find_member - Find a given name member in a data structure 797 * die_find_member - Find a given name member in a data structure
795 * @st_die: a data structure type DIE 798 * @st_die: a data structure type DIE
796 * @name: member name 799 * @name: member name
797 * @die_mem: a buffer for result DIE 800 * @die_mem: a buffer for result DIE
798 * 801 *
799 * Find a member DIE called @name in @st_die. 802 * Find a member DIE called @name in @st_die.
800 */ 803 */
801 Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, 804 Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
802 Dwarf_Die *die_mem) 805 Dwarf_Die *die_mem)
803 { 806 {
804 return die_find_child(st_die, __die_find_member_cb, (void *)name, 807 return die_find_child(st_die, __die_find_member_cb, (void *)name,
805 die_mem); 808 die_mem);
806 } 809 }
807 810
808 /** 811 /**
809 * die_get_typename - Get the name of given variable DIE 812 * die_get_typename - Get the name of given variable DIE
810 * @vr_die: a variable DIE 813 * @vr_die: a variable DIE
811 * @buf: a buffer for result type name 814 * @buf: a buffer for result type name
812 * @len: a max-length of @buf 815 * @len: a max-length of @buf
813 * 816 *
814 * Get the name of @vr_die and stores it to @buf. Return the actual length 817 * Get the name of @vr_die and stores it to @buf. Return the actual length
815 * of type name if succeeded. Return -E2BIG if @len is not enough long, and 818 * of type name if succeeded. Return -E2BIG if @len is not enough long, and
816 * Return -ENOENT if failed to find type name. 819 * Return -ENOENT if failed to find type name.
817 * Note that the result will stores typedef name if possible, and stores 820 * Note that the result will stores typedef name if possible, and stores
818 * "*(function_type)" if the type is a function pointer. 821 * "*(function_type)" if the type is a function pointer.
819 */ 822 */
820 int die_get_typename(Dwarf_Die *vr_die, char *buf, int len) 823 int die_get_typename(Dwarf_Die *vr_die, char *buf, int len)
821 { 824 {
822 Dwarf_Die type; 825 Dwarf_Die type;
823 int tag, ret, ret2; 826 int tag, ret, ret2;
824 const char *tmp = ""; 827 const char *tmp = "";
825 828
826 if (__die_get_real_type(vr_die, &type) == NULL) 829 if (__die_get_real_type(vr_die, &type) == NULL)
827 return -ENOENT; 830 return -ENOENT;
828 831
829 tag = dwarf_tag(&type); 832 tag = dwarf_tag(&type);
830 if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type) 833 if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)
831 tmp = "*"; 834 tmp = "*";
832 else if (tag == DW_TAG_subroutine_type) { 835 else if (tag == DW_TAG_subroutine_type) {
833 /* Function pointer */ 836 /* Function pointer */
834 ret = snprintf(buf, len, "(function_type)"); 837 ret = snprintf(buf, len, "(function_type)");
835 return (ret >= len) ? -E2BIG : ret; 838 return (ret >= len) ? -E2BIG : ret;
836 } else { 839 } else {
837 if (!dwarf_diename(&type)) 840 if (!dwarf_diename(&type))
838 return -ENOENT; 841 return -ENOENT;
839 if (tag == DW_TAG_union_type) 842 if (tag == DW_TAG_union_type)
840 tmp = "union "; 843 tmp = "union ";
841 else if (tag == DW_TAG_structure_type) 844 else if (tag == DW_TAG_structure_type)
842 tmp = "struct "; 845 tmp = "struct ";
843 else if (tag == DW_TAG_enumeration_type) 846 else if (tag == DW_TAG_enumeration_type)
844 tmp = "enum "; 847 tmp = "enum ";
845 /* Write a base name */ 848 /* Write a base name */
846 ret = snprintf(buf, len, "%s%s", tmp, dwarf_diename(&type)); 849 ret = snprintf(buf, len, "%s%s", tmp, dwarf_diename(&type));
847 return (ret >= len) ? -E2BIG : ret; 850 return (ret >= len) ? -E2BIG : ret;
848 } 851 }
849 ret = die_get_typename(&type, buf, len); 852 ret = die_get_typename(&type, buf, len);
850 if (ret > 0) { 853 if (ret > 0) {
851 ret2 = snprintf(buf + ret, len - ret, "%s", tmp); 854 ret2 = snprintf(buf + ret, len - ret, "%s", tmp);
852 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret; 855 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
853 } 856 }
854 return ret; 857 return ret;
855 } 858 }
856 859
857 /** 860 /**
858 * die_get_varname - Get the name and type of given variable DIE 861 * die_get_varname - Get the name and type of given variable DIE
859 * @vr_die: a variable DIE 862 * @vr_die: a variable DIE
860 * @buf: a buffer for type and variable name 863 * @buf: a buffer for type and variable name
861 * @len: the max-length of @buf 864 * @len: the max-length of @buf
862 * 865 *
863 * Get the name and type of @vr_die and stores it in @buf as "type\tname". 866 * Get the name and type of @vr_die and stores it in @buf as "type\tname".
864 */ 867 */
865 int die_get_varname(Dwarf_Die *vr_die, char *buf, int len) 868 int die_get_varname(Dwarf_Die *vr_die, char *buf, int len)
866 { 869 {
867 int ret, ret2; 870 int ret, ret2;
868 871
869 ret = die_get_typename(vr_die, buf, len); 872 ret = die_get_typename(vr_die, buf, len);
870 if (ret < 0) { 873 if (ret < 0) {
871 pr_debug("Failed to get type, make it unknown.\n"); 874 pr_debug("Failed to get type, make it unknown.\n");
872 ret = snprintf(buf, len, "(unknown_type)"); 875 ret = snprintf(buf, len, "(unknown_type)");
873 } 876 }
874 if (ret > 0) { 877 if (ret > 0) {
875 ret2 = snprintf(buf + ret, len - ret, "\t%s", 878 ret2 = snprintf(buf + ret, len - ret, "\t%s",
876 dwarf_diename(vr_die)); 879 dwarf_diename(vr_die));
877 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret; 880 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
878 } 881 }
879 return ret; 882 return ret;
880 } 883 }
881 884
tools/perf/util/probe-finder.c
1 /* 1 /*
2 * probe-finder.c : C expression to kprobe event converter 2 * probe-finder.c : C expression to kprobe event converter
3 * 3 *
4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 4 * Written by Masami Hiramatsu <mhiramat@redhat.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 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 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 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * 19 *
20 */ 20 */
21 21
22 #include <sys/utsname.h> 22 #include <sys/utsname.h>
23 #include <sys/types.h> 23 #include <sys/types.h>
24 #include <sys/stat.h> 24 #include <sys/stat.h>
25 #include <fcntl.h> 25 #include <fcntl.h>
26 #include <errno.h> 26 #include <errno.h>
27 #include <stdio.h> 27 #include <stdio.h>
28 #include <unistd.h> 28 #include <unistd.h>
29 #include <getopt.h> 29 #include <getopt.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 #include <stdarg.h> 32 #include <stdarg.h>
33 #include <dwarf-regs.h> 33 #include <dwarf-regs.h>
34 34
35 #include <linux/bitops.h> 35 #include <linux/bitops.h>
36 #include "event.h" 36 #include "event.h"
37 #include "dso.h" 37 #include "dso.h"
38 #include "debug.h" 38 #include "debug.h"
39 #include "intlist.h" 39 #include "intlist.h"
40 #include "util.h" 40 #include "util.h"
41 #include "symbol.h" 41 #include "symbol.h"
42 #include "probe-finder.h" 42 #include "probe-finder.h"
43 43
44 /* Kprobe tracer basic type is up to u64 */ 44 /* Kprobe tracer basic type is up to u64 */
45 #define MAX_BASIC_TYPE_BITS 64 45 #define MAX_BASIC_TYPE_BITS 64
46 46
47 /* Dwarf FL wrappers */ 47 /* Dwarf FL wrappers */
48 static char *debuginfo_path; /* Currently dummy */ 48 static char *debuginfo_path; /* Currently dummy */
49 49
50 static const Dwfl_Callbacks offline_callbacks = { 50 static const Dwfl_Callbacks offline_callbacks = {
51 .find_debuginfo = dwfl_standard_find_debuginfo, 51 .find_debuginfo = dwfl_standard_find_debuginfo,
52 .debuginfo_path = &debuginfo_path, 52 .debuginfo_path = &debuginfo_path,
53 53
54 .section_address = dwfl_offline_section_address, 54 .section_address = dwfl_offline_section_address,
55 55
56 /* We use this table for core files too. */ 56 /* We use this table for core files too. */
57 .find_elf = dwfl_build_id_find_elf, 57 .find_elf = dwfl_build_id_find_elf,
58 }; 58 };
59 59
60 /* Get a Dwarf from offline image */ 60 /* Get a Dwarf from offline image */
61 static int debuginfo__init_offline_dwarf(struct debuginfo *dbg, 61 static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
62 const char *path) 62 const char *path)
63 { 63 {
64 int fd; 64 int fd;
65 65
66 fd = open(path, O_RDONLY); 66 fd = open(path, O_RDONLY);
67 if (fd < 0) 67 if (fd < 0)
68 return fd; 68 return fd;
69 69
70 dbg->dwfl = dwfl_begin(&offline_callbacks); 70 dbg->dwfl = dwfl_begin(&offline_callbacks);
71 if (!dbg->dwfl) 71 if (!dbg->dwfl)
72 goto error; 72 goto error;
73 73
74 dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd); 74 dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd);
75 if (!dbg->mod) 75 if (!dbg->mod)
76 goto error; 76 goto error;
77 77
78 dbg->dbg = dwfl_module_getdwarf(dbg->mod, &dbg->bias); 78 dbg->dbg = dwfl_module_getdwarf(dbg->mod, &dbg->bias);
79 if (!dbg->dbg) 79 if (!dbg->dbg)
80 goto error; 80 goto error;
81 81
82 return 0; 82 return 0;
83 error: 83 error:
84 if (dbg->dwfl) 84 if (dbg->dwfl)
85 dwfl_end(dbg->dwfl); 85 dwfl_end(dbg->dwfl);
86 else 86 else
87 close(fd); 87 close(fd);
88 memset(dbg, 0, sizeof(*dbg)); 88 memset(dbg, 0, sizeof(*dbg));
89 89
90 return -ENOENT; 90 return -ENOENT;
91 } 91 }
92 92
93 static struct debuginfo *__debuginfo__new(const char *path) 93 static struct debuginfo *__debuginfo__new(const char *path)
94 { 94 {
95 struct debuginfo *dbg = zalloc(sizeof(*dbg)); 95 struct debuginfo *dbg = zalloc(sizeof(*dbg));
96 if (!dbg) 96 if (!dbg)
97 return NULL; 97 return NULL;
98 98
99 if (debuginfo__init_offline_dwarf(dbg, path) < 0) 99 if (debuginfo__init_offline_dwarf(dbg, path) < 0)
100 zfree(&dbg); 100 zfree(&dbg);
101 if (dbg) 101 if (dbg)
102 pr_debug("Open Debuginfo file: %s\n", path); 102 pr_debug("Open Debuginfo file: %s\n", path);
103 return dbg; 103 return dbg;
104 } 104 }
105 105
106 enum dso_binary_type distro_dwarf_types[] = { 106 enum dso_binary_type distro_dwarf_types[] = {
107 DSO_BINARY_TYPE__FEDORA_DEBUGINFO, 107 DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
108 DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, 108 DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
109 DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO, 109 DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
110 DSO_BINARY_TYPE__BUILDID_DEBUGINFO, 110 DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
111 DSO_BINARY_TYPE__NOT_FOUND, 111 DSO_BINARY_TYPE__NOT_FOUND,
112 }; 112 };
113 113
114 struct debuginfo *debuginfo__new(const char *path) 114 struct debuginfo *debuginfo__new(const char *path)
115 { 115 {
116 enum dso_binary_type *type; 116 enum dso_binary_type *type;
117 char buf[PATH_MAX], nil = '\0'; 117 char buf[PATH_MAX], nil = '\0';
118 struct dso *dso; 118 struct dso *dso;
119 struct debuginfo *dinfo = NULL; 119 struct debuginfo *dinfo = NULL;
120 120
121 /* Try to open distro debuginfo files */ 121 /* Try to open distro debuginfo files */
122 dso = dso__new(path); 122 dso = dso__new(path);
123 if (!dso) 123 if (!dso)
124 goto out; 124 goto out;
125 125
126 for (type = distro_dwarf_types; 126 for (type = distro_dwarf_types;
127 !dinfo && *type != DSO_BINARY_TYPE__NOT_FOUND; 127 !dinfo && *type != DSO_BINARY_TYPE__NOT_FOUND;
128 type++) { 128 type++) {
129 if (dso__read_binary_type_filename(dso, *type, &nil, 129 if (dso__read_binary_type_filename(dso, *type, &nil,
130 buf, PATH_MAX) < 0) 130 buf, PATH_MAX) < 0)
131 continue; 131 continue;
132 dinfo = __debuginfo__new(buf); 132 dinfo = __debuginfo__new(buf);
133 } 133 }
134 dso__delete(dso); 134 dso__delete(dso);
135 135
136 out: 136 out:
137 /* if failed to open all distro debuginfo, open given binary */ 137 /* if failed to open all distro debuginfo, open given binary */
138 return dinfo ? : __debuginfo__new(path); 138 return dinfo ? : __debuginfo__new(path);
139 } 139 }
140 140
141 void debuginfo__delete(struct debuginfo *dbg) 141 void debuginfo__delete(struct debuginfo *dbg)
142 { 142 {
143 if (dbg) { 143 if (dbg) {
144 if (dbg->dwfl) 144 if (dbg->dwfl)
145 dwfl_end(dbg->dwfl); 145 dwfl_end(dbg->dwfl);
146 free(dbg); 146 free(dbg);
147 } 147 }
148 } 148 }
149 149
150 /* 150 /*
151 * Probe finder related functions 151 * Probe finder related functions
152 */ 152 */
153 153
154 static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs) 154 static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
155 { 155 {
156 struct probe_trace_arg_ref *ref; 156 struct probe_trace_arg_ref *ref;
157 ref = zalloc(sizeof(struct probe_trace_arg_ref)); 157 ref = zalloc(sizeof(struct probe_trace_arg_ref));
158 if (ref != NULL) 158 if (ref != NULL)
159 ref->offset = offs; 159 ref->offset = offs;
160 return ref; 160 return ref;
161 } 161 }
162 162
163 /* 163 /*
164 * Convert a location into trace_arg. 164 * Convert a location into trace_arg.
165 * If tvar == NULL, this just checks variable can be converted. 165 * If tvar == NULL, this just checks variable can be converted.
166 * If fentry == true and vr_die is a parameter, do huristic search 166 * If fentry == true and vr_die is a parameter, do huristic search
167 * for the location fuzzed by function entry mcount. 167 * for the location fuzzed by function entry mcount.
168 */ 168 */
169 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr, 169 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
170 Dwarf_Op *fb_ops, Dwarf_Die *sp_die, 170 Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
171 struct probe_trace_arg *tvar) 171 struct probe_trace_arg *tvar)
172 { 172 {
173 Dwarf_Attribute attr; 173 Dwarf_Attribute attr;
174 Dwarf_Addr tmp = 0; 174 Dwarf_Addr tmp = 0;
175 Dwarf_Op *op; 175 Dwarf_Op *op;
176 size_t nops; 176 size_t nops;
177 unsigned int regn; 177 unsigned int regn;
178 Dwarf_Word offs = 0; 178 Dwarf_Word offs = 0;
179 bool ref = false; 179 bool ref = false;
180 const char *regs; 180 const char *regs;
181 int ret; 181 int ret;
182 182
183 if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL) 183 if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL)
184 goto static_var; 184 goto static_var;
185 185
186 /* TODO: handle more than 1 exprs */ 186 /* TODO: handle more than 1 exprs */
187 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL) 187 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
188 return -EINVAL; /* Broken DIE ? */ 188 return -EINVAL; /* Broken DIE ? */
189 if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) { 189 if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) {
190 ret = dwarf_entrypc(sp_die, &tmp); 190 ret = dwarf_entrypc(sp_die, &tmp);
191 if (ret || addr != tmp || 191 if (ret || addr != tmp ||
192 dwarf_tag(vr_die) != DW_TAG_formal_parameter || 192 dwarf_tag(vr_die) != DW_TAG_formal_parameter ||
193 dwarf_highpc(sp_die, &tmp)) 193 dwarf_highpc(sp_die, &tmp))
194 return -ENOENT; 194 return -ENOENT;
195 /* 195 /*
196 * This is fuzzed by fentry mcount. We try to find the 196 * This is fuzzed by fentry mcount. We try to find the
197 * parameter location at the earliest address. 197 * parameter location at the earliest address.
198 */ 198 */
199 for (addr += 1; addr <= tmp; addr++) { 199 for (addr += 1; addr <= tmp; addr++) {
200 if (dwarf_getlocation_addr(&attr, addr, &op, 200 if (dwarf_getlocation_addr(&attr, addr, &op,
201 &nops, 1) > 0) 201 &nops, 1) > 0)
202 goto found; 202 goto found;
203 } 203 }
204 return -ENOENT; 204 return -ENOENT;
205 } 205 }
206 found: 206 found:
207 if (nops == 0) 207 if (nops == 0)
208 /* TODO: Support const_value */ 208 /* TODO: Support const_value */
209 return -ENOENT; 209 return -ENOENT;
210 210
211 if (op->atom == DW_OP_addr) { 211 if (op->atom == DW_OP_addr) {
212 static_var: 212 static_var:
213 if (!tvar) 213 if (!tvar)
214 return 0; 214 return 0;
215 /* Static variables on memory (not stack), make @varname */ 215 /* Static variables on memory (not stack), make @varname */
216 ret = strlen(dwarf_diename(vr_die)); 216 ret = strlen(dwarf_diename(vr_die));
217 tvar->value = zalloc(ret + 2); 217 tvar->value = zalloc(ret + 2);
218 if (tvar->value == NULL) 218 if (tvar->value == NULL)
219 return -ENOMEM; 219 return -ENOMEM;
220 snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die)); 220 snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die));
221 tvar->ref = alloc_trace_arg_ref((long)offs); 221 tvar->ref = alloc_trace_arg_ref((long)offs);
222 if (tvar->ref == NULL) 222 if (tvar->ref == NULL)
223 return -ENOMEM; 223 return -ENOMEM;
224 return 0; 224 return 0;
225 } 225 }
226 226
227 /* If this is based on frame buffer, set the offset */ 227 /* If this is based on frame buffer, set the offset */
228 if (op->atom == DW_OP_fbreg) { 228 if (op->atom == DW_OP_fbreg) {
229 if (fb_ops == NULL) 229 if (fb_ops == NULL)
230 return -ENOTSUP; 230 return -ENOTSUP;
231 ref = true; 231 ref = true;
232 offs = op->number; 232 offs = op->number;
233 op = &fb_ops[0]; 233 op = &fb_ops[0];
234 } 234 }
235 235
236 if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) { 236 if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
237 regn = op->atom - DW_OP_breg0; 237 regn = op->atom - DW_OP_breg0;
238 offs += op->number; 238 offs += op->number;
239 ref = true; 239 ref = true;
240 } else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) { 240 } else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) {
241 regn = op->atom - DW_OP_reg0; 241 regn = op->atom - DW_OP_reg0;
242 } else if (op->atom == DW_OP_bregx) { 242 } else if (op->atom == DW_OP_bregx) {
243 regn = op->number; 243 regn = op->number;
244 offs += op->number2; 244 offs += op->number2;
245 ref = true; 245 ref = true;
246 } else if (op->atom == DW_OP_regx) { 246 } else if (op->atom == DW_OP_regx) {
247 regn = op->number; 247 regn = op->number;
248 } else { 248 } else {
249 pr_debug("DW_OP %x is not supported.\n", op->atom); 249 pr_debug("DW_OP %x is not supported.\n", op->atom);
250 return -ENOTSUP; 250 return -ENOTSUP;
251 } 251 }
252 252
253 if (!tvar) 253 if (!tvar)
254 return 0; 254 return 0;
255 255
256 regs = get_arch_regstr(regn); 256 regs = get_arch_regstr(regn);
257 if (!regs) { 257 if (!regs) {
258 /* This should be a bug in DWARF or this tool */ 258 /* This should be a bug in DWARF or this tool */
259 pr_warning("Mapping for the register number %u " 259 pr_warning("Mapping for the register number %u "
260 "missing on this architecture.\n", regn); 260 "missing on this architecture.\n", regn);
261 return -ERANGE; 261 return -ERANGE;
262 } 262 }
263 263
264 tvar->value = strdup(regs); 264 tvar->value = strdup(regs);
265 if (tvar->value == NULL) 265 if (tvar->value == NULL)
266 return -ENOMEM; 266 return -ENOMEM;
267 267
268 if (ref) { 268 if (ref) {
269 tvar->ref = alloc_trace_arg_ref((long)offs); 269 tvar->ref = alloc_trace_arg_ref((long)offs);
270 if (tvar->ref == NULL) 270 if (tvar->ref == NULL)
271 return -ENOMEM; 271 return -ENOMEM;
272 } 272 }
273 return 0; 273 return 0;
274 } 274 }
275 275
276 #define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long)) 276 #define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long))
277 277
278 static int convert_variable_type(Dwarf_Die *vr_die, 278 static int convert_variable_type(Dwarf_Die *vr_die,
279 struct probe_trace_arg *tvar, 279 struct probe_trace_arg *tvar,
280 const char *cast) 280 const char *cast)
281 { 281 {
282 struct probe_trace_arg_ref **ref_ptr = &tvar->ref; 282 struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
283 Dwarf_Die type; 283 Dwarf_Die type;
284 char buf[16]; 284 char buf[16];
285 int bsize, boffs, total; 285 int bsize, boffs, total;
286 int ret; 286 int ret;
287 287
288 /* TODO: check all types */ 288 /* TODO: check all types */
289 if (cast && strcmp(cast, "string") != 0) { 289 if (cast && strcmp(cast, "string") != 0) {
290 /* Non string type is OK */ 290 /* Non string type is OK */
291 tvar->type = strdup(cast); 291 tvar->type = strdup(cast);
292 return (tvar->type == NULL) ? -ENOMEM : 0; 292 return (tvar->type == NULL) ? -ENOMEM : 0;
293 } 293 }
294 294
295 bsize = dwarf_bitsize(vr_die); 295 bsize = dwarf_bitsize(vr_die);
296 if (bsize > 0) { 296 if (bsize > 0) {
297 /* This is a bitfield */ 297 /* This is a bitfield */
298 boffs = dwarf_bitoffset(vr_die); 298 boffs = dwarf_bitoffset(vr_die);
299 total = dwarf_bytesize(vr_die); 299 total = dwarf_bytesize(vr_die);
300 if (boffs < 0 || total < 0) 300 if (boffs < 0 || total < 0)
301 return -ENOENT; 301 return -ENOENT;
302 ret = snprintf(buf, 16, "b%d@%d/%zd", bsize, boffs, 302 ret = snprintf(buf, 16, "b%d@%d/%zd", bsize, boffs,
303 BYTES_TO_BITS(total)); 303 BYTES_TO_BITS(total));
304 goto formatted; 304 goto formatted;
305 } 305 }
306 306
307 if (die_get_real_type(vr_die, &type) == NULL) { 307 if (die_get_real_type(vr_die, &type) == NULL) {
308 pr_warning("Failed to get a type information of %s.\n", 308 pr_warning("Failed to get a type information of %s.\n",
309 dwarf_diename(vr_die)); 309 dwarf_diename(vr_die));
310 return -ENOENT; 310 return -ENOENT;
311 } 311 }
312 312
313 pr_debug("%s type is %s.\n", 313 pr_debug("%s type is %s.\n",
314 dwarf_diename(vr_die), dwarf_diename(&type)); 314 dwarf_diename(vr_die), dwarf_diename(&type));
315 315
316 if (cast && strcmp(cast, "string") == 0) { /* String type */ 316 if (cast && strcmp(cast, "string") == 0) { /* String type */
317 ret = dwarf_tag(&type); 317 ret = dwarf_tag(&type);
318 if (ret != DW_TAG_pointer_type && 318 if (ret != DW_TAG_pointer_type &&
319 ret != DW_TAG_array_type) { 319 ret != DW_TAG_array_type) {
320 pr_warning("Failed to cast into string: " 320 pr_warning("Failed to cast into string: "
321 "%s(%s) is not a pointer nor array.\n", 321 "%s(%s) is not a pointer nor array.\n",
322 dwarf_diename(vr_die), dwarf_diename(&type)); 322 dwarf_diename(vr_die), dwarf_diename(&type));
323 return -EINVAL; 323 return -EINVAL;
324 } 324 }
325 if (die_get_real_type(&type, &type) == NULL) { 325 if (die_get_real_type(&type, &type) == NULL) {
326 pr_warning("Failed to get a type" 326 pr_warning("Failed to get a type"
327 " information.\n"); 327 " information.\n");
328 return -ENOENT; 328 return -ENOENT;
329 } 329 }
330 if (ret == DW_TAG_pointer_type) { 330 if (ret == DW_TAG_pointer_type) {
331 while (*ref_ptr) 331 while (*ref_ptr)
332 ref_ptr = &(*ref_ptr)->next; 332 ref_ptr = &(*ref_ptr)->next;
333 /* Add new reference with offset +0 */ 333 /* Add new reference with offset +0 */
334 *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref)); 334 *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref));
335 if (*ref_ptr == NULL) { 335 if (*ref_ptr == NULL) {
336 pr_warning("Out of memory error\n"); 336 pr_warning("Out of memory error\n");
337 return -ENOMEM; 337 return -ENOMEM;
338 } 338 }
339 } 339 }
340 if (!die_compare_name(&type, "char") && 340 if (!die_compare_name(&type, "char") &&
341 !die_compare_name(&type, "unsigned char")) { 341 !die_compare_name(&type, "unsigned char")) {
342 pr_warning("Failed to cast into string: " 342 pr_warning("Failed to cast into string: "
343 "%s is not (unsigned) char *.\n", 343 "%s is not (unsigned) char *.\n",
344 dwarf_diename(vr_die)); 344 dwarf_diename(vr_die));
345 return -EINVAL; 345 return -EINVAL;
346 } 346 }
347 tvar->type = strdup(cast); 347 tvar->type = strdup(cast);
348 return (tvar->type == NULL) ? -ENOMEM : 0; 348 return (tvar->type == NULL) ? -ENOMEM : 0;
349 } 349 }
350 350
351 ret = dwarf_bytesize(&type); 351 ret = dwarf_bytesize(&type);
352 if (ret <= 0) 352 if (ret <= 0)
353 /* No size ... try to use default type */ 353 /* No size ... try to use default type */
354 return 0; 354 return 0;
355 ret = BYTES_TO_BITS(ret); 355 ret = BYTES_TO_BITS(ret);
356 356
357 /* Check the bitwidth */ 357 /* Check the bitwidth */
358 if (ret > MAX_BASIC_TYPE_BITS) { 358 if (ret > MAX_BASIC_TYPE_BITS) {
359 pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n", 359 pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n",
360 dwarf_diename(&type), MAX_BASIC_TYPE_BITS); 360 dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
361 ret = MAX_BASIC_TYPE_BITS; 361 ret = MAX_BASIC_TYPE_BITS;
362 } 362 }
363 ret = snprintf(buf, 16, "%c%d", 363 ret = snprintf(buf, 16, "%c%d",
364 die_is_signed_type(&type) ? 's' : 'u', ret); 364 die_is_signed_type(&type) ? 's' : 'u', ret);
365 365
366 formatted: 366 formatted:
367 if (ret < 0 || ret >= 16) { 367 if (ret < 0 || ret >= 16) {
368 if (ret >= 16) 368 if (ret >= 16)
369 ret = -E2BIG; 369 ret = -E2BIG;
370 pr_warning("Failed to convert variable type: %s\n", 370 pr_warning("Failed to convert variable type: %s\n",
371 strerror(-ret)); 371 strerror(-ret));
372 return ret; 372 return ret;
373 } 373 }
374 tvar->type = strdup(buf); 374 tvar->type = strdup(buf);
375 if (tvar->type == NULL) 375 if (tvar->type == NULL)
376 return -ENOMEM; 376 return -ENOMEM;
377 return 0; 377 return 0;
378 } 378 }
379 379
380 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, 380 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
381 struct perf_probe_arg_field *field, 381 struct perf_probe_arg_field *field,
382 struct probe_trace_arg_ref **ref_ptr, 382 struct probe_trace_arg_ref **ref_ptr,
383 Dwarf_Die *die_mem) 383 Dwarf_Die *die_mem)
384 { 384 {
385 struct probe_trace_arg_ref *ref = *ref_ptr; 385 struct probe_trace_arg_ref *ref = *ref_ptr;
386 Dwarf_Die type; 386 Dwarf_Die type;
387 Dwarf_Word offs; 387 Dwarf_Word offs;
388 int ret, tag; 388 int ret, tag;
389 389
390 pr_debug("converting %s in %s\n", field->name, varname); 390 pr_debug("converting %s in %s\n", field->name, varname);
391 if (die_get_real_type(vr_die, &type) == NULL) { 391 if (die_get_real_type(vr_die, &type) == NULL) {
392 pr_warning("Failed to get the type of %s.\n", varname); 392 pr_warning("Failed to get the type of %s.\n", varname);
393 return -ENOENT; 393 return -ENOENT;
394 } 394 }
395 pr_debug2("Var real type: (%x)\n", (unsigned)dwarf_dieoffset(&type)); 395 pr_debug2("Var real type: (%x)\n", (unsigned)dwarf_dieoffset(&type));
396 tag = dwarf_tag(&type); 396 tag = dwarf_tag(&type);
397 397
398 if (field->name[0] == '[' && 398 if (field->name[0] == '[' &&
399 (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) { 399 (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) {
400 if (field->next) 400 if (field->next)
401 /* Save original type for next field */ 401 /* Save original type for next field */
402 memcpy(die_mem, &type, sizeof(*die_mem)); 402 memcpy(die_mem, &type, sizeof(*die_mem));
403 /* Get the type of this array */ 403 /* Get the type of this array */
404 if (die_get_real_type(&type, &type) == NULL) { 404 if (die_get_real_type(&type, &type) == NULL) {
405 pr_warning("Failed to get the type of %s.\n", varname); 405 pr_warning("Failed to get the type of %s.\n", varname);
406 return -ENOENT; 406 return -ENOENT;
407 } 407 }
408 pr_debug2("Array real type: (%x)\n", 408 pr_debug2("Array real type: (%x)\n",
409 (unsigned)dwarf_dieoffset(&type)); 409 (unsigned)dwarf_dieoffset(&type));
410 if (tag == DW_TAG_pointer_type) { 410 if (tag == DW_TAG_pointer_type) {
411 ref = zalloc(sizeof(struct probe_trace_arg_ref)); 411 ref = zalloc(sizeof(struct probe_trace_arg_ref));
412 if (ref == NULL) 412 if (ref == NULL)
413 return -ENOMEM; 413 return -ENOMEM;
414 if (*ref_ptr) 414 if (*ref_ptr)
415 (*ref_ptr)->next = ref; 415 (*ref_ptr)->next = ref;
416 else 416 else
417 *ref_ptr = ref; 417 *ref_ptr = ref;
418 } 418 }
419 ref->offset += dwarf_bytesize(&type) * field->index; 419 ref->offset += dwarf_bytesize(&type) * field->index;
420 if (!field->next) 420 if (!field->next)
421 /* Save vr_die for converting types */ 421 /* Save vr_die for converting types */
422 memcpy(die_mem, vr_die, sizeof(*die_mem)); 422 memcpy(die_mem, vr_die, sizeof(*die_mem));
423 goto next; 423 goto next;
424 } else if (tag == DW_TAG_pointer_type) { 424 } else if (tag == DW_TAG_pointer_type) {
425 /* Check the pointer and dereference */ 425 /* Check the pointer and dereference */
426 if (!field->ref) { 426 if (!field->ref) {
427 pr_err("Semantic error: %s must be referred by '->'\n", 427 pr_err("Semantic error: %s must be referred by '->'\n",
428 field->name); 428 field->name);
429 return -EINVAL; 429 return -EINVAL;
430 } 430 }
431 /* Get the type pointed by this pointer */ 431 /* Get the type pointed by this pointer */
432 if (die_get_real_type(&type, &type) == NULL) { 432 if (die_get_real_type(&type, &type) == NULL) {
433 pr_warning("Failed to get the type of %s.\n", varname); 433 pr_warning("Failed to get the type of %s.\n", varname);
434 return -ENOENT; 434 return -ENOENT;
435 } 435 }
436 /* Verify it is a data structure */ 436 /* Verify it is a data structure */
437 tag = dwarf_tag(&type); 437 tag = dwarf_tag(&type);
438 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { 438 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
439 pr_warning("%s is not a data structure nor an union.\n", 439 pr_warning("%s is not a data structure nor an union.\n",
440 varname); 440 varname);
441 return -EINVAL; 441 return -EINVAL;
442 } 442 }
443 443
444 ref = zalloc(sizeof(struct probe_trace_arg_ref)); 444 ref = zalloc(sizeof(struct probe_trace_arg_ref));
445 if (ref == NULL) 445 if (ref == NULL)
446 return -ENOMEM; 446 return -ENOMEM;
447 if (*ref_ptr) 447 if (*ref_ptr)
448 (*ref_ptr)->next = ref; 448 (*ref_ptr)->next = ref;
449 else 449 else
450 *ref_ptr = ref; 450 *ref_ptr = ref;
451 } else { 451 } else {
452 /* Verify it is a data structure */ 452 /* Verify it is a data structure */
453 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { 453 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
454 pr_warning("%s is not a data structure nor an union.\n", 454 pr_warning("%s is not a data structure nor an union.\n",
455 varname); 455 varname);
456 return -EINVAL; 456 return -EINVAL;
457 } 457 }
458 if (field->name[0] == '[') { 458 if (field->name[0] == '[') {
459 pr_err("Semantic error: %s is not a pointor" 459 pr_err("Semantic error: %s is not a pointor"
460 " nor array.\n", varname); 460 " nor array.\n", varname);
461 return -EINVAL; 461 return -EINVAL;
462 } 462 }
463 if (field->ref) { 463 if (field->ref) {
464 pr_err("Semantic error: %s must be referred by '.'\n", 464 pr_err("Semantic error: %s must be referred by '.'\n",
465 field->name); 465 field->name);
466 return -EINVAL; 466 return -EINVAL;
467 } 467 }
468 if (!ref) { 468 if (!ref) {
469 pr_warning("Structure on a register is not " 469 pr_warning("Structure on a register is not "
470 "supported yet.\n"); 470 "supported yet.\n");
471 return -ENOTSUP; 471 return -ENOTSUP;
472 } 472 }
473 } 473 }
474 474
475 if (die_find_member(&type, field->name, die_mem) == NULL) { 475 if (die_find_member(&type, field->name, die_mem) == NULL) {
476 pr_warning("%s(type:%s) has no member %s.\n", varname, 476 pr_warning("%s(type:%s) has no member %s.\n", varname,
477 dwarf_diename(&type), field->name); 477 dwarf_diename(&type), field->name);
478 return -EINVAL; 478 return -EINVAL;
479 } 479 }
480 480
481 /* Get the offset of the field */ 481 /* Get the offset of the field */
482 if (tag == DW_TAG_union_type) { 482 if (tag == DW_TAG_union_type) {
483 offs = 0; 483 offs = 0;
484 } else { 484 } else {
485 ret = die_get_data_member_location(die_mem, &offs); 485 ret = die_get_data_member_location(die_mem, &offs);
486 if (ret < 0) { 486 if (ret < 0) {
487 pr_warning("Failed to get the offset of %s.\n", 487 pr_warning("Failed to get the offset of %s.\n",
488 field->name); 488 field->name);
489 return ret; 489 return ret;
490 } 490 }
491 } 491 }
492 ref->offset += (long)offs; 492 ref->offset += (long)offs;
493 493
494 next: 494 next:
495 /* Converting next field */ 495 /* Converting next field */
496 if (field->next) 496 if (field->next)
497 return convert_variable_fields(die_mem, field->name, 497 return convert_variable_fields(die_mem, field->name,
498 field->next, &ref, die_mem); 498 field->next, &ref, die_mem);
499 else 499 else
500 return 0; 500 return 0;
501 } 501 }
502 502
503 /* Show a variables in kprobe event format */ 503 /* Show a variables in kprobe event format */
504 static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) 504 static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
505 { 505 {
506 Dwarf_Die die_mem; 506 Dwarf_Die die_mem;
507 int ret; 507 int ret;
508 508
509 pr_debug("Converting variable %s into trace event.\n", 509 pr_debug("Converting variable %s into trace event.\n",
510 dwarf_diename(vr_die)); 510 dwarf_diename(vr_die));
511 511
512 ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops, 512 ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
513 &pf->sp_die, pf->tvar); 513 &pf->sp_die, pf->tvar);
514 if (ret == -ENOENT) 514 if (ret == -ENOENT || ret == -EINVAL)
515 pr_err("Failed to find the location of %s at this address.\n" 515 pr_err("Failed to find the location of %s at this address.\n"
516 " Perhaps, it has been optimized out.\n", pf->pvar->var); 516 " Perhaps, it has been optimized out.\n", pf->pvar->var);
517 else if (ret == -ENOTSUP) 517 else if (ret == -ENOTSUP)
518 pr_err("Sorry, we don't support this variable location yet.\n"); 518 pr_err("Sorry, we don't support this variable location yet.\n");
519 else if (pf->pvar->field) { 519 else if (ret == 0 && pf->pvar->field) {
520 ret = convert_variable_fields(vr_die, pf->pvar->var, 520 ret = convert_variable_fields(vr_die, pf->pvar->var,
521 pf->pvar->field, &pf->tvar->ref, 521 pf->pvar->field, &pf->tvar->ref,
522 &die_mem); 522 &die_mem);
523 vr_die = &die_mem; 523 vr_die = &die_mem;
524 } 524 }
525 if (ret == 0) 525 if (ret == 0)
526 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type); 526 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type);
527 /* *expr will be cached in libdw. Don't free it. */ 527 /* *expr will be cached in libdw. Don't free it. */
528 return ret; 528 return ret;
529 } 529 }
530 530
531 /* Find a variable in a scope DIE */ 531 /* Find a variable in a scope DIE */
532 static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) 532 static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
533 { 533 {
534 Dwarf_Die vr_die; 534 Dwarf_Die vr_die;
535 char buf[32], *ptr; 535 char buf[32], *ptr;
536 int ret = 0; 536 int ret = 0;
537 537
538 if (!is_c_varname(pf->pvar->var)) { 538 if (!is_c_varname(pf->pvar->var)) {
539 /* Copy raw parameters */ 539 /* Copy raw parameters */
540 pf->tvar->value = strdup(pf->pvar->var); 540 pf->tvar->value = strdup(pf->pvar->var);
541 if (pf->tvar->value == NULL) 541 if (pf->tvar->value == NULL)
542 return -ENOMEM; 542 return -ENOMEM;
543 if (pf->pvar->type) { 543 if (pf->pvar->type) {
544 pf->tvar->type = strdup(pf->pvar->type); 544 pf->tvar->type = strdup(pf->pvar->type);
545 if (pf->tvar->type == NULL) 545 if (pf->tvar->type == NULL)
546 return -ENOMEM; 546 return -ENOMEM;
547 } 547 }
548 if (pf->pvar->name) { 548 if (pf->pvar->name) {
549 pf->tvar->name = strdup(pf->pvar->name); 549 pf->tvar->name = strdup(pf->pvar->name);
550 if (pf->tvar->name == NULL) 550 if (pf->tvar->name == NULL)
551 return -ENOMEM; 551 return -ENOMEM;
552 } else 552 } else
553 pf->tvar->name = NULL; 553 pf->tvar->name = NULL;
554 return 0; 554 return 0;
555 } 555 }
556 556
557 if (pf->pvar->name) 557 if (pf->pvar->name)
558 pf->tvar->name = strdup(pf->pvar->name); 558 pf->tvar->name = strdup(pf->pvar->name);
559 else { 559 else {
560 ret = synthesize_perf_probe_arg(pf->pvar, buf, 32); 560 ret = synthesize_perf_probe_arg(pf->pvar, buf, 32);
561 if (ret < 0) 561 if (ret < 0)
562 return ret; 562 return ret;
563 ptr = strchr(buf, ':'); /* Change type separator to _ */ 563 ptr = strchr(buf, ':'); /* Change type separator to _ */
564 if (ptr) 564 if (ptr)
565 *ptr = '_'; 565 *ptr = '_';
566 pf->tvar->name = strdup(buf); 566 pf->tvar->name = strdup(buf);
567 } 567 }
568 if (pf->tvar->name == NULL) 568 if (pf->tvar->name == NULL)
569 return -ENOMEM; 569 return -ENOMEM;
570 570
571 pr_debug("Searching '%s' variable in context.\n", pf->pvar->var); 571 pr_debug("Searching '%s' variable in context.\n", pf->pvar->var);
572 /* Search child die for local variables and parameters. */ 572 /* Search child die for local variables and parameters. */
573 if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) { 573 if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
574 /* Search again in global variables */ 574 /* Search again in global variables */
575 if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die)) 575 if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die))
576 ret = -ENOENT; 576 ret = -ENOENT;
577 } 577 }
578 if (ret >= 0) 578 if (ret >= 0)
579 ret = convert_variable(&vr_die, pf); 579 ret = convert_variable(&vr_die, pf);
580 580
581 if (ret < 0) 581 if (ret < 0)
582 pr_warning("Failed to find '%s' in this function.\n", 582 pr_warning("Failed to find '%s' in this function.\n",
583 pf->pvar->var); 583 pf->pvar->var);
584 return ret; 584 return ret;
585 } 585 }
586 586
587 /* Convert subprogram DIE to trace point */ 587 /* Convert subprogram DIE to trace point */
588 static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, 588 static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
589 Dwarf_Addr paddr, bool retprobe, 589 Dwarf_Addr paddr, bool retprobe,
590 struct probe_trace_point *tp) 590 struct probe_trace_point *tp)
591 { 591 {
592 Dwarf_Addr eaddr, highaddr; 592 Dwarf_Addr eaddr, highaddr;
593 GElf_Sym sym; 593 GElf_Sym sym;
594 const char *symbol; 594 const char *symbol;
595 595
596 /* Verify the address is correct */ 596 /* Verify the address is correct */
597 if (dwarf_entrypc(sp_die, &eaddr) != 0) { 597 if (dwarf_entrypc(sp_die, &eaddr) != 0) {
598 pr_warning("Failed to get entry address of %s\n", 598 pr_warning("Failed to get entry address of %s\n",
599 dwarf_diename(sp_die)); 599 dwarf_diename(sp_die));
600 return -ENOENT; 600 return -ENOENT;
601 } 601 }
602 if (dwarf_highpc(sp_die, &highaddr) != 0) { 602 if (dwarf_highpc(sp_die, &highaddr) != 0) {
603 pr_warning("Failed to get end address of %s\n", 603 pr_warning("Failed to get end address of %s\n",
604 dwarf_diename(sp_die)); 604 dwarf_diename(sp_die));
605 return -ENOENT; 605 return -ENOENT;
606 } 606 }
607 if (paddr > highaddr) { 607 if (paddr > highaddr) {
608 pr_warning("Offset specified is greater than size of %s\n", 608 pr_warning("Offset specified is greater than size of %s\n",
609 dwarf_diename(sp_die)); 609 dwarf_diename(sp_die));
610 return -EINVAL; 610 return -EINVAL;
611 } 611 }
612 612
613 /* Get an appropriate symbol from symtab */ 613 /* Get an appropriate symbol from symtab */
614 symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL); 614 symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
615 if (!symbol) { 615 if (!symbol) {
616 pr_warning("Failed to find symbol at 0x%lx\n", 616 pr_warning("Failed to find symbol at 0x%lx\n",
617 (unsigned long)paddr); 617 (unsigned long)paddr);
618 return -ENOENT; 618 return -ENOENT;
619 } 619 }
620 tp->offset = (unsigned long)(paddr - sym.st_value); 620 tp->offset = (unsigned long)(paddr - sym.st_value);
621 tp->address = (unsigned long)paddr; 621 tp->address = (unsigned long)paddr;
622 tp->symbol = strdup(symbol); 622 tp->symbol = strdup(symbol);
623 if (!tp->symbol) 623 if (!tp->symbol)
624 return -ENOMEM; 624 return -ENOMEM;
625 625
626 /* Return probe must be on the head of a subprogram */ 626 /* Return probe must be on the head of a subprogram */
627 if (retprobe) { 627 if (retprobe) {
628 if (eaddr != paddr) { 628 if (eaddr != paddr) {
629 pr_warning("Return probe must be on the head of" 629 pr_warning("Return probe must be on the head of"
630 " a real function.\n"); 630 " a real function.\n");
631 return -EINVAL; 631 return -EINVAL;
632 } 632 }
633 tp->retprobe = true; 633 tp->retprobe = true;
634 } 634 }
635 635
636 return 0; 636 return 0;
637 } 637 }
638 638
639 /* Call probe_finder callback with scope DIE */ 639 /* Call probe_finder callback with scope DIE */
640 static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf) 640 static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
641 { 641 {
642 Dwarf_Attribute fb_attr; 642 Dwarf_Attribute fb_attr;
643 size_t nops; 643 size_t nops;
644 int ret; 644 int ret;
645 645
646 if (!sc_die) { 646 if (!sc_die) {
647 pr_err("Caller must pass a scope DIE. Program error.\n"); 647 pr_err("Caller must pass a scope DIE. Program error.\n");
648 return -EINVAL; 648 return -EINVAL;
649 } 649 }
650 650
651 /* If not a real subprogram, find a real one */ 651 /* If not a real subprogram, find a real one */
652 if (!die_is_func_def(sc_die)) { 652 if (!die_is_func_def(sc_die)) {
653 if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { 653 if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
654 pr_warning("Failed to find probe point in any " 654 pr_warning("Failed to find probe point in any "
655 "functions.\n"); 655 "functions.\n");
656 return -ENOENT; 656 return -ENOENT;
657 } 657 }
658 } else 658 } else
659 memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die)); 659 memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die));
660 660
661 /* Get the frame base attribute/ops from subprogram */ 661 /* Get the frame base attribute/ops from subprogram */
662 dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr); 662 dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr);
663 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); 663 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
664 if (ret <= 0 || nops == 0) { 664 if (ret <= 0 || nops == 0) {
665 pf->fb_ops = NULL; 665 pf->fb_ops = NULL;
666 #if _ELFUTILS_PREREQ(0, 142) 666 #if _ELFUTILS_PREREQ(0, 142)
667 } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa && 667 } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
668 pf->cfi != NULL) { 668 pf->cfi != NULL) {
669 Dwarf_Frame *frame; 669 Dwarf_Frame *frame;
670 if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 || 670 if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
671 dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) { 671 dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
672 pr_warning("Failed to get call frame on 0x%jx\n", 672 pr_warning("Failed to get call frame on 0x%jx\n",
673 (uintmax_t)pf->addr); 673 (uintmax_t)pf->addr);
674 return -ENOENT; 674 return -ENOENT;
675 } 675 }
676 #endif 676 #endif
677 } 677 }
678 678
679 /* Call finder's callback handler */ 679 /* Call finder's callback handler */
680 ret = pf->callback(sc_die, pf); 680 ret = pf->callback(sc_die, pf);
681 681
682 /* *pf->fb_ops will be cached in libdw. Don't free it. */ 682 /* *pf->fb_ops will be cached in libdw. Don't free it. */
683 pf->fb_ops = NULL; 683 pf->fb_ops = NULL;
684 684
685 return ret; 685 return ret;
686 } 686 }
687 687
688 struct find_scope_param { 688 struct find_scope_param {
689 const char *function; 689 const char *function;
690 const char *file; 690 const char *file;
691 int line; 691 int line;
692 int diff; 692 int diff;
693 Dwarf_Die *die_mem; 693 Dwarf_Die *die_mem;
694 bool found; 694 bool found;
695 }; 695 };
696 696
697 static int find_best_scope_cb(Dwarf_Die *fn_die, void *data) 697 static int find_best_scope_cb(Dwarf_Die *fn_die, void *data)
698 { 698 {
699 struct find_scope_param *fsp = data; 699 struct find_scope_param *fsp = data;
700 const char *file; 700 const char *file;
701 int lno; 701 int lno;
702 702
703 /* Skip if declared file name does not match */ 703 /* Skip if declared file name does not match */
704 if (fsp->file) { 704 if (fsp->file) {
705 file = dwarf_decl_file(fn_die); 705 file = dwarf_decl_file(fn_die);
706 if (!file || strcmp(fsp->file, file) != 0) 706 if (!file || strcmp(fsp->file, file) != 0)
707 return 0; 707 return 0;
708 } 708 }
709 /* If the function name is given, that's what user expects */ 709 /* If the function name is given, that's what user expects */
710 if (fsp->function) { 710 if (fsp->function) {
711 if (die_compare_name(fn_die, fsp->function)) { 711 if (die_compare_name(fn_die, fsp->function)) {
712 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); 712 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
713 fsp->found = true; 713 fsp->found = true;
714 return 1; 714 return 1;
715 } 715 }
716 } else { 716 } else {
717 /* With the line number, find the nearest declared DIE */ 717 /* With the line number, find the nearest declared DIE */
718 dwarf_decl_line(fn_die, &lno); 718 dwarf_decl_line(fn_die, &lno);
719 if (lno < fsp->line && fsp->diff > fsp->line - lno) { 719 if (lno < fsp->line && fsp->diff > fsp->line - lno) {
720 /* Keep a candidate and continue */ 720 /* Keep a candidate and continue */
721 fsp->diff = fsp->line - lno; 721 fsp->diff = fsp->line - lno;
722 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); 722 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
723 fsp->found = true; 723 fsp->found = true;
724 } 724 }
725 } 725 }
726 return 0; 726 return 0;
727 } 727 }
728 728
729 /* Find an appropriate scope fits to given conditions */ 729 /* Find an appropriate scope fits to given conditions */
730 static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem) 730 static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
731 { 731 {
732 struct find_scope_param fsp = { 732 struct find_scope_param fsp = {
733 .function = pf->pev->point.function, 733 .function = pf->pev->point.function,
734 .file = pf->fname, 734 .file = pf->fname,
735 .line = pf->lno, 735 .line = pf->lno,
736 .diff = INT_MAX, 736 .diff = INT_MAX,
737 .die_mem = die_mem, 737 .die_mem = die_mem,
738 .found = false, 738 .found = false,
739 }; 739 };
740 740
741 cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb, &fsp); 741 cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb, &fsp);
742 742
743 return fsp.found ? die_mem : NULL; 743 return fsp.found ? die_mem : NULL;
744 } 744 }
745 745
746 static int probe_point_line_walker(const char *fname, int lineno, 746 static int probe_point_line_walker(const char *fname, int lineno,
747 Dwarf_Addr addr, void *data) 747 Dwarf_Addr addr, void *data)
748 { 748 {
749 struct probe_finder *pf = data; 749 struct probe_finder *pf = data;
750 Dwarf_Die *sc_die, die_mem; 750 Dwarf_Die *sc_die, die_mem;
751 int ret; 751 int ret;
752 752
753 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0) 753 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0)
754 return 0; 754 return 0;
755 755
756 pf->addr = addr; 756 pf->addr = addr;
757 sc_die = find_best_scope(pf, &die_mem); 757 sc_die = find_best_scope(pf, &die_mem);
758 if (!sc_die) { 758 if (!sc_die) {
759 pr_warning("Failed to find scope of probe point.\n"); 759 pr_warning("Failed to find scope of probe point.\n");
760 return -ENOENT; 760 return -ENOENT;
761 } 761 }
762 762
763 ret = call_probe_finder(sc_die, pf); 763 ret = call_probe_finder(sc_die, pf);
764 764
765 /* Continue if no error, because the line will be in inline function */ 765 /* Continue if no error, because the line will be in inline function */
766 return ret < 0 ? ret : 0; 766 return ret < 0 ? ret : 0;
767 } 767 }
768 768
769 /* Find probe point from its line number */ 769 /* Find probe point from its line number */
770 static int find_probe_point_by_line(struct probe_finder *pf) 770 static int find_probe_point_by_line(struct probe_finder *pf)
771 { 771 {
772 return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf); 772 return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf);
773 } 773 }
774 774
775 /* Find lines which match lazy pattern */ 775 /* Find lines which match lazy pattern */
776 static int find_lazy_match_lines(struct intlist *list, 776 static int find_lazy_match_lines(struct intlist *list,
777 const char *fname, const char *pat) 777 const char *fname, const char *pat)
778 { 778 {
779 FILE *fp; 779 FILE *fp;
780 char *line = NULL; 780 char *line = NULL;
781 size_t line_len; 781 size_t line_len;
782 ssize_t len; 782 ssize_t len;
783 int count = 0, linenum = 1; 783 int count = 0, linenum = 1;
784 784
785 fp = fopen(fname, "r"); 785 fp = fopen(fname, "r");
786 if (!fp) { 786 if (!fp) {
787 pr_warning("Failed to open %s: %s\n", fname, strerror(errno)); 787 pr_warning("Failed to open %s: %s\n", fname, strerror(errno));
788 return -errno; 788 return -errno;
789 } 789 }
790 790
791 while ((len = getline(&line, &line_len, fp)) > 0) { 791 while ((len = getline(&line, &line_len, fp)) > 0) {
792 792
793 if (line[len - 1] == '\n') 793 if (line[len - 1] == '\n')
794 line[len - 1] = '\0'; 794 line[len - 1] = '\0';
795 795
796 if (strlazymatch(line, pat)) { 796 if (strlazymatch(line, pat)) {
797 intlist__add(list, linenum); 797 intlist__add(list, linenum);
798 count++; 798 count++;
799 } 799 }
800 linenum++; 800 linenum++;
801 } 801 }
802 802
803 if (ferror(fp)) 803 if (ferror(fp))
804 count = -errno; 804 count = -errno;
805 free(line); 805 free(line);
806 fclose(fp); 806 fclose(fp);
807 807
808 if (count == 0) 808 if (count == 0)
809 pr_debug("No matched lines found in %s.\n", fname); 809 pr_debug("No matched lines found in %s.\n", fname);
810 return count; 810 return count;
811 } 811 }
812 812
813 static int probe_point_lazy_walker(const char *fname, int lineno, 813 static int probe_point_lazy_walker(const char *fname, int lineno,
814 Dwarf_Addr addr, void *data) 814 Dwarf_Addr addr, void *data)
815 { 815 {
816 struct probe_finder *pf = data; 816 struct probe_finder *pf = data;
817 Dwarf_Die *sc_die, die_mem; 817 Dwarf_Die *sc_die, die_mem;
818 int ret; 818 int ret;
819 819
820 if (!intlist__has_entry(pf->lcache, lineno) || 820 if (!intlist__has_entry(pf->lcache, lineno) ||
821 strtailcmp(fname, pf->fname) != 0) 821 strtailcmp(fname, pf->fname) != 0)
822 return 0; 822 return 0;
823 823
824 pr_debug("Probe line found: line:%d addr:0x%llx\n", 824 pr_debug("Probe line found: line:%d addr:0x%llx\n",
825 lineno, (unsigned long long)addr); 825 lineno, (unsigned long long)addr);
826 pf->addr = addr; 826 pf->addr = addr;
827 pf->lno = lineno; 827 pf->lno = lineno;
828 sc_die = find_best_scope(pf, &die_mem); 828 sc_die = find_best_scope(pf, &die_mem);
829 if (!sc_die) { 829 if (!sc_die) {
830 pr_warning("Failed to find scope of probe point.\n"); 830 pr_warning("Failed to find scope of probe point.\n");
831 return -ENOENT; 831 return -ENOENT;
832 } 832 }
833 833
834 ret = call_probe_finder(sc_die, pf); 834 ret = call_probe_finder(sc_die, pf);
835 835
836 /* 836 /*
837 * Continue if no error, because the lazy pattern will match 837 * Continue if no error, because the lazy pattern will match
838 * to other lines 838 * to other lines
839 */ 839 */
840 return ret < 0 ? ret : 0; 840 return ret < 0 ? ret : 0;
841 } 841 }
842 842
843 /* Find probe points from lazy pattern */ 843 /* Find probe points from lazy pattern */
844 static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf) 844 static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
845 { 845 {
846 int ret = 0; 846 int ret = 0;
847 847
848 if (intlist__empty(pf->lcache)) { 848 if (intlist__empty(pf->lcache)) {
849 /* Matching lazy line pattern */ 849 /* Matching lazy line pattern */
850 ret = find_lazy_match_lines(pf->lcache, pf->fname, 850 ret = find_lazy_match_lines(pf->lcache, pf->fname,
851 pf->pev->point.lazy_line); 851 pf->pev->point.lazy_line);
852 if (ret <= 0) 852 if (ret <= 0)
853 return ret; 853 return ret;
854 } 854 }
855 855
856 return die_walk_lines(sp_die, probe_point_lazy_walker, pf); 856 return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
857 } 857 }
858 858
859 static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) 859 static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
860 { 860 {
861 struct probe_finder *pf = data; 861 struct probe_finder *pf = data;
862 struct perf_probe_point *pp = &pf->pev->point; 862 struct perf_probe_point *pp = &pf->pev->point;
863 Dwarf_Addr addr; 863 Dwarf_Addr addr;
864 int ret; 864 int ret;
865 865
866 if (pp->lazy_line) 866 if (pp->lazy_line)
867 ret = find_probe_point_lazy(in_die, pf); 867 ret = find_probe_point_lazy(in_die, pf);
868 else { 868 else {
869 /* Get probe address */ 869 /* Get probe address */
870 if (dwarf_entrypc(in_die, &addr) != 0) { 870 if (dwarf_entrypc(in_die, &addr) != 0) {
871 pr_warning("Failed to get entry address of %s.\n", 871 pr_warning("Failed to get entry address of %s.\n",
872 dwarf_diename(in_die)); 872 dwarf_diename(in_die));
873 return -ENOENT; 873 return -ENOENT;
874 } 874 }
875 pf->addr = addr; 875 pf->addr = addr;
876 pf->addr += pp->offset; 876 pf->addr += pp->offset;
877 pr_debug("found inline addr: 0x%jx\n", 877 pr_debug("found inline addr: 0x%jx\n",
878 (uintmax_t)pf->addr); 878 (uintmax_t)pf->addr);
879 879
880 ret = call_probe_finder(in_die, pf); 880 ret = call_probe_finder(in_die, pf);
881 } 881 }
882 882
883 return ret; 883 return ret;
884 } 884 }
885 885
886 /* Callback parameter with return value for libdw */ 886 /* Callback parameter with return value for libdw */
887 struct dwarf_callback_param { 887 struct dwarf_callback_param {
888 void *data; 888 void *data;
889 int retval; 889 int retval;
890 }; 890 };
891 891
892 /* Search function from function name */ 892 /* Search function from function name */
893 static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) 893 static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
894 { 894 {
895 struct dwarf_callback_param *param = data; 895 struct dwarf_callback_param *param = data;
896 struct probe_finder *pf = param->data; 896 struct probe_finder *pf = param->data;
897 struct perf_probe_point *pp = &pf->pev->point; 897 struct perf_probe_point *pp = &pf->pev->point;
898 898
899 /* Check tag and diename */ 899 /* Check tag and diename */
900 if (!die_is_func_def(sp_die) || 900 if (!die_is_func_def(sp_die) ||
901 !die_compare_name(sp_die, pp->function)) 901 !die_compare_name(sp_die, pp->function))
902 return DWARF_CB_OK; 902 return DWARF_CB_OK;
903 903
904 /* Check declared file */ 904 /* Check declared file */
905 if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die))) 905 if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die)))
906 return DWARF_CB_OK; 906 return DWARF_CB_OK;
907 907
908 pf->fname = dwarf_decl_file(sp_die); 908 pf->fname = dwarf_decl_file(sp_die);
909 if (pp->line) { /* Function relative line */ 909 if (pp->line) { /* Function relative line */
910 dwarf_decl_line(sp_die, &pf->lno); 910 dwarf_decl_line(sp_die, &pf->lno);
911 pf->lno += pp->line; 911 pf->lno += pp->line;
912 param->retval = find_probe_point_by_line(pf); 912 param->retval = find_probe_point_by_line(pf);
913 } else if (!dwarf_func_inline(sp_die)) { 913 } else if (!dwarf_func_inline(sp_die)) {
914 /* Real function */ 914 /* Real function */
915 if (pp->lazy_line) 915 if (pp->lazy_line)
916 param->retval = find_probe_point_lazy(sp_die, pf); 916 param->retval = find_probe_point_lazy(sp_die, pf);
917 else { 917 else {
918 if (dwarf_entrypc(sp_die, &pf->addr) != 0) { 918 if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
919 pr_warning("Failed to get entry address of " 919 pr_warning("Failed to get entry address of "
920 "%s.\n", dwarf_diename(sp_die)); 920 "%s.\n", dwarf_diename(sp_die));
921 param->retval = -ENOENT; 921 param->retval = -ENOENT;
922 return DWARF_CB_ABORT; 922 return DWARF_CB_ABORT;
923 } 923 }
924 pf->addr += pp->offset; 924 pf->addr += pp->offset;
925 /* TODO: Check the address in this function */ 925 /* TODO: Check the address in this function */
926 param->retval = call_probe_finder(sp_die, pf); 926 param->retval = call_probe_finder(sp_die, pf);
927 } 927 }
928 } else 928 } else
929 /* Inlined function: search instances */ 929 /* Inlined function: search instances */
930 param->retval = die_walk_instances(sp_die, 930 param->retval = die_walk_instances(sp_die,
931 probe_point_inline_cb, (void *)pf); 931 probe_point_inline_cb, (void *)pf);
932 932
933 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */ 933 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
934 } 934 }
935 935
936 static int find_probe_point_by_func(struct probe_finder *pf) 936 static int find_probe_point_by_func(struct probe_finder *pf)
937 { 937 {
938 struct dwarf_callback_param _param = {.data = (void *)pf, 938 struct dwarf_callback_param _param = {.data = (void *)pf,
939 .retval = 0}; 939 .retval = 0};
940 dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0); 940 dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
941 return _param.retval; 941 return _param.retval;
942 } 942 }
943 943
944 struct pubname_callback_param { 944 struct pubname_callback_param {
945 char *function; 945 char *function;
946 char *file; 946 char *file;
947 Dwarf_Die *cu_die; 947 Dwarf_Die *cu_die;
948 Dwarf_Die *sp_die; 948 Dwarf_Die *sp_die;
949 int found; 949 int found;
950 }; 950 };
951 951
952 static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data) 952 static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
953 { 953 {
954 struct pubname_callback_param *param = data; 954 struct pubname_callback_param *param = data;
955 955
956 if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) { 956 if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
957 if (dwarf_tag(param->sp_die) != DW_TAG_subprogram) 957 if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
958 return DWARF_CB_OK; 958 return DWARF_CB_OK;
959 959
960 if (die_compare_name(param->sp_die, param->function)) { 960 if (die_compare_name(param->sp_die, param->function)) {
961 if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die)) 961 if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
962 return DWARF_CB_OK; 962 return DWARF_CB_OK;
963 963
964 if (param->file && 964 if (param->file &&
965 strtailcmp(param->file, dwarf_decl_file(param->sp_die))) 965 strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
966 return DWARF_CB_OK; 966 return DWARF_CB_OK;
967 967
968 param->found = 1; 968 param->found = 1;
969 return DWARF_CB_ABORT; 969 return DWARF_CB_ABORT;
970 } 970 }
971 } 971 }
972 972
973 return DWARF_CB_OK; 973 return DWARF_CB_OK;
974 } 974 }
975 975
976 /* Find probe points from debuginfo */ 976 /* Find probe points from debuginfo */
977 static int debuginfo__find_probes(struct debuginfo *dbg, 977 static int debuginfo__find_probes(struct debuginfo *dbg,
978 struct probe_finder *pf) 978 struct probe_finder *pf)
979 { 979 {
980 struct perf_probe_point *pp = &pf->pev->point; 980 struct perf_probe_point *pp = &pf->pev->point;
981 Dwarf_Off off, noff; 981 Dwarf_Off off, noff;
982 size_t cuhl; 982 size_t cuhl;
983 Dwarf_Die *diep; 983 Dwarf_Die *diep;
984 int ret = 0; 984 int ret = 0;
985 985
986 #if _ELFUTILS_PREREQ(0, 142) 986 #if _ELFUTILS_PREREQ(0, 142)
987 /* Get the call frame information from this dwarf */ 987 /* Get the call frame information from this dwarf */
988 pf->cfi = dwarf_getcfi_elf(dwarf_getelf(dbg->dbg)); 988 pf->cfi = dwarf_getcfi_elf(dwarf_getelf(dbg->dbg));
989 #endif 989 #endif
990 990
991 off = 0; 991 off = 0;
992 pf->lcache = intlist__new(NULL); 992 pf->lcache = intlist__new(NULL);
993 if (!pf->lcache) 993 if (!pf->lcache)
994 return -ENOMEM; 994 return -ENOMEM;
995 995
996 /* Fastpath: lookup by function name from .debug_pubnames section */ 996 /* Fastpath: lookup by function name from .debug_pubnames section */
997 if (pp->function) { 997 if (pp->function) {
998 struct pubname_callback_param pubname_param = { 998 struct pubname_callback_param pubname_param = {
999 .function = pp->function, 999 .function = pp->function,
1000 .file = pp->file, 1000 .file = pp->file,
1001 .cu_die = &pf->cu_die, 1001 .cu_die = &pf->cu_die,
1002 .sp_die = &pf->sp_die, 1002 .sp_die = &pf->sp_die,
1003 .found = 0, 1003 .found = 0,
1004 }; 1004 };
1005 struct dwarf_callback_param probe_param = { 1005 struct dwarf_callback_param probe_param = {
1006 .data = pf, 1006 .data = pf,
1007 }; 1007 };
1008 1008
1009 dwarf_getpubnames(dbg->dbg, pubname_search_cb, 1009 dwarf_getpubnames(dbg->dbg, pubname_search_cb,
1010 &pubname_param, 0); 1010 &pubname_param, 0);
1011 if (pubname_param.found) { 1011 if (pubname_param.found) {
1012 ret = probe_point_search_cb(&pf->sp_die, &probe_param); 1012 ret = probe_point_search_cb(&pf->sp_die, &probe_param);
1013 if (ret) 1013 if (ret)
1014 goto found; 1014 goto found;
1015 } 1015 }
1016 } 1016 }
1017 1017
1018 /* Loop on CUs (Compilation Unit) */ 1018 /* Loop on CUs (Compilation Unit) */
1019 while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { 1019 while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1020 /* Get the DIE(Debugging Information Entry) of this CU */ 1020 /* Get the DIE(Debugging Information Entry) of this CU */
1021 diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die); 1021 diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die);
1022 if (!diep) 1022 if (!diep)
1023 continue; 1023 continue;
1024 1024
1025 /* Check if target file is included. */ 1025 /* Check if target file is included. */
1026 if (pp->file) 1026 if (pp->file)
1027 pf->fname = cu_find_realpath(&pf->cu_die, pp->file); 1027 pf->fname = cu_find_realpath(&pf->cu_die, pp->file);
1028 else 1028 else
1029 pf->fname = NULL; 1029 pf->fname = NULL;
1030 1030
1031 if (!pp->file || pf->fname) { 1031 if (!pp->file || pf->fname) {
1032 if (pp->function) 1032 if (pp->function)
1033 ret = find_probe_point_by_func(pf); 1033 ret = find_probe_point_by_func(pf);
1034 else if (pp->lazy_line) 1034 else if (pp->lazy_line)
1035 ret = find_probe_point_lazy(NULL, pf); 1035 ret = find_probe_point_lazy(NULL, pf);
1036 else { 1036 else {
1037 pf->lno = pp->line; 1037 pf->lno = pp->line;
1038 ret = find_probe_point_by_line(pf); 1038 ret = find_probe_point_by_line(pf);
1039 } 1039 }
1040 if (ret < 0) 1040 if (ret < 0)
1041 break; 1041 break;
1042 } 1042 }
1043 off = noff; 1043 off = noff;
1044 } 1044 }
1045 1045
1046 found: 1046 found:
1047 intlist__delete(pf->lcache); 1047 intlist__delete(pf->lcache);
1048 pf->lcache = NULL; 1048 pf->lcache = NULL;
1049 1049
1050 return ret; 1050 return ret;
1051 } 1051 }
1052 1052
1053 struct local_vars_finder { 1053 struct local_vars_finder {
1054 struct probe_finder *pf; 1054 struct probe_finder *pf;
1055 struct perf_probe_arg *args; 1055 struct perf_probe_arg *args;
1056 int max_args; 1056 int max_args;
1057 int nargs; 1057 int nargs;
1058 int ret; 1058 int ret;
1059 }; 1059 };
1060 1060
1061 /* Collect available variables in this scope */ 1061 /* Collect available variables in this scope */
1062 static int copy_variables_cb(Dwarf_Die *die_mem, void *data) 1062 static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
1063 { 1063 {
1064 struct local_vars_finder *vf = data; 1064 struct local_vars_finder *vf = data;
1065 struct probe_finder *pf = vf->pf; 1065 struct probe_finder *pf = vf->pf;
1066 int tag; 1066 int tag;
1067 1067
1068 tag = dwarf_tag(die_mem); 1068 tag = dwarf_tag(die_mem);
1069 if (tag == DW_TAG_formal_parameter || 1069 if (tag == DW_TAG_formal_parameter ||
1070 tag == DW_TAG_variable) { 1070 tag == DW_TAG_variable) {
1071 if (convert_variable_location(die_mem, vf->pf->addr, 1071 if (convert_variable_location(die_mem, vf->pf->addr,
1072 vf->pf->fb_ops, &pf->sp_die, 1072 vf->pf->fb_ops, &pf->sp_die,
1073 NULL) == 0) { 1073 NULL) == 0) {
1074 vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem); 1074 vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
1075 if (vf->args[vf->nargs].var == NULL) { 1075 if (vf->args[vf->nargs].var == NULL) {
1076 vf->ret = -ENOMEM; 1076 vf->ret = -ENOMEM;
1077 return DIE_FIND_CB_END; 1077 return DIE_FIND_CB_END;
1078 } 1078 }
1079 pr_debug(" %s", vf->args[vf->nargs].var); 1079 pr_debug(" %s", vf->args[vf->nargs].var);
1080 vf->nargs++; 1080 vf->nargs++;
1081 } 1081 }
1082 } 1082 }
1083 1083
1084 if (dwarf_haspc(die_mem, vf->pf->addr)) 1084 if (dwarf_haspc(die_mem, vf->pf->addr))
1085 return DIE_FIND_CB_CONTINUE; 1085 return DIE_FIND_CB_CONTINUE;
1086 else 1086 else
1087 return DIE_FIND_CB_SIBLING; 1087 return DIE_FIND_CB_SIBLING;
1088 } 1088 }
1089 1089
1090 static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf, 1090 static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
1091 struct perf_probe_arg *args) 1091 struct perf_probe_arg *args)
1092 { 1092 {
1093 Dwarf_Die die_mem; 1093 Dwarf_Die die_mem;
1094 int i; 1094 int i;
1095 int n = 0; 1095 int n = 0;
1096 struct local_vars_finder vf = {.pf = pf, .args = args, 1096 struct local_vars_finder vf = {.pf = pf, .args = args,
1097 .max_args = MAX_PROBE_ARGS, .ret = 0}; 1097 .max_args = MAX_PROBE_ARGS, .ret = 0};
1098 1098
1099 for (i = 0; i < pf->pev->nargs; i++) { 1099 for (i = 0; i < pf->pev->nargs; i++) {
1100 /* var never be NULL */ 1100 /* var never be NULL */
1101 if (strcmp(pf->pev->args[i].var, "$vars") == 0) { 1101 if (strcmp(pf->pev->args[i].var, "$vars") == 0) {
1102 pr_debug("Expanding $vars into:"); 1102 pr_debug("Expanding $vars into:");
1103 vf.nargs = n; 1103 vf.nargs = n;
1104 /* Special local variables */ 1104 /* Special local variables */
1105 die_find_child(sc_die, copy_variables_cb, (void *)&vf, 1105 die_find_child(sc_die, copy_variables_cb, (void *)&vf,
1106 &die_mem); 1106 &die_mem);
1107 pr_debug(" (%d)\n", vf.nargs - n); 1107 pr_debug(" (%d)\n", vf.nargs - n);
1108 if (vf.ret < 0) 1108 if (vf.ret < 0)
1109 return vf.ret; 1109 return vf.ret;
1110 n = vf.nargs; 1110 n = vf.nargs;
1111 } else { 1111 } else {
1112 /* Copy normal argument */ 1112 /* Copy normal argument */
1113 args[n] = pf->pev->args[i]; 1113 args[n] = pf->pev->args[i];
1114 n++; 1114 n++;
1115 } 1115 }
1116 } 1116 }
1117 return n; 1117 return n;
1118 } 1118 }
1119 1119
1120 /* Add a found probe point into trace event list */ 1120 /* Add a found probe point into trace event list */
1121 static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) 1121 static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1122 { 1122 {
1123 struct trace_event_finder *tf = 1123 struct trace_event_finder *tf =
1124 container_of(pf, struct trace_event_finder, pf); 1124 container_of(pf, struct trace_event_finder, pf);
1125 struct probe_trace_event *tev; 1125 struct probe_trace_event *tev;
1126 struct perf_probe_arg *args; 1126 struct perf_probe_arg *args;
1127 int ret, i; 1127 int ret, i;
1128 1128
1129 /* Check number of tevs */ 1129 /* Check number of tevs */
1130 if (tf->ntevs == tf->max_tevs) { 1130 if (tf->ntevs == tf->max_tevs) {
1131 pr_warning("Too many( > %d) probe point found.\n", 1131 pr_warning("Too many( > %d) probe point found.\n",
1132 tf->max_tevs); 1132 tf->max_tevs);
1133 return -ERANGE; 1133 return -ERANGE;
1134 } 1134 }
1135 tev = &tf->tevs[tf->ntevs++]; 1135 tev = &tf->tevs[tf->ntevs++];
1136 1136
1137 /* Trace point should be converted from subprogram DIE */ 1137 /* Trace point should be converted from subprogram DIE */
1138 ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr, 1138 ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
1139 pf->pev->point.retprobe, &tev->point); 1139 pf->pev->point.retprobe, &tev->point);
1140 if (ret < 0) 1140 if (ret < 0)
1141 return ret; 1141 return ret;
1142 1142
1143 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, 1143 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
1144 tev->point.offset); 1144 tev->point.offset);
1145 1145
1146 /* Expand special probe argument if exist */ 1146 /* Expand special probe argument if exist */
1147 args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS); 1147 args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
1148 if (args == NULL) 1148 if (args == NULL)
1149 return -ENOMEM; 1149 return -ENOMEM;
1150 1150
1151 ret = expand_probe_args(sc_die, pf, args); 1151 ret = expand_probe_args(sc_die, pf, args);
1152 if (ret < 0) 1152 if (ret < 0)
1153 goto end; 1153 goto end;
1154 1154
1155 tev->nargs = ret; 1155 tev->nargs = ret;
1156 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1156 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1157 if (tev->args == NULL) { 1157 if (tev->args == NULL) {
1158 ret = -ENOMEM; 1158 ret = -ENOMEM;
1159 goto end; 1159 goto end;
1160 } 1160 }
1161 1161
1162 /* Find each argument */ 1162 /* Find each argument */
1163 for (i = 0; i < tev->nargs; i++) { 1163 for (i = 0; i < tev->nargs; i++) {
1164 pf->pvar = &args[i]; 1164 pf->pvar = &args[i];
1165 pf->tvar = &tev->args[i]; 1165 pf->tvar = &tev->args[i];
1166 /* Variable should be found from scope DIE */ 1166 /* Variable should be found from scope DIE */
1167 ret = find_variable(sc_die, pf); 1167 ret = find_variable(sc_die, pf);
1168 if (ret != 0) 1168 if (ret != 0)
1169 break; 1169 break;
1170 } 1170 }
1171 1171
1172 end: 1172 end:
1173 free(args); 1173 free(args);
1174 return ret; 1174 return ret;
1175 } 1175 }
1176 1176
1177 /* Find probe_trace_events specified by perf_probe_event from debuginfo */ 1177 /* Find probe_trace_events specified by perf_probe_event from debuginfo */
1178 int debuginfo__find_trace_events(struct debuginfo *dbg, 1178 int debuginfo__find_trace_events(struct debuginfo *dbg,
1179 struct perf_probe_event *pev, 1179 struct perf_probe_event *pev,
1180 struct probe_trace_event **tevs, int max_tevs) 1180 struct probe_trace_event **tevs, int max_tevs)
1181 { 1181 {
1182 struct trace_event_finder tf = { 1182 struct trace_event_finder tf = {
1183 .pf = {.pev = pev, .callback = add_probe_trace_event}, 1183 .pf = {.pev = pev, .callback = add_probe_trace_event},
1184 .mod = dbg->mod, .max_tevs = max_tevs}; 1184 .mod = dbg->mod, .max_tevs = max_tevs};
1185 int ret; 1185 int ret;
1186 1186
1187 /* Allocate result tevs array */ 1187 /* Allocate result tevs array */
1188 *tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs); 1188 *tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs);
1189 if (*tevs == NULL) 1189 if (*tevs == NULL)
1190 return -ENOMEM; 1190 return -ENOMEM;
1191 1191
1192 tf.tevs = *tevs; 1192 tf.tevs = *tevs;
1193 tf.ntevs = 0; 1193 tf.ntevs = 0;
1194 1194
1195 ret = debuginfo__find_probes(dbg, &tf.pf); 1195 ret = debuginfo__find_probes(dbg, &tf.pf);
1196 if (ret < 0) { 1196 if (ret < 0) {
1197 zfree(tevs); 1197 zfree(tevs);
1198 return ret; 1198 return ret;
1199 } 1199 }
1200 1200
1201 return (ret < 0) ? ret : tf.ntevs; 1201 return (ret < 0) ? ret : tf.ntevs;
1202 } 1202 }
1203 1203
1204 #define MAX_VAR_LEN 64 1204 #define MAX_VAR_LEN 64
1205 1205
1206 /* Collect available variables in this scope */ 1206 /* Collect available variables in this scope */
1207 static int collect_variables_cb(Dwarf_Die *die_mem, void *data) 1207 static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1208 { 1208 {
1209 struct available_var_finder *af = data; 1209 struct available_var_finder *af = data;
1210 struct variable_list *vl; 1210 struct variable_list *vl;
1211 char buf[MAX_VAR_LEN]; 1211 char buf[MAX_VAR_LEN];
1212 int tag, ret; 1212 int tag, ret;
1213 1213
1214 vl = &af->vls[af->nvls - 1]; 1214 vl = &af->vls[af->nvls - 1];
1215 1215
1216 tag = dwarf_tag(die_mem); 1216 tag = dwarf_tag(die_mem);
1217 if (tag == DW_TAG_formal_parameter || 1217 if (tag == DW_TAG_formal_parameter ||
1218 tag == DW_TAG_variable) { 1218 tag == DW_TAG_variable) {
1219 ret = convert_variable_location(die_mem, af->pf.addr, 1219 ret = convert_variable_location(die_mem, af->pf.addr,
1220 af->pf.fb_ops, &af->pf.sp_die, 1220 af->pf.fb_ops, &af->pf.sp_die,
1221 NULL); 1221 NULL);
1222 if (ret == 0) { 1222 if (ret == 0) {
1223 ret = die_get_varname(die_mem, buf, MAX_VAR_LEN); 1223 ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
1224 pr_debug2("Add new var: %s\n", buf); 1224 pr_debug2("Add new var: %s\n", buf);
1225 if (ret > 0) 1225 if (ret > 0)
1226 strlist__add(vl->vars, buf); 1226 strlist__add(vl->vars, buf);
1227 } 1227 }
1228 } 1228 }
1229 1229
1230 if (af->child && dwarf_haspc(die_mem, af->pf.addr)) 1230 if (af->child && dwarf_haspc(die_mem, af->pf.addr))
1231 return DIE_FIND_CB_CONTINUE; 1231 return DIE_FIND_CB_CONTINUE;
1232 else 1232 else
1233 return DIE_FIND_CB_SIBLING; 1233 return DIE_FIND_CB_SIBLING;
1234 } 1234 }
1235 1235
1236 /* Add a found vars into available variables list */ 1236 /* Add a found vars into available variables list */
1237 static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf) 1237 static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
1238 { 1238 {
1239 struct available_var_finder *af = 1239 struct available_var_finder *af =
1240 container_of(pf, struct available_var_finder, pf); 1240 container_of(pf, struct available_var_finder, pf);
1241 struct variable_list *vl; 1241 struct variable_list *vl;
1242 Dwarf_Die die_mem; 1242 Dwarf_Die die_mem;
1243 int ret; 1243 int ret;
1244 1244
1245 /* Check number of tevs */ 1245 /* Check number of tevs */
1246 if (af->nvls == af->max_vls) { 1246 if (af->nvls == af->max_vls) {
1247 pr_warning("Too many( > %d) probe point found.\n", af->max_vls); 1247 pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
1248 return -ERANGE; 1248 return -ERANGE;
1249 } 1249 }
1250 vl = &af->vls[af->nvls++]; 1250 vl = &af->vls[af->nvls++];
1251 1251
1252 /* Trace point should be converted from subprogram DIE */ 1252 /* Trace point should be converted from subprogram DIE */
1253 ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr, 1253 ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
1254 pf->pev->point.retprobe, &vl->point); 1254 pf->pev->point.retprobe, &vl->point);
1255 if (ret < 0) 1255 if (ret < 0)
1256 return ret; 1256 return ret;
1257 1257
1258 pr_debug("Probe point found: %s+%lu\n", vl->point.symbol, 1258 pr_debug("Probe point found: %s+%lu\n", vl->point.symbol,
1259 vl->point.offset); 1259 vl->point.offset);
1260 1260
1261 /* Find local variables */ 1261 /* Find local variables */
1262 vl->vars = strlist__new(true, NULL); 1262 vl->vars = strlist__new(true, NULL);
1263 if (vl->vars == NULL) 1263 if (vl->vars == NULL)
1264 return -ENOMEM; 1264 return -ENOMEM;
1265 af->child = true; 1265 af->child = true;
1266 die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem); 1266 die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem);
1267 1267
1268 /* Find external variables */ 1268 /* Find external variables */
1269 if (!af->externs) 1269 if (!af->externs)
1270 goto out; 1270 goto out;
1271 /* Don't need to search child DIE for externs. */ 1271 /* Don't need to search child DIE for externs. */
1272 af->child = false; 1272 af->child = false;
1273 die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem); 1273 die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem);
1274 1274
1275 out: 1275 out:
1276 if (strlist__empty(vl->vars)) { 1276 if (strlist__empty(vl->vars)) {
1277 strlist__delete(vl->vars); 1277 strlist__delete(vl->vars);
1278 vl->vars = NULL; 1278 vl->vars = NULL;
1279 } 1279 }
1280 1280
1281 return ret; 1281 return ret;
1282 } 1282 }
1283 1283
1284 /* Find available variables at given probe point */ 1284 /* Find available variables at given probe point */
1285 int debuginfo__find_available_vars_at(struct debuginfo *dbg, 1285 int debuginfo__find_available_vars_at(struct debuginfo *dbg,
1286 struct perf_probe_event *pev, 1286 struct perf_probe_event *pev,
1287 struct variable_list **vls, 1287 struct variable_list **vls,
1288 int max_vls, bool externs) 1288 int max_vls, bool externs)
1289 { 1289 {
1290 struct available_var_finder af = { 1290 struct available_var_finder af = {
1291 .pf = {.pev = pev, .callback = add_available_vars}, 1291 .pf = {.pev = pev, .callback = add_available_vars},
1292 .mod = dbg->mod, 1292 .mod = dbg->mod,
1293 .max_vls = max_vls, .externs = externs}; 1293 .max_vls = max_vls, .externs = externs};
1294 int ret; 1294 int ret;
1295 1295
1296 /* Allocate result vls array */ 1296 /* Allocate result vls array */
1297 *vls = zalloc(sizeof(struct variable_list) * max_vls); 1297 *vls = zalloc(sizeof(struct variable_list) * max_vls);
1298 if (*vls == NULL) 1298 if (*vls == NULL)
1299 return -ENOMEM; 1299 return -ENOMEM;
1300 1300
1301 af.vls = *vls; 1301 af.vls = *vls;
1302 af.nvls = 0; 1302 af.nvls = 0;
1303 1303
1304 ret = debuginfo__find_probes(dbg, &af.pf); 1304 ret = debuginfo__find_probes(dbg, &af.pf);
1305 if (ret < 0) { 1305 if (ret < 0) {
1306 /* Free vlist for error */ 1306 /* Free vlist for error */
1307 while (af.nvls--) { 1307 while (af.nvls--) {
1308 zfree(&af.vls[af.nvls].point.symbol); 1308 zfree(&af.vls[af.nvls].point.symbol);
1309 strlist__delete(af.vls[af.nvls].vars); 1309 strlist__delete(af.vls[af.nvls].vars);
1310 } 1310 }
1311 zfree(vls); 1311 zfree(vls);
1312 return ret; 1312 return ret;
1313 } 1313 }
1314 1314
1315 return (ret < 0) ? ret : af.nvls; 1315 return (ret < 0) ? ret : af.nvls;
1316 } 1316 }
1317 1317
1318 /* Reverse search */ 1318 /* Reverse search */
1319 int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr, 1319 int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
1320 struct perf_probe_point *ppt) 1320 struct perf_probe_point *ppt)
1321 { 1321 {
1322 Dwarf_Die cudie, spdie, indie; 1322 Dwarf_Die cudie, spdie, indie;
1323 Dwarf_Addr _addr = 0, baseaddr = 0; 1323 Dwarf_Addr _addr = 0, baseaddr = 0;
1324 const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp; 1324 const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp;
1325 int baseline = 0, lineno = 0, ret = 0; 1325 int baseline = 0, lineno = 0, ret = 0;
1326 1326
1327 /* Adjust address with bias */ 1327 /* Adjust address with bias */
1328 addr += dbg->bias; 1328 addr += dbg->bias;
1329 1329
1330 /* Find cu die */ 1330 /* Find cu die */
1331 if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr - dbg->bias, &cudie)) { 1331 if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr - dbg->bias, &cudie)) {
1332 pr_warning("Failed to find debug information for address %lx\n", 1332 pr_warning("Failed to find debug information for address %lx\n",
1333 addr); 1333 addr);
1334 ret = -EINVAL; 1334 ret = -EINVAL;
1335 goto end; 1335 goto end;
1336 } 1336 }
1337 1337
1338 /* Find a corresponding line (filename and lineno) */ 1338 /* Find a corresponding line (filename and lineno) */
1339 cu_find_lineinfo(&cudie, addr, &fname, &lineno); 1339 cu_find_lineinfo(&cudie, addr, &fname, &lineno);
1340 /* Don't care whether it failed or not */ 1340 /* Don't care whether it failed or not */
1341 1341
1342 /* Find a corresponding function (name, baseline and baseaddr) */ 1342 /* Find a corresponding function (name, baseline and baseaddr) */
1343 if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { 1343 if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
1344 /* Get function entry information */ 1344 /* Get function entry information */
1345 func = basefunc = dwarf_diename(&spdie); 1345 func = basefunc = dwarf_diename(&spdie);
1346 if (!func || 1346 if (!func ||
1347 dwarf_entrypc(&spdie, &baseaddr) != 0 || 1347 dwarf_entrypc(&spdie, &baseaddr) != 0 ||
1348 dwarf_decl_line(&spdie, &baseline) != 0) { 1348 dwarf_decl_line(&spdie, &baseline) != 0) {
1349 lineno = 0; 1349 lineno = 0;
1350 goto post; 1350 goto post;
1351 } 1351 }
1352 1352
1353 fname = dwarf_decl_file(&spdie); 1353 fname = dwarf_decl_file(&spdie);
1354 if (addr == (unsigned long)baseaddr) { 1354 if (addr == (unsigned long)baseaddr) {
1355 /* Function entry - Relative line number is 0 */ 1355 /* Function entry - Relative line number is 0 */
1356 lineno = baseline; 1356 lineno = baseline;
1357 goto post; 1357 goto post;
1358 } 1358 }
1359 1359
1360 /* Track down the inline functions step by step */ 1360 /* Track down the inline functions step by step */
1361 while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr, 1361 while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
1362 &indie)) { 1362 &indie)) {
1363 /* There is an inline function */ 1363 /* There is an inline function */
1364 if (dwarf_entrypc(&indie, &_addr) == 0 && 1364 if (dwarf_entrypc(&indie, &_addr) == 0 &&
1365 _addr == addr) { 1365 _addr == addr) {
1366 /* 1366 /*
1367 * addr is at an inline function entry. 1367 * addr is at an inline function entry.
1368 * In this case, lineno should be the call-site 1368 * In this case, lineno should be the call-site
1369 * line number. (overwrite lineinfo) 1369 * line number. (overwrite lineinfo)
1370 */ 1370 */
1371 lineno = die_get_call_lineno(&indie); 1371 lineno = die_get_call_lineno(&indie);
1372 fname = die_get_call_file(&indie); 1372 fname = die_get_call_file(&indie);
1373 break; 1373 break;
1374 } else { 1374 } else {
1375 /* 1375 /*
1376 * addr is in an inline function body. 1376 * addr is in an inline function body.
1377 * Since lineno points one of the lines 1377 * Since lineno points one of the lines
1378 * of the inline function, baseline should 1378 * of the inline function, baseline should
1379 * be the entry line of the inline function. 1379 * be the entry line of the inline function.
1380 */ 1380 */
1381 tmp = dwarf_diename(&indie); 1381 tmp = dwarf_diename(&indie);
1382 if (!tmp || 1382 if (!tmp ||
1383 dwarf_decl_line(&indie, &baseline) != 0) 1383 dwarf_decl_line(&indie, &baseline) != 0)
1384 break; 1384 break;
1385 func = tmp; 1385 func = tmp;
1386 spdie = indie; 1386 spdie = indie;
1387 } 1387 }
1388 } 1388 }
1389 /* Verify the lineno and baseline are in a same file */ 1389 /* Verify the lineno and baseline are in a same file */
1390 tmp = dwarf_decl_file(&spdie); 1390 tmp = dwarf_decl_file(&spdie);
1391 if (!tmp || strcmp(tmp, fname) != 0) 1391 if (!tmp || strcmp(tmp, fname) != 0)
1392 lineno = 0; 1392 lineno = 0;
1393 } 1393 }
1394 1394
1395 post: 1395 post:
1396 /* Make a relative line number or an offset */ 1396 /* Make a relative line number or an offset */
1397 if (lineno) 1397 if (lineno)
1398 ppt->line = lineno - baseline; 1398 ppt->line = lineno - baseline;
1399 else if (basefunc) { 1399 else if (basefunc) {
1400 ppt->offset = addr - (unsigned long)baseaddr; 1400 ppt->offset = addr - (unsigned long)baseaddr;
1401 func = basefunc; 1401 func = basefunc;
1402 } 1402 }
1403 1403
1404 /* Duplicate strings */ 1404 /* Duplicate strings */
1405 if (func) { 1405 if (func) {
1406 ppt->function = strdup(func); 1406 ppt->function = strdup(func);
1407 if (ppt->function == NULL) { 1407 if (ppt->function == NULL) {
1408 ret = -ENOMEM; 1408 ret = -ENOMEM;
1409 goto end; 1409 goto end;
1410 } 1410 }
1411 } 1411 }
1412 if (fname) { 1412 if (fname) {
1413 ppt->file = strdup(fname); 1413 ppt->file = strdup(fname);
1414 if (ppt->file == NULL) { 1414 if (ppt->file == NULL) {
1415 zfree(&ppt->function); 1415 zfree(&ppt->function);
1416 ret = -ENOMEM; 1416 ret = -ENOMEM;
1417 goto end; 1417 goto end;
1418 } 1418 }
1419 } 1419 }
1420 end: 1420 end:
1421 if (ret == 0 && (fname || func)) 1421 if (ret == 0 && (fname || func))
1422 ret = 1; /* Found a point */ 1422 ret = 1; /* Found a point */
1423 return ret; 1423 return ret;
1424 } 1424 }
1425 1425
1426 /* Add a line and store the src path */ 1426 /* Add a line and store the src path */
1427 static int line_range_add_line(const char *src, unsigned int lineno, 1427 static int line_range_add_line(const char *src, unsigned int lineno,
1428 struct line_range *lr) 1428 struct line_range *lr)
1429 { 1429 {
1430 /* Copy source path */ 1430 /* Copy source path */
1431 if (!lr->path) { 1431 if (!lr->path) {
1432 lr->path = strdup(src); 1432 lr->path = strdup(src);
1433 if (lr->path == NULL) 1433 if (lr->path == NULL)
1434 return -ENOMEM; 1434 return -ENOMEM;
1435 } 1435 }
1436 return intlist__add(lr->line_list, lineno); 1436 return intlist__add(lr->line_list, lineno);
1437 } 1437 }
1438 1438
1439 static int line_range_walk_cb(const char *fname, int lineno, 1439 static int line_range_walk_cb(const char *fname, int lineno,
1440 Dwarf_Addr addr __maybe_unused, 1440 Dwarf_Addr addr __maybe_unused,
1441 void *data) 1441 void *data)
1442 { 1442 {
1443 struct line_finder *lf = data; 1443 struct line_finder *lf = data;
1444 int err; 1444 int err;
1445 1445
1446 if ((strtailcmp(fname, lf->fname) != 0) || 1446 if ((strtailcmp(fname, lf->fname) != 0) ||
1447 (lf->lno_s > lineno || lf->lno_e < lineno)) 1447 (lf->lno_s > lineno || lf->lno_e < lineno))
1448 return 0; 1448 return 0;
1449 1449
1450 err = line_range_add_line(fname, lineno, lf->lr); 1450 err = line_range_add_line(fname, lineno, lf->lr);
1451 if (err < 0 && err != -EEXIST) 1451 if (err < 0 && err != -EEXIST)
1452 return err; 1452 return err;
1453 1453
1454 return 0; 1454 return 0;
1455 } 1455 }
1456 1456
1457 /* Find line range from its line number */ 1457 /* Find line range from its line number */
1458 static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) 1458 static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
1459 { 1459 {
1460 int ret; 1460 int ret;
1461 1461
1462 ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf); 1462 ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf);
1463 1463
1464 /* Update status */ 1464 /* Update status */
1465 if (ret >= 0) 1465 if (ret >= 0)
1466 if (!intlist__empty(lf->lr->line_list)) 1466 if (!intlist__empty(lf->lr->line_list))
1467 ret = lf->found = 1; 1467 ret = lf->found = 1;
1468 else 1468 else
1469 ret = 0; /* Lines are not found */ 1469 ret = 0; /* Lines are not found */
1470 else { 1470 else {
1471 zfree(&lf->lr->path); 1471 zfree(&lf->lr->path);
1472 } 1472 }
1473 return ret; 1473 return ret;
1474 } 1474 }
1475 1475
1476 static int line_range_inline_cb(Dwarf_Die *in_die, void *data) 1476 static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
1477 { 1477 {
1478 int ret = find_line_range_by_line(in_die, data); 1478 int ret = find_line_range_by_line(in_die, data);
1479 1479
1480 /* 1480 /*
1481 * We have to check all instances of inlined function, because 1481 * We have to check all instances of inlined function, because
1482 * some execution paths can be optimized out depends on the 1482 * some execution paths can be optimized out depends on the
1483 * function argument of instances. However, if an error occurs, 1483 * function argument of instances. However, if an error occurs,
1484 * it should be handled by the caller. 1484 * it should be handled by the caller.
1485 */ 1485 */
1486 return ret < 0 ? ret : 0; 1486 return ret < 0 ? ret : 0;
1487 } 1487 }
1488 1488
1489 /* Search function definition from function name */ 1489 /* Search function definition from function name */
1490 static int line_range_search_cb(Dwarf_Die *sp_die, void *data) 1490 static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
1491 { 1491 {
1492 struct dwarf_callback_param *param = data; 1492 struct dwarf_callback_param *param = data;
1493 struct line_finder *lf = param->data; 1493 struct line_finder *lf = param->data;
1494 struct line_range *lr = lf->lr; 1494 struct line_range *lr = lf->lr;
1495 1495
1496 /* Check declared file */ 1496 /* Check declared file */
1497 if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die))) 1497 if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
1498 return DWARF_CB_OK; 1498 return DWARF_CB_OK;
1499 1499
1500 if (die_is_func_def(sp_die) && 1500 if (die_is_func_def(sp_die) &&
1501 die_compare_name(sp_die, lr->function)) { 1501 die_compare_name(sp_die, lr->function)) {
1502 lf->fname = dwarf_decl_file(sp_die); 1502 lf->fname = dwarf_decl_file(sp_die);
1503 dwarf_decl_line(sp_die, &lr->offset); 1503 dwarf_decl_line(sp_die, &lr->offset);
1504 pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset); 1504 pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
1505 lf->lno_s = lr->offset + lr->start; 1505 lf->lno_s = lr->offset + lr->start;
1506 if (lf->lno_s < 0) /* Overflow */ 1506 if (lf->lno_s < 0) /* Overflow */
1507 lf->lno_s = INT_MAX; 1507 lf->lno_s = INT_MAX;
1508 lf->lno_e = lr->offset + lr->end; 1508 lf->lno_e = lr->offset + lr->end;
1509 if (lf->lno_e < 0) /* Overflow */ 1509 if (lf->lno_e < 0) /* Overflow */
1510 lf->lno_e = INT_MAX; 1510 lf->lno_e = INT_MAX;
1511 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); 1511 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
1512 lr->start = lf->lno_s; 1512 lr->start = lf->lno_s;
1513 lr->end = lf->lno_e; 1513 lr->end = lf->lno_e;
1514 if (dwarf_func_inline(sp_die)) 1514 if (dwarf_func_inline(sp_die))
1515 param->retval = die_walk_instances(sp_die, 1515 param->retval = die_walk_instances(sp_die,
1516 line_range_inline_cb, lf); 1516 line_range_inline_cb, lf);
1517 else 1517 else
1518 param->retval = find_line_range_by_line(sp_die, lf); 1518 param->retval = find_line_range_by_line(sp_die, lf);
1519 return DWARF_CB_ABORT; 1519 return DWARF_CB_ABORT;
1520 } 1520 }
1521 return DWARF_CB_OK; 1521 return DWARF_CB_OK;
1522 } 1522 }
1523 1523
1524 static int find_line_range_by_func(struct line_finder *lf) 1524 static int find_line_range_by_func(struct line_finder *lf)
1525 { 1525 {
1526 struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0}; 1526 struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
1527 dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0); 1527 dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0);
1528 return param.retval; 1528 return param.retval;
1529 } 1529 }
1530 1530
1531 int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr) 1531 int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
1532 { 1532 {
1533 struct line_finder lf = {.lr = lr, .found = 0}; 1533 struct line_finder lf = {.lr = lr, .found = 0};
1534 int ret = 0; 1534 int ret = 0;
1535 Dwarf_Off off = 0, noff; 1535 Dwarf_Off off = 0, noff;
1536 size_t cuhl; 1536 size_t cuhl;
1537 Dwarf_Die *diep; 1537 Dwarf_Die *diep;
1538 const char *comp_dir; 1538 const char *comp_dir;
1539 1539
1540 /* Fastpath: lookup by function name from .debug_pubnames section */ 1540 /* Fastpath: lookup by function name from .debug_pubnames section */
1541 if (lr->function) { 1541 if (lr->function) {
1542 struct pubname_callback_param pubname_param = { 1542 struct pubname_callback_param pubname_param = {
1543 .function = lr->function, .file = lr->file, 1543 .function = lr->function, .file = lr->file,
1544 .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0}; 1544 .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
1545 struct dwarf_callback_param line_range_param = { 1545 struct dwarf_callback_param line_range_param = {
1546 .data = (void *)&lf, .retval = 0}; 1546 .data = (void *)&lf, .retval = 0};
1547 1547
1548 dwarf_getpubnames(dbg->dbg, pubname_search_cb, 1548 dwarf_getpubnames(dbg->dbg, pubname_search_cb,
1549 &pubname_param, 0); 1549 &pubname_param, 0);
1550 if (pubname_param.found) { 1550 if (pubname_param.found) {
1551 line_range_search_cb(&lf.sp_die, &line_range_param); 1551 line_range_search_cb(&lf.sp_die, &line_range_param);
1552 if (lf.found) 1552 if (lf.found)
1553 goto found; 1553 goto found;
1554 } 1554 }
1555 } 1555 }
1556 1556
1557 /* Loop on CUs (Compilation Unit) */ 1557 /* Loop on CUs (Compilation Unit) */
1558 while (!lf.found && ret >= 0) { 1558 while (!lf.found && ret >= 0) {
1559 if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, 1559 if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl,
1560 NULL, NULL, NULL) != 0) 1560 NULL, NULL, NULL) != 0)
1561 break; 1561 break;
1562 1562
1563 /* Get the DIE(Debugging Information Entry) of this CU */ 1563 /* Get the DIE(Debugging Information Entry) of this CU */
1564 diep = dwarf_offdie(dbg->dbg, off + cuhl, &lf.cu_die); 1564 diep = dwarf_offdie(dbg->dbg, off + cuhl, &lf.cu_die);
1565 if (!diep) 1565 if (!diep)
1566 continue; 1566 continue;
1567 1567
1568 /* Check if target file is included. */ 1568 /* Check if target file is included. */
1569 if (lr->file) 1569 if (lr->file)
1570 lf.fname = cu_find_realpath(&lf.cu_die, lr->file); 1570 lf.fname = cu_find_realpath(&lf.cu_die, lr->file);
1571 else 1571 else
1572 lf.fname = 0; 1572 lf.fname = 0;
1573 1573
1574 if (!lr->file || lf.fname) { 1574 if (!lr->file || lf.fname) {
1575 if (lr->function) 1575 if (lr->function)
1576 ret = find_line_range_by_func(&lf); 1576 ret = find_line_range_by_func(&lf);
1577 else { 1577 else {
1578 lf.lno_s = lr->start; 1578 lf.lno_s = lr->start;
1579 lf.lno_e = lr->end; 1579 lf.lno_e = lr->end;
1580 ret = find_line_range_by_line(NULL, &lf); 1580 ret = find_line_range_by_line(NULL, &lf);
1581 } 1581 }
1582 } 1582 }
1583 off = noff; 1583 off = noff;
1584 } 1584 }
1585 1585
1586 found: 1586 found:
1587 /* Store comp_dir */ 1587 /* Store comp_dir */
1588 if (lf.found) { 1588 if (lf.found) {
1589 comp_dir = cu_get_comp_dir(&lf.cu_die); 1589 comp_dir = cu_get_comp_dir(&lf.cu_die);
1590 if (comp_dir) { 1590 if (comp_dir) {
1591 lr->comp_dir = strdup(comp_dir); 1591 lr->comp_dir = strdup(comp_dir);
1592 if (!lr->comp_dir) 1592 if (!lr->comp_dir)
1593 ret = -ENOMEM; 1593 ret = -ENOMEM;
1594 } 1594 }
1595 } 1595 }
1596 1596
1597 pr_debug("path: %s\n", lr->path); 1597 pr_debug("path: %s\n", lr->path);
1598 return (ret < 0) ? ret : lf.found; 1598 return (ret < 0) ? ret : lf.found;
1599 } 1599 }
1600 1600
1601 1601