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 (gavin@cygnus.com). | |
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; | |
a67a8777 AH |
189 | if (aDieInfo->length == 0) |
190 | return false; | |
252b5132 RH |
191 | if (aDieInfo->length < 6) |
192 | { | |
193 | /* Just padding bytes. */ | |
194 | aDieInfo->tag = TAG_padding; | |
195 | return true; | |
196 | } | |
197 | ||
198 | /* Then the tag. */ | |
199 | aDieInfo->tag = bfd_get_16 (abfd, xptr); | |
200 | xptr += 2; | |
201 | ||
202 | /* Then the attributes. */ | |
203 | while (xptr < (this_die + aDieInfo->length)) | |
204 | { | |
205 | unsigned short attr; | |
206 | ||
207 | /* Parse the attribute based on its form. This section | |
208 | must handle all dwarf1 forms, but need only handle the | |
209 | actual attributes that we care about. */ | |
210 | ||
211 | attr = bfd_get_16 (abfd, xptr); | |
212 | xptr += 2; | |
213 | ||
214 | switch (FORM_FROM_ATTR (attr)) | |
215 | { | |
216 | case FORM_DATA2: | |
217 | xptr += 2; | |
218 | break; | |
219 | case FORM_DATA4: | |
220 | case FORM_REF: | |
221 | if (attr == AT_sibling) | |
222 | aDieInfo->sibling = bfd_get_32 (abfd, xptr); | |
223 | else if (attr == AT_stmt_list) | |
224 | { | |
225 | aDieInfo->stmt_list_offset = bfd_get_32 (abfd, xptr); | |
226 | aDieInfo->has_stmt_list = 1; | |
227 | } | |
228 | xptr += 4; | |
229 | break; | |
230 | case FORM_DATA8: | |
231 | xptr += 8; | |
232 | break; | |
233 | case FORM_ADDR: | |
234 | if (attr == AT_low_pc) | |
235 | aDieInfo->low_pc = bfd_get_32 (abfd, xptr); | |
236 | else if (attr == AT_high_pc) | |
237 | aDieInfo->high_pc = bfd_get_32 (abfd, xptr); | |
238 | xptr += 4; | |
239 | break; | |
240 | case FORM_BLOCK2: | |
241 | xptr += 2 + bfd_get_16 (abfd, xptr); | |
242 | break; | |
243 | case FORM_BLOCK4: | |
244 | xptr += 4 + bfd_get_32 (abfd, xptr); | |
245 | break; | |
246 | case FORM_STRING: | |
247 | if (attr == AT_name) | |
248 | aDieInfo->name = xptr; | |
249 | xptr += strlen (xptr) + 1; | |
250 | break; | |
251 | } | |
252 | } | |
253 | ||
254 | return true; | |
255 | } | |
256 | ||
257 | /* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset' | |
258 | into 'aUnit->linenumber_table'. Return false if an error | |
259 | occurs; true otherwise. */ | |
260 | ||
261 | static boolean | |
262 | parse_line_table (stash, aUnit) | |
263 | struct dwarf1_debug* stash; | |
264 | struct dwarf1_unit* aUnit; | |
265 | { | |
266 | char* xptr; | |
267 | ||
268 | /* Load the ".line" section from the bfd if we haven't already. */ | |
269 | if (stash->line_section == 0) | |
270 | { | |
271 | asection *msec; | |
272 | unsigned long size; | |
273 | ||
274 | msec = bfd_get_section_by_name (stash->abfd, ".line"); | |
275 | if (! msec) | |
276 | return false; | |
277 | ||
278 | size = bfd_get_section_size_before_reloc (msec); | |
279 | stash->line_section = (unsigned char*) bfd_alloc (stash->abfd, size); | |
280 | ||
281 | if (! stash->line_section) | |
282 | return false; | |
283 | ||
284 | if (! bfd_get_section_contents (stash->abfd, msec, stash->line_section, 0, size)) | |
285 | { | |
286 | stash->line_section = 0; | |
287 | return false; | |
288 | } | |
289 | ||
290 | stash->line_section_end = stash->line_section + size; | |
291 | } | |
292 | ||
293 | xptr = stash->line_section + aUnit->stmt_list_offset; | |
294 | if (xptr < stash->line_section_end) | |
295 | { | |
7442e600 | 296 | unsigned long eachLine; |
252b5132 RH |
297 | |
298 | char* tblend; | |
299 | unsigned long base; | |
300 | ||
301 | /* First comes the length. */ | |
302 | tblend = bfd_get_32 (stash->abfd, xptr) + xptr; | |
303 | xptr += 4; | |
304 | ||
305 | /* Then the base address for each address in the table. */ | |
306 | base = bfd_get_32 (stash->abfd, xptr); | |
307 | xptr += 4; | |
308 | ||
309 | /* How many line entrys? | |
310 | 10 = 4 (line number) + 2 (pos in line) + 4 (address in line) */ | |
311 | aUnit->line_count = (tblend - xptr) / 10; | |
312 | ||
313 | /* Allocate an array for the entries. */ | |
314 | aUnit->linenumber_table = (struct linenumber*) | |
315 | bfd_alloc (stash->abfd, | |
316 | sizeof (struct linenumber) * aUnit->line_count); | |
317 | ||
318 | for (eachLine = 0; eachLine < aUnit->line_count; eachLine++) | |
319 | { | |
320 | /* A line number. */ | |
321 | aUnit->linenumber_table[eachLine].linenumber | |
322 | = bfd_get_32 (stash->abfd, xptr); | |
323 | xptr += 4; | |
324 | ||
325 | /* Skip the position within the line. */ | |
326 | xptr += 2; | |
327 | ||
328 | /* And finally the address. */ | |
329 | aUnit->linenumber_table[eachLine].addr | |
330 | = base + bfd_get_32 (stash->abfd, xptr); | |
331 | xptr += 4; | |
332 | } | |
333 | } | |
334 | ||
335 | return true; | |
336 | } | |
337 | ||
338 | /* Parse each function die in a compilation unit 'aUnit'. | |
339 | The first child die of 'aUnit' should be in 'aUnit->first_child', | |
340 | the result is placed in 'aUnit->func_list'. | |
341 | Return false if error; true otherwise. */ | |
342 | ||
343 | static boolean | |
344 | parse_functions_in_unit (stash, aUnit) | |
345 | struct dwarf1_debug* stash; | |
346 | struct dwarf1_unit* aUnit; | |
347 | { | |
348 | char* eachDie; | |
349 | ||
350 | if (aUnit->first_child) | |
351 | for (eachDie = aUnit->first_child; | |
352 | eachDie < stash->debug_section_end; | |
353 | ) | |
354 | { | |
355 | struct die_info eachDieInfo; | |
356 | ||
357 | if (! parse_die (stash->abfd, &eachDieInfo, eachDie)) | |
358 | return false; | |
359 | ||
360 | if (eachDieInfo.tag == TAG_global_subroutine | |
361 | || eachDieInfo.tag == TAG_subroutine | |
362 | || eachDieInfo.tag == TAG_inlined_subroutine | |
363 | || eachDieInfo.tag == TAG_entry_point) | |
364 | { | |
365 | struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit); | |
366 | ||
367 | aFunc->name = eachDieInfo.name; | |
368 | aFunc->low_pc = eachDieInfo.low_pc; | |
369 | aFunc->high_pc = eachDieInfo.high_pc; | |
370 | } | |
371 | ||
372 | /* Move to next sibling, if none, end loop */ | |
373 | if (eachDieInfo.sibling) | |
374 | eachDie = stash->debug_section + eachDieInfo.sibling; | |
375 | else | |
376 | break; | |
377 | } | |
378 | ||
379 | return true; | |
380 | } | |
381 | ||
382 | /* Find the nearest line to 'addr' in 'aUnit'. | |
383 | Return whether we found the line (or a function) without error. */ | |
384 | ||
385 | static boolean | |
386 | dwarf1_unit_find_nearest_line (stash, aUnit, addr, | |
387 | filename_ptr, functionname_ptr, | |
388 | linenumber_ptr) | |
389 | struct dwarf1_debug* stash; | |
390 | struct dwarf1_unit* aUnit; | |
391 | unsigned long addr; | |
392 | const char **filename_ptr; | |
393 | const char **functionname_ptr; | |
394 | unsigned int *linenumber_ptr; | |
395 | { | |
396 | int line_p = false; | |
397 | int func_p = false; | |
398 | ||
399 | if (aUnit->low_pc <= addr && addr < aUnit->high_pc) | |
400 | { | |
401 | if (aUnit->has_stmt_list) | |
402 | { | |
7442e600 | 403 | unsigned long i; |
252b5132 RH |
404 | struct dwarf1_func* eachFunc; |
405 | ||
406 | if (! aUnit->linenumber_table) | |
407 | { | |
408 | if (! parse_line_table (stash, aUnit)) | |
409 | return false; | |
410 | } | |
411 | ||
412 | if (! aUnit->func_list) | |
413 | { | |
414 | if (! parse_functions_in_unit (stash, aUnit)) | |
415 | return false; | |
416 | } | |
417 | ||
418 | for (i = 0; i < aUnit->line_count; i++) | |
419 | { | |
420 | if (aUnit->linenumber_table[i].addr <= addr | |
421 | && addr < aUnit->linenumber_table[i+1].addr) | |
422 | { | |
423 | *filename_ptr = aUnit->name; | |
424 | *linenumber_ptr = aUnit->linenumber_table[i].linenumber; | |
425 | line_p = true; | |
426 | break; | |
427 | } | |
428 | } | |
429 | ||
430 | for (eachFunc = aUnit->func_list; | |
431 | eachFunc; | |
432 | eachFunc = eachFunc->prev) | |
433 | { | |
434 | if (eachFunc->low_pc <= addr | |
435 | && addr < eachFunc->high_pc) | |
436 | { | |
437 | *functionname_ptr = eachFunc->name; | |
438 | func_p = true; | |
439 | break; | |
440 | } | |
441 | } | |
442 | } | |
443 | } | |
444 | ||
445 | return line_p || func_p; | |
446 | } | |
447 | ||
448 | ||
449 | ||
450 | ||
451 | /* The DWARF 1 version of find_nearest line. | |
452 | Return true if the line is found without error. */ | |
453 | ||
454 | boolean | |
455 | _bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, | |
456 | filename_ptr, functionname_ptr, linenumber_ptr) | |
457 | bfd *abfd; | |
458 | asection *section; | |
7442e600 | 459 | asymbol **symbols ATTRIBUTE_UNUSED; |
252b5132 RH |
460 | bfd_vma offset; |
461 | const char **filename_ptr; | |
462 | const char **functionname_ptr; | |
463 | unsigned int *linenumber_ptr; | |
464 | { | |
465 | struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info; | |
466 | ||
467 | struct dwarf1_unit* eachUnit; | |
468 | ||
469 | /* What address are we looking for? */ | |
470 | bfd_vma addr = offset + section->vma; | |
471 | ||
472 | *filename_ptr = NULL; | |
473 | *functionname_ptr = NULL; | |
474 | *linenumber_ptr = 0; | |
475 | ||
476 | ||
477 | if (! stash) | |
478 | { | |
479 | asection *msec; | |
480 | unsigned long size; | |
481 | ||
482 | stash = elf_tdata (abfd)->dwarf1_find_line_info = | |
483 | (struct dwarf1_debug*) bfd_zalloc (abfd, sizeof (struct dwarf1_debug)); | |
484 | ||
485 | if (! stash) | |
486 | return false; | |
487 | ||
488 | msec = bfd_get_section_by_name (abfd, ".debug"); | |
489 | if (! msec) | |
490 | { | |
491 | /* No dwarf1 info. Note that at this point the stash | |
492 | has been allocated, but contains zeros, this lets | |
493 | future calls to this function fail quicker. */ | |
494 | return false; | |
495 | } | |
496 | ||
497 | size = bfd_get_section_size_before_reloc (msec); | |
498 | stash->debug_section = (unsigned char*) bfd_alloc (abfd, size); | |
499 | ||
500 | if (! stash->debug_section) | |
501 | return false; | |
502 | ||
503 | if (! bfd_get_section_contents (abfd, msec, stash->debug_section, 0, size)) | |
504 | { | |
505 | stash->debug_section = 0; | |
506 | return false; | |
507 | } | |
508 | ||
509 | stash->debug_section_end = stash->debug_section + size; | |
510 | stash->currentDie = stash->debug_section; | |
511 | stash->abfd = abfd; | |
512 | } | |
513 | ||
514 | /* A null debug_section indicates that there was no dwarf1 info | |
515 | or that an error occured while setting up the stash. */ | |
516 | ||
517 | if (! stash->debug_section) | |
518 | return false; | |
519 | ||
520 | ||
521 | /* Look at the previously parsed units to see if any contain | |
522 | the addr. */ | |
523 | for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev) | |
524 | { | |
525 | if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc) | |
526 | return dwarf1_unit_find_nearest_line (stash, eachUnit, addr, | |
527 | filename_ptr, | |
528 | functionname_ptr, | |
529 | linenumber_ptr); | |
530 | } | |
531 | ||
532 | while (stash->currentDie < stash->debug_section_end) | |
533 | { | |
534 | struct die_info aDieInfo; | |
535 | ||
536 | if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie)) | |
537 | return false; | |
538 | ||
539 | if (aDieInfo.tag == TAG_compile_unit) | |
540 | { | |
541 | struct dwarf1_unit* aUnit | |
542 | = alloc_dwarf1_unit (stash); | |
543 | ||
544 | aUnit->name = aDieInfo.name; | |
545 | aUnit->low_pc = aDieInfo.low_pc; | |
546 | aUnit->high_pc = aDieInfo.high_pc; | |
547 | aUnit->has_stmt_list = aDieInfo.has_stmt_list; | |
548 | aUnit->stmt_list_offset = aDieInfo.stmt_list_offset; | |
549 | ||
550 | /* A die has a child if it's followed by a die that is | |
551 | not it's sibling. */ | |
552 | if (aDieInfo.sibling | |
553 | && stash->currentDie + aDieInfo.length | |
554 | < stash->debug_section_end | |
555 | && stash->currentDie + aDieInfo.length | |
556 | != stash->debug_section + aDieInfo.sibling) | |
557 | aUnit->first_child = stash->currentDie + aDieInfo.length; | |
558 | else | |
559 | aUnit->first_child = 0; | |
560 | ||
561 | if (aUnit->low_pc <= addr && addr < aUnit->high_pc) | |
562 | return dwarf1_unit_find_nearest_line (stash, aUnit, addr, | |
563 | filename_ptr, | |
564 | functionname_ptr, | |
565 | linenumber_ptr); | |
566 | } | |
567 | ||
568 | if (aDieInfo.sibling != 0) | |
569 | stash->currentDie = stash->debug_section + aDieInfo.sibling; | |
570 | else | |
571 | stash->currentDie += aDieInfo.length; | |
572 | } | |
573 | ||
574 | return false; | |
575 | } | |
576 | ||
577 | ||
578 | /* EOF */ |