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