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