]>
Commit | Line | Data |
---|---|---|
252b5132 | 1 | /* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line). |
7442e600 | 2 | Copyright 1998, 1999 Free Software Foundation, Inc. |
252b5132 RH |
3 | |
4 | Written by Gavin Romig-Koch of Cygnus Solutions ([email protected]). | |
5 | ||
6 | This file is part of BFD. | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2 of the License, or (at | |
11 | your option) any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, but | |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; if not, write to the Free Software | |
20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
21 | ||
22 | #include "bfd.h" | |
23 | #include "sysdep.h" | |
24 | #include "libiberty.h" | |
25 | #include "libbfd.h" | |
26 | #include "elf-bfd.h" | |
27 | #include "elf/dwarf.h" | |
28 | ||
29 | /* dwarf1_debug is the starting point for all dwarf1 info. */ | |
30 | ||
31 | struct dwarf1_debug { | |
32 | ||
33 | /* The bfd we are working with. */ | |
34 | bfd* abfd; | |
35 | ||
36 | /* List of already parsed compilation units. */ | |
37 | struct dwarf1_unit* lastUnit; | |
38 | ||
39 | /* The buffer for the .debug section. | |
40 | Zero indicates that the .debug section failed to load. */ | |
41 | char* debug_section; | |
42 | ||
43 | /* Pointer to the end of the .debug_info section memory buffer. */ | |
44 | char* debug_section_end; | |
45 | ||
46 | /* The buffer for the .line section. */ | |
47 | char* line_section; | |
48 | ||
49 | /* End of that buffer. */ | |
50 | char* line_section_end; | |
51 | ||
52 | /* The current or next unread die within the .debug section. */ | |
53 | char* currentDie; | |
54 | }; | |
55 | ||
56 | /* One dwarf1_unit for each parsed compilation unit die. */ | |
57 | ||
58 | struct dwarf1_unit { | |
59 | /* Linked starting from stash->lastUnit. */ | |
60 | struct dwarf1_unit* prev; | |
61 | ||
62 | /* Name of the compilation unit. */ | |
63 | char* name; | |
64 | ||
65 | /* The highest and lowest address used in the compilation unit. */ | |
66 | unsigned long low_pc; | |
67 | unsigned long high_pc; | |
68 | ||
69 | /* Does this unit have a statement list? */ | |
70 | int has_stmt_list; | |
71 | ||
72 | /* If any, the offset of the line number table in the .line section. */ | |
73 | unsigned long stmt_list_offset; | |
74 | ||
75 | /* If non-zero, a pointer to the first child of this unit. */ | |
76 | char* first_child; | |
77 | ||
78 | /* How many line entries? */ | |
79 | unsigned long line_count; | |
80 | ||
81 | /* The decoded line number table (line_count entries). */ | |
82 | struct linenumber* linenumber_table; | |
83 | ||
84 | /* The list of functions in this unit. */ | |
85 | struct dwarf1_func* func_list; | |
86 | }; | |
87 | ||
88 | ||
89 | ||
90 | /* One dwarf1_func for each parsed function die. */ | |
91 | ||
92 | struct dwarf1_func { | |
93 | /* Linked starting from aUnit->func_list. */ | |
94 | struct dwarf1_func* prev; | |
95 | ||
96 | /* Name of function. */ | |
97 | char* name; | |
98 | ||
99 | /* The highest and lowest address used in the compilation unit. */ | |
100 | unsigned long low_pc; | |
101 | unsigned long high_pc; | |
102 | }; | |
103 | ||
104 | ||
105 | /* Used to return info about a parsed die. */ | |
106 | struct die_info { | |
107 | unsigned long length; | |
108 | unsigned long sibling; | |
109 | unsigned long low_pc; | |
110 | unsigned long high_pc; | |
111 | unsigned long stmt_list_offset; | |
112 | ||
113 | char* name; | |
114 | ||
115 | int has_stmt_list; | |
116 | ||
117 | unsigned short tag; | |
118 | }; | |
119 | ||
120 | ||
121 | /* Parsed line number information. */ | |
122 | struct linenumber { | |
123 | /* First address in the line. */ | |
124 | unsigned long addr; | |
125 | ||
126 | /* The line number. */ | |
127 | unsigned long linenumber; | |
128 | }; | |
129 | ||
130 | ||
131 | /* Find the form of an attr, from the attr field. */ | |
132 | #define FORM_FROM_ATTR(attr) ((attr) & 0xF) /* Implicitly specified */ | |
133 | ||
134 | ||
135 | /* Return a newly allocated dwarf1_unit. It should be cleared and | |
136 | then attached into the 'stash' at 'stash->lastUnit'. */ | |
137 | ||
138 | static struct dwarf1_unit* | |
139 | alloc_dwarf1_unit (stash) | |
140 | struct dwarf1_debug* stash; | |
141 | { | |
142 | struct dwarf1_unit* x = | |
aec89efb JR |
143 | (struct dwarf1_unit*) bfd_zalloc (stash->abfd, |
144 | sizeof (struct dwarf1_unit)); | |
252b5132 RH |
145 | x->prev = stash->lastUnit; |
146 | stash->lastUnit = x; | |
147 | ||
148 | return x; | |
149 | } | |
150 | ||
151 | /* Return a newly allocated dwarf1_func. It must be cleared and | |
152 | attached into 'aUnit' at 'aUnit->func_list'. */ | |
153 | ||
154 | static struct dwarf1_func* | |
155 | alloc_dwarf1_func (stash, aUnit) | |
156 | struct dwarf1_debug* stash; | |
157 | struct dwarf1_unit* aUnit; | |
158 | { | |
159 | struct dwarf1_func* x = | |
aec89efb JR |
160 | (struct dwarf1_func*) bfd_zalloc (stash->abfd, |
161 | sizeof (struct dwarf1_func)); | |
252b5132 RH |
162 | x->prev = aUnit->func_list; |
163 | aUnit->func_list = x; | |
164 | ||
165 | return x; | |
166 | } | |
167 | ||
168 | /* parse_die - parse a Dwarf1 die. | |
169 | Parse the die starting at 'aDiePtr' into 'aDieInfo'. | |
170 | 'abfd' must be the bfd from which the section that 'aDiePtr' | |
171 | points to was pulled from. | |
172 | ||
173 | Return false if the die is invalidly formatted; true otherwise. */ | |
174 | ||
175 | static boolean | |
176 | parse_die (abfd, aDieInfo, aDiePtr) | |
177 | bfd* abfd; | |
178 | struct die_info* aDieInfo; | |
179 | char* aDiePtr; | |
180 | { | |
181 | char* this_die = aDiePtr; | |
182 | char* xptr = this_die; | |
183 | ||
184 | memset (aDieInfo,0,sizeof(*aDieInfo)); | |
185 | ||
186 | /* First comes the length. */ | |
187 | aDieInfo->length = bfd_get_32 (abfd, xptr); | |
188 | xptr += 4; | |
189 | if (aDieInfo->length < 6) | |
190 | { | |
191 | /* Just padding bytes. */ | |
192 | aDieInfo->tag = TAG_padding; | |
193 | return true; | |
194 | } | |
195 | ||
196 | /* Then the tag. */ | |
197 | aDieInfo->tag = bfd_get_16 (abfd, xptr); | |
198 | xptr += 2; | |
199 | ||
200 | /* Then the attributes. */ | |
201 | while (xptr < (this_die + aDieInfo->length)) | |
202 | { | |
203 | unsigned short attr; | |
204 | ||
205 | /* Parse the attribute based on its form. This section | |
206 | must handle all dwarf1 forms, but need only handle the | |
207 | actual attributes that we care about. */ | |
208 | ||
209 | attr = bfd_get_16 (abfd, xptr); | |
210 | xptr += 2; | |
211 | ||
212 | switch (FORM_FROM_ATTR (attr)) | |
213 | { | |
214 | case FORM_DATA2: | |
215 | xptr += 2; | |
216 | break; | |
217 | case FORM_DATA4: | |
218 | case FORM_REF: | |
219 | if (attr == AT_sibling) | |
220 | aDieInfo->sibling = bfd_get_32 (abfd, xptr); | |
221 | else if (attr == AT_stmt_list) | |
222 | { | |
223 | aDieInfo->stmt_list_offset = bfd_get_32 (abfd, xptr); | |
224 | aDieInfo->has_stmt_list = 1; | |
225 | } | |
226 | xptr += 4; | |
227 | break; | |
228 | case FORM_DATA8: | |
229 | xptr += 8; | |
230 | break; | |
231 | case FORM_ADDR: | |
232 | if (attr == AT_low_pc) | |
233 | aDieInfo->low_pc = bfd_get_32 (abfd, xptr); | |
234 | else if (attr == AT_high_pc) | |
235 | aDieInfo->high_pc = bfd_get_32 (abfd, xptr); | |
236 | xptr += 4; | |
237 | break; | |
238 | case FORM_BLOCK2: | |
239 | xptr += 2 + bfd_get_16 (abfd, xptr); | |
240 | break; | |
241 | case FORM_BLOCK4: | |
242 | xptr += 4 + bfd_get_32 (abfd, xptr); | |
243 | break; | |
244 | case FORM_STRING: | |
245 | if (attr == AT_name) | |
246 | aDieInfo->name = xptr; | |
247 | xptr += strlen (xptr) + 1; | |
248 | break; | |
249 | } | |
250 | } | |
251 | ||
252 | return true; | |
253 | } | |
254 | ||
255 | /* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset' | |
256 | into 'aUnit->linenumber_table'. Return false if an error | |
257 | occurs; true otherwise. */ | |
258 | ||
259 | static boolean | |
260 | parse_line_table (stash, aUnit) | |
261 | struct dwarf1_debug* stash; | |
262 | struct dwarf1_unit* aUnit; | |
263 | { | |
264 | char* xptr; | |
265 | ||
266 | /* Load the ".line" section from the bfd if we haven't already. */ | |
267 | if (stash->line_section == 0) | |
268 | { | |
269 | asection *msec; | |
270 | unsigned long size; | |
271 | ||
272 | msec = bfd_get_section_by_name (stash->abfd, ".line"); | |
273 | if (! msec) | |
274 | return false; | |
275 | ||
276 | size = bfd_get_section_size_before_reloc (msec); | |
277 | stash->line_section = (unsigned char*) bfd_alloc (stash->abfd, size); | |
278 | ||
279 | if (! stash->line_section) | |
280 | return false; | |
281 | ||
282 | if (! bfd_get_section_contents (stash->abfd, msec, stash->line_section, 0, size)) | |
283 | { | |
284 | stash->line_section = 0; | |
285 | return false; | |
286 | } | |
287 | ||
288 | stash->line_section_end = stash->line_section + size; | |
289 | } | |
290 | ||
291 | xptr = stash->line_section + aUnit->stmt_list_offset; | |
292 | if (xptr < stash->line_section_end) | |
293 | { | |
7442e600 | 294 | unsigned long eachLine; |
252b5132 RH |
295 | |
296 | char* tblend; | |
297 | unsigned long base; | |
298 | ||
299 | /* First comes the length. */ | |
300 | tblend = bfd_get_32 (stash->abfd, xptr) + xptr; | |
301 | xptr += 4; | |
302 | ||
303 | /* Then the base address for each address in the table. */ | |
304 | base = bfd_get_32 (stash->abfd, xptr); | |
305 | xptr += 4; | |
306 | ||
307 | /* How many line entrys? | |
308 | 10 = 4 (line number) + 2 (pos in line) + 4 (address in line) */ | |
309 | aUnit->line_count = (tblend - xptr) / 10; | |
310 | ||
311 | /* Allocate an array for the entries. */ | |
312 | aUnit->linenumber_table = (struct linenumber*) | |
313 | bfd_alloc (stash->abfd, | |
314 | sizeof (struct linenumber) * aUnit->line_count); | |
315 | ||
316 | for (eachLine = 0; eachLine < aUnit->line_count; eachLine++) | |
317 | { | |
318 | /* A line number. */ | |
319 | aUnit->linenumber_table[eachLine].linenumber | |
320 | = bfd_get_32 (stash->abfd, xptr); | |
321 | xptr += 4; | |
322 | ||
323 | /* Skip the position within the line. */ | |
324 | xptr += 2; | |
325 | ||
326 | /* And finally the address. */ | |
327 | aUnit->linenumber_table[eachLine].addr | |
328 | = base + bfd_get_32 (stash->abfd, xptr); | |
329 | xptr += 4; | |
330 | } | |
331 | } | |
332 | ||
333 | return true; | |
334 | } | |
335 | ||
336 | /* Parse each function die in a compilation unit 'aUnit'. | |
337 | The first child die of 'aUnit' should be in 'aUnit->first_child', | |
338 | the result is placed in 'aUnit->func_list'. | |
339 | Return false if error; true otherwise. */ | |
340 | ||
341 | static boolean | |
342 | parse_functions_in_unit (stash, aUnit) | |
343 | struct dwarf1_debug* stash; | |
344 | struct dwarf1_unit* aUnit; | |
345 | { | |
346 | char* eachDie; | |
347 | ||
348 | if (aUnit->first_child) | |
349 | for (eachDie = aUnit->first_child; | |
350 | eachDie < stash->debug_section_end; | |
351 | ) | |
352 | { | |
353 | struct die_info eachDieInfo; | |
354 | ||
355 | if (! parse_die (stash->abfd, &eachDieInfo, eachDie)) | |
356 | return false; | |
357 | ||
358 | if (eachDieInfo.tag == TAG_global_subroutine | |
359 | || eachDieInfo.tag == TAG_subroutine | |
360 | || eachDieInfo.tag == TAG_inlined_subroutine | |
361 | || eachDieInfo.tag == TAG_entry_point) | |
362 | { | |
363 | struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit); | |
364 | ||
365 | aFunc->name = eachDieInfo.name; | |
366 | aFunc->low_pc = eachDieInfo.low_pc; | |
367 | aFunc->high_pc = eachDieInfo.high_pc; | |
368 | } | |
369 | ||
370 | /* Move to next sibling, if none, end loop */ | |
371 | if (eachDieInfo.sibling) | |
372 | eachDie = stash->debug_section + eachDieInfo.sibling; | |
373 | else | |
374 | break; | |
375 | } | |
376 | ||
377 | return true; | |
378 | } | |
379 | ||
380 | /* Find the nearest line to 'addr' in 'aUnit'. | |
381 | Return whether we found the line (or a function) without error. */ | |
382 | ||
383 | static boolean | |
384 | dwarf1_unit_find_nearest_line (stash, aUnit, addr, | |
385 | filename_ptr, functionname_ptr, | |
386 | linenumber_ptr) | |
387 | struct dwarf1_debug* stash; | |
388 | struct dwarf1_unit* aUnit; | |
389 | unsigned long addr; | |
390 | const char **filename_ptr; | |
391 | const char **functionname_ptr; | |
392 | unsigned int *linenumber_ptr; | |
393 | { | |
394 | int line_p = false; | |
395 | int func_p = false; | |
396 | ||
397 | if (aUnit->low_pc <= addr && addr < aUnit->high_pc) | |
398 | { | |
399 | if (aUnit->has_stmt_list) | |
400 | { | |
7442e600 | 401 | unsigned long i; |
252b5132 RH |
402 | struct dwarf1_func* eachFunc; |
403 | ||
404 | if (! aUnit->linenumber_table) | |
405 | { | |
406 | if (! parse_line_table (stash, aUnit)) | |
407 | return false; | |
408 | } | |
409 | ||
410 | if (! aUnit->func_list) | |
411 | { | |
412 | if (! parse_functions_in_unit (stash, aUnit)) | |
413 | return false; | |
414 | } | |
415 | ||
416 | for (i = 0; i < aUnit->line_count; i++) | |
417 | { | |
418 | if (aUnit->linenumber_table[i].addr <= addr | |
419 | && addr < aUnit->linenumber_table[i+1].addr) | |
420 | { | |
421 | *filename_ptr = aUnit->name; | |
422 | *linenumber_ptr = aUnit->linenumber_table[i].linenumber; | |
423 | line_p = true; | |
424 | break; | |
425 | } | |
426 | } | |
427 | ||
428 | for (eachFunc = aUnit->func_list; | |
429 | eachFunc; | |
430 | eachFunc = eachFunc->prev) | |
431 | { | |
432 | if (eachFunc->low_pc <= addr | |
433 | && addr < eachFunc->high_pc) | |
434 | { | |
435 | *functionname_ptr = eachFunc->name; | |
436 | func_p = true; | |
437 | break; | |
438 | } | |
439 | } | |
440 | } | |
441 | } | |
442 | ||
443 | return line_p || func_p; | |
444 | } | |
445 | ||
446 | ||
447 | ||
448 | ||
449 | /* The DWARF 1 version of find_nearest line. | |
450 | Return true if the line is found without error. */ | |
451 | ||
452 | boolean | |
453 | _bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, | |
454 | filename_ptr, functionname_ptr, linenumber_ptr) | |
455 | bfd *abfd; | |
456 | asection *section; | |
7442e600 | 457 | asymbol **symbols ATTRIBUTE_UNUSED; |
252b5132 RH |
458 | bfd_vma offset; |
459 | const char **filename_ptr; | |
460 | const char **functionname_ptr; | |
461 | unsigned int *linenumber_ptr; | |
462 | { | |
463 | struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info; | |
464 | ||
465 | struct dwarf1_unit* eachUnit; | |
466 | ||
467 | /* What address are we looking for? */ | |
468 | bfd_vma addr = offset + section->vma; | |
469 | ||
470 | *filename_ptr = NULL; | |
471 | *functionname_ptr = NULL; | |
472 | *linenumber_ptr = 0; | |
473 | ||
474 | ||
475 | if (! stash) | |
476 | { | |
477 | asection *msec; | |
478 | unsigned long size; | |
479 | ||
480 | stash = elf_tdata (abfd)->dwarf1_find_line_info = | |
481 | (struct dwarf1_debug*) bfd_zalloc (abfd, sizeof (struct dwarf1_debug)); | |
482 | ||
483 | if (! stash) | |
484 | return false; | |
485 | ||
486 | msec = bfd_get_section_by_name (abfd, ".debug"); | |
487 | if (! msec) | |
488 | { | |
489 | /* No dwarf1 info. Note that at this point the stash | |
490 | has been allocated, but contains zeros, this lets | |
491 | future calls to this function fail quicker. */ | |
492 | return false; | |
493 | } | |
494 | ||
495 | size = bfd_get_section_size_before_reloc (msec); | |
496 | stash->debug_section = (unsigned char*) bfd_alloc (abfd, size); | |
497 | ||
498 | if (! stash->debug_section) | |
499 | return false; | |
500 | ||
501 | if (! bfd_get_section_contents (abfd, msec, stash->debug_section, 0, size)) | |
502 | { | |
503 | stash->debug_section = 0; | |
504 | return false; | |
505 | } | |
506 | ||
507 | stash->debug_section_end = stash->debug_section + size; | |
508 | stash->currentDie = stash->debug_section; | |
509 | stash->abfd = abfd; | |
510 | } | |
511 | ||
512 | /* A null debug_section indicates that there was no dwarf1 info | |
513 | or that an error occured while setting up the stash. */ | |
514 | ||
515 | if (! stash->debug_section) | |
516 | return false; | |
517 | ||
518 | ||
519 | /* Look at the previously parsed units to see if any contain | |
520 | the addr. */ | |
521 | for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev) | |
522 | { | |
523 | if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc) | |
524 | return dwarf1_unit_find_nearest_line (stash, eachUnit, addr, | |
525 | filename_ptr, | |
526 | functionname_ptr, | |
527 | linenumber_ptr); | |
528 | } | |
529 | ||
530 | while (stash->currentDie < stash->debug_section_end) | |
531 | { | |
532 | struct die_info aDieInfo; | |
533 | ||
534 | if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie)) | |
535 | return false; | |
536 | ||
537 | if (aDieInfo.tag == TAG_compile_unit) | |
538 | { | |
539 | struct dwarf1_unit* aUnit | |
540 | = alloc_dwarf1_unit (stash); | |
541 | ||
542 | aUnit->name = aDieInfo.name; | |
543 | aUnit->low_pc = aDieInfo.low_pc; | |
544 | aUnit->high_pc = aDieInfo.high_pc; | |
545 | aUnit->has_stmt_list = aDieInfo.has_stmt_list; | |
546 | aUnit->stmt_list_offset = aDieInfo.stmt_list_offset; | |
547 | ||
548 | /* A die has a child if it's followed by a die that is | |
549 | not it's sibling. */ | |
550 | if (aDieInfo.sibling | |
551 | && stash->currentDie + aDieInfo.length | |
552 | < stash->debug_section_end | |
553 | && stash->currentDie + aDieInfo.length | |
554 | != stash->debug_section + aDieInfo.sibling) | |
555 | aUnit->first_child = stash->currentDie + aDieInfo.length; | |
556 | else | |
557 | aUnit->first_child = 0; | |
558 | ||
559 | if (aUnit->low_pc <= addr && addr < aUnit->high_pc) | |
560 | return dwarf1_unit_find_nearest_line (stash, aUnit, addr, | |
561 | filename_ptr, | |
562 | functionname_ptr, | |
563 | linenumber_ptr); | |
564 | } | |
565 | ||
566 | if (aDieInfo.sibling != 0) | |
567 | stash->currentDie = stash->debug_section + aDieInfo.sibling; | |
568 | else | |
569 | stash->currentDie += aDieInfo.length; | |
570 | } | |
571 | ||
572 | return false; | |
573 | } | |
574 | ||
575 | ||
576 | /* EOF */ |