source: trunk/src/binutils/bfd/dwarf1.c@ 947

Last change on this file since 947 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 15.2 KB
Line 
1/* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line).
2 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4Written by Gavin Romig-Koch of Cygnus Solutions ([email protected]).
5
6This file is part of BFD.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or (at
11your option) any later version.
12
13This program is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, 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
31struct 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
58struct 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/* One dwarf1_func for each parsed function die. */
89
90struct dwarf1_func {
91 /* Linked starting from aUnit->func_list. */
92 struct dwarf1_func* prev;
93
94 /* Name of function. */
95 char* name;
96
97 /* The highest and lowest address used in the compilation unit. */
98 unsigned long low_pc;
99 unsigned long high_pc;
100};
101
102/* Used to return info about a parsed die. */
103struct die_info {
104 unsigned long length;
105 unsigned long sibling;
106 unsigned long low_pc;
107 unsigned long high_pc;
108 unsigned long stmt_list_offset;
109
110 char* name;
111
112 int has_stmt_list;
113
114 unsigned short tag;
115};
116
117/* Parsed line number information. */
118struct linenumber {
119 /* First address in the line. */
120 unsigned long addr;
121
122 /* The line number. */
123 unsigned long linenumber;
124};
125
126/* Find the form of an attr, from the attr field. */
127#define FORM_FROM_ATTR(attr) ((attr) & 0xF) /* Implicitly specified */
128
129static struct dwarf1_unit *alloc_dwarf1_unit
130 PARAMS ((struct dwarf1_debug *));
131static struct dwarf1_func *alloc_dwarf1_func
132 PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *));
133static bfd_boolean parse_die
134 PARAMS ((bfd *, struct die_info *, char *, char *));
135static bfd_boolean parse_line_table
136 PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *));
137static bfd_boolean parse_functions_in_unit
138 PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *));
139static bfd_boolean dwarf1_unit_find_nearest_line
140 PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *, unsigned long,
141 const char **, const char **, unsigned int *));
142
143/* Return a newly allocated dwarf1_unit. It should be cleared and
144 then attached into the 'stash' at 'stash->lastUnit'. */
145
146static struct dwarf1_unit*
147alloc_dwarf1_unit (stash)
148 struct dwarf1_debug* stash;
149{
150 bfd_size_type amt = sizeof (struct dwarf1_unit);
151
152 struct dwarf1_unit* x = (struct dwarf1_unit*) bfd_zalloc (stash->abfd, amt);
153 x->prev = stash->lastUnit;
154 stash->lastUnit = x;
155
156 return x;
157}
158
159/* Return a newly allocated dwarf1_func. It must be cleared and
160 attached into 'aUnit' at 'aUnit->func_list'. */
161
162static struct dwarf1_func*
163alloc_dwarf1_func (stash, aUnit)
164 struct dwarf1_debug* stash;
165 struct dwarf1_unit* aUnit;
166{
167 bfd_size_type amt = sizeof (struct dwarf1_func);
168
169 struct dwarf1_func* x = (struct dwarf1_func*) bfd_zalloc (stash->abfd, amt);
170 x->prev = aUnit->func_list;
171 aUnit->func_list = x;
172
173 return x;
174}
175
176/* parse_die - parse a Dwarf1 die.
177 Parse the die starting at 'aDiePtr' into 'aDieInfo'.
178 'abfd' must be the bfd from which the section that 'aDiePtr'
179 points to was pulled from.
180
181 Return FALSE if the die is invalidly formatted; TRUE otherwise. */
182
183static bfd_boolean
184parse_die (abfd, aDieInfo, aDiePtr, aDiePtrEnd)
185 bfd* abfd;
186 struct die_info* aDieInfo;
187 char* aDiePtr;
188 char* aDiePtrEnd;
189{
190 char* this_die = aDiePtr;
191 char* xptr = this_die;
192
193 memset (aDieInfo,0,sizeof (*aDieInfo));
194
195 /* First comes the length. */
196 aDieInfo->length = bfd_get_32 (abfd, (bfd_byte *) xptr);
197 xptr += 4;
198 if (aDieInfo->length == 0
199 || (this_die + aDieInfo->length) >= aDiePtrEnd)
200 return FALSE;
201 if (aDieInfo->length < 6)
202 {
203 /* Just padding bytes. */
204 aDieInfo->tag = TAG_padding;
205 return TRUE;
206 }
207
208 /* Then the tag. */
209 aDieInfo->tag = bfd_get_16 (abfd, (bfd_byte *) xptr);
210 xptr += 2;
211
212 /* Then the attributes. */
213 while (xptr < (this_die + aDieInfo->length))
214 {
215 unsigned short attr;
216
217 /* Parse the attribute based on its form. This section
218 must handle all dwarf1 forms, but need only handle the
219 actual attributes that we care about. */
220
221 attr = bfd_get_16 (abfd, (bfd_byte *) xptr);
222 xptr += 2;
223
224 switch (FORM_FROM_ATTR (attr))
225 {
226 case FORM_DATA2:
227 xptr += 2;
228 break;
229 case FORM_DATA4:
230 case FORM_REF:
231 if (attr == AT_sibling)
232 aDieInfo->sibling = bfd_get_32 (abfd, (bfd_byte *) xptr);
233 else if (attr == AT_stmt_list)
234 {
235 aDieInfo->stmt_list_offset = bfd_get_32 (abfd, (bfd_byte *) xptr);
236 aDieInfo->has_stmt_list = 1;
237 }
238 xptr += 4;
239 break;
240 case FORM_DATA8:
241 xptr += 8;
242 break;
243 case FORM_ADDR:
244 if (attr == AT_low_pc)
245 aDieInfo->low_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
246 else if (attr == AT_high_pc)
247 aDieInfo->high_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
248 xptr += 4;
249 break;
250 case FORM_BLOCK2:
251 xptr += 2 + bfd_get_16 (abfd, (bfd_byte *) xptr);
252 break;
253 case FORM_BLOCK4:
254 xptr += 4 + bfd_get_32 (abfd, (bfd_byte *) xptr);
255 break;
256 case FORM_STRING:
257 if (attr == AT_name)
258 aDieInfo->name = xptr;
259 xptr += strlen (xptr) + 1;
260 break;
261 }
262 }
263
264 return TRUE;
265}
266
267/* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset'
268 into 'aUnit->linenumber_table'. Return FALSE if an error
269 occurs; TRUE otherwise. */
270
271static bfd_boolean
272parse_line_table (stash, aUnit)
273 struct dwarf1_debug* stash;
274 struct dwarf1_unit* aUnit;