xref: /dragonfly/contrib/gdb-7/bfd/dwarf1.c (revision 86d7f5d3)
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