1 /*
2
3 Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of version 2.1 of the GNU Lesser General Public License
8 as published by the Free Software Foundation.
9
10 This program is distributed in the hope that it would be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 Further, this software is distributed without any warranty that it is
15 free of the rightful claim of any third person regarding infringement
16 or the like. Any license provided herein, whether implied or
17 otherwise, applies only to this software file. Patent licenses, if
18 any, provided herein do not apply to combinations of this program with
19 other software, or any other product whatsoever.
20
21 You should have received a copy of the GNU Lesser General Public
22 License along with this program; if not, write the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24 USA.
25
26 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27 Mountain View, CA 94043, or:
28
29 http://www.sgi.com
30
31 For further information regarding this notice, see:
32
33 http://oss.sgi.com/projects/GenInfo/NoticeExplan
34
35 */
36 /* The address of the Free Software Foundation is
37 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38 Boston, MA 02110-1301, USA.
39 SGI has moved from the Crittenden Lane address.
40 */
41
42
43
44
45 #include "config.h"
46 #include "dwarf_incl.h"
47 #include <stdio.h>
48 #include <limits.h>
49 #ifdef HAVE_STDLIB_H
50 #include <stdlib.h>
51 #endif /* HAVE_STDLIB_H */
52 #include "dwarf_macro.h"
53
54
55 #define LEFTPAREN '('
56 #define RIGHTPAREN ')'
57 #define SPACE ' '
58
59 /*
60 Given the dwarf macro string, return a pointer to
61 the value. Returns pointer to 0 byte at end of string
62 if no value found (meaning the value is the empty string).
63
64 Only understands well-formed dwarf macinfo strings.
65 */
66 char *
dwarf_find_macro_value_start(char * str)67 dwarf_find_macro_value_start(char *str)
68 {
69 char *lcp;
70 int funclike = 0;
71
72 for (lcp = str; *lcp; ++lcp) {
73 switch (*lcp) {
74 case LEFTPAREN:
75 funclike = 1;
76 break;
77 case RIGHTPAREN:
78 /* lcp+1 must be a space, and following char is the value */
79 return lcp + 2;
80 case SPACE:
81 /* we allow extraneous spaces inside macro parameter **
82 list, just in case... This is not really needed. */
83 if (!funclike) {
84 return lcp + 1;
85 }
86 break;
87 }
88 }
89 /* never found value: returns pointer to the 0 byte at end of
90 string */
91 return lcp;
92
93 }
94
95
96 /*
97 Try to keep fileindex correct in every Macro_Details
98 record by tracking file starts and ends.
99 Uses high water mark: space reused, not freed.
100 Presumption is that this makes sense for most uses.
101 STARTERMAX is set so that the array need not be expanded for
102 most files: it is the initial include file depth.
103 */
104 struct macro_stack_s {
105 Dwarf_Signed *st_base;
106 long max;
107 long next_to_use;
108 int was_fault;
109 };
110
111 static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms);
112 static void
free_macro_stack(Dwarf_Debug dbg,struct macro_stack_s * ms)113 free_macro_stack(Dwarf_Debug dbg, struct macro_stack_s *ms)
114 {
115 dwarf_dealloc(dbg,ms->st_base,DW_DLA_STRING);
116 _dwarf_reset_index_macro_stack(ms);
117 }
118
119 #define STARTERMAX 10
120 static void
_dwarf_reset_index_macro_stack(struct macro_stack_s * ms)121 _dwarf_reset_index_macro_stack(struct macro_stack_s *ms)
122 {
123 ms->st_base = 0;
124 ms->max = 0;
125 ms->next_to_use = 0;
126 ms->was_fault = 0;
127 }
128 static int
_dwarf_macro_stack_push_index(Dwarf_Debug dbg,Dwarf_Signed indx,struct macro_stack_s * ms)129 _dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx,
130 struct macro_stack_s *ms)
131 {
132 Dwarf_Signed *newbase;
133
134 if (ms->next_to_use >= ms->max) {
135 long new_size;
136
137 if (ms->max == 0) {
138 ms->max = STARTERMAX;
139 }
140 new_size = ms->max * 2;
141 newbase =
142 _dwarf_get_alloc(dbg, DW_DLA_STRING,
143 new_size * sizeof(Dwarf_Signed));
144 if (newbase == 0) {
145 /* just leave the old array in place */
146 ms->was_fault = 1;
147 return DW_DLV_ERROR;
148 }
149 if(ms->st_base) {
150 memcpy(newbase, ms->st_base,
151 ms->next_to_use * sizeof(Dwarf_Signed));
152 dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING);
153 }
154 ms->st_base = newbase;
155 ms->max = new_size;
156 }
157 ms->st_base[ms->next_to_use] = indx;
158 ++ms->next_to_use;
159 return DW_DLV_OK;
160 }
161
162 static Dwarf_Signed
_dwarf_macro_stack_pop_index(struct macro_stack_s * ms)163 _dwarf_macro_stack_pop_index(struct macro_stack_s *ms)
164 {
165 if (ms->was_fault) {
166 return -1;
167 }
168 if (ms->next_to_use > 0) {
169 ms->next_to_use--;
170 return (ms->st_base[ms->next_to_use]);
171 } else {
172 ms->was_fault = 1;
173 }
174 return -1;
175 }
176
177 /* starting at macro_offset in .debug_macinfo,
178 if maximum_count is 0, treat as if it is infinite.
179 get macro data up thru
180 maximum_count entries or the end of a compilation
181 unit's entries (whichever comes first).
182 */
183
184 int
dwarf_get_macro_details(Dwarf_Debug dbg,Dwarf_Off macro_offset,Dwarf_Unsigned maximum_count,Dwarf_Signed * entry_count,Dwarf_Macro_Details ** details,Dwarf_Error * error)185 dwarf_get_macro_details(Dwarf_Debug dbg,
186 Dwarf_Off macro_offset,
187 Dwarf_Unsigned maximum_count,
188 Dwarf_Signed * entry_count,
189 Dwarf_Macro_Details ** details,
190 Dwarf_Error * error)
191 {
192 Dwarf_Small *macro_base = 0;
193 Dwarf_Small *pnext = 0;
194 Dwarf_Unsigned endloc = 0;
195 unsigned char uc = 0;
196 unsigned long depth = 0;
197 /* By section 6.3.2 Dwarf3 draft 8/9,
198 the base file should appear as
199 DW_MACINFO_start_file. See
200 http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg03442.html
201 on "[Bug debug/20253] New: [3.4/4.0 regression]:
202 Macro debug info broken due to lexer change" for how
203 gcc is broken in some versions. We no longer use
204 depth as a stopping point, it's not needed as a
205 stopping point anyway. */
206 int res = 0;
207 /* count space used by strings */
208 unsigned long str_space = 0;
209 int done = 0;
210 unsigned long space_needed = 0;
211 unsigned long string_offset = 0;
212 Dwarf_Small *return_data = 0;
213 Dwarf_Small *pdata = 0;
214 unsigned long final_count = 0;
215 Dwarf_Signed fileindex = -1;
216 Dwarf_Small *latest_str_loc = 0;
217 struct macro_stack_s msdata;
218
219 unsigned long count = 0;
220 unsigned long max_count = (unsigned long) maximum_count;
221
222 _dwarf_reset_index_macro_stack(&msdata);
223 if (dbg == NULL) {
224 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
225 free_macro_stack(dbg,&msdata);
226 return (DW_DLV_ERROR);
227 }
228
229 res = _dwarf_load_section(dbg, &dbg->de_debug_macinfo,error);
230 if (res != DW_DLV_OK) {
231 free_macro_stack(dbg,&msdata);
232 return res;
233 }
234
235 macro_base = dbg->de_debug_macinfo.dss_data;
236 if (macro_base == NULL) {
237 free_macro_stack(dbg,&msdata);
238 return (DW_DLV_NO_ENTRY);
239 }
240 if (macro_offset >= dbg->de_debug_macinfo.dss_size) {
241 free_macro_stack(dbg,&msdata);
242 return (DW_DLV_NO_ENTRY);
243 }
244
245 pnext = macro_base + macro_offset;
246 if (maximum_count == 0) {
247 max_count = ULONG_MAX;
248 }
249
250
251 /* how many entries and how much space will they take? */
252
253 endloc = (pnext - macro_base);
254 if (endloc >= dbg->de_debug_macinfo.dss_size) {
255 if (endloc == dbg->de_debug_macinfo.dss_size) {
256 /* normal: found last entry */
257 free_macro_stack(dbg,&msdata);
258 return DW_DLV_NO_ENTRY;
259 }
260 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
261 free_macro_stack(dbg,&msdata);
262 return (DW_DLV_ERROR);
263 }
264 for (count = 0; !done && count < max_count; ++count) {
265 unsigned long slen;
266 Dwarf_Word len;
267
268 uc = *pnext;
269 ++pnext; /* get past the type code */
270 switch (uc) {
271 case DW_MACINFO_define:
272 case DW_MACINFO_undef:
273 /* line, string */
274 case DW_MACINFO_vendor_ext:
275 /* number, string */
276 (void) _dwarf_decode_u_leb128(pnext, &len);
277
278 pnext += len;
279 if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
280 free_macro_stack(dbg,&msdata);
281 _dwarf_error(dbg, error,
282 DW_DLE_DEBUG_MACRO_INCONSISTENT);
283 return (DW_DLV_ERROR);
284 }
285 slen = strlen((char *) pnext) + 1;
286 pnext += slen;
287 if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
288 free_macro_stack(dbg,&msdata);
289 _dwarf_error(dbg, error,
290 DW_DLE_DEBUG_MACRO_INCONSISTENT);
291 return (DW_DLV_ERROR);
292 }
293 str_space += slen;
294 break;
295 case DW_MACINFO_start_file:
296 /* line, file index */
297 (void) _dwarf_decode_u_leb128(pnext, &len);
298 pnext += len;
299 if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
300 free_macro_stack(dbg,&msdata);
301 _dwarf_error(dbg, error,
302 DW_DLE_DEBUG_MACRO_INCONSISTENT);
303 return (DW_DLV_ERROR);
304 }
305 (void) _dwarf_decode_u_leb128(pnext, &len);
306 pnext += len;
307 if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
308 free_macro_stack(dbg,&msdata);
309 _dwarf_error(dbg, error,
310 DW_DLE_DEBUG_MACRO_INCONSISTENT);
311 return (DW_DLV_ERROR);
312 }
313 ++depth;
314 break;
315
316 case DW_MACINFO_end_file:
317 if (--depth == 0) {
318 /* done = 1; no, do not stop here, at least one gcc had
319 the wrong depth settings in the gcc 3.4 timeframe. */
320 }
321 break; /* no string or number here */
322 case 0:
323 /* end of cu's entries */
324 done = 1;
325 break;
326 default:
327 free_macro_stack(dbg,&msdata);
328 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
329 return (DW_DLV_ERROR);
330 /* bogus macinfo! */
331 }
332
333 endloc = (pnext - macro_base);
334 if (endloc == dbg->de_debug_macinfo.dss_size) {
335 done = 1;
336 } else if (endloc > dbg->de_debug_macinfo.dss_size) {
337 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
338 free_macro_stack(dbg,&msdata);
339 return (DW_DLV_ERROR);
340 }
341 }
342 if (count == 0) {
343 free_macro_stack(dbg,&msdata);
344 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INTERNAL_ERR);
345 return (DW_DLV_ERROR);
346 }
347
348 /* we have 'count' array entries to allocate and str_space bytes of
349 string space to provide for. */
350
351 string_offset = count * sizeof(Dwarf_Macro_Details);
352
353 /* extra 2 not really needed */
354 space_needed = string_offset + str_space + 2;
355 return_data = pdata =
356 _dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed);
357 latest_str_loc = pdata + string_offset;
358 if (pdata == 0) {
359 free_macro_stack(dbg,&msdata);
360 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE);
361 return (DW_DLV_ERROR);
362 }
363 pnext = macro_base + macro_offset;
364
365 done = 0;
366
367 /* A series ends with a type code of 0. */
368
369 for (final_count = 0; !done && final_count < count; ++final_count) {
370 unsigned long slen;
371 Dwarf_Word len;
372 Dwarf_Unsigned v1;
373 Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata +
374 (final_count * sizeof (Dwarf_Macro_Details)));
375
376 endloc = (pnext - macro_base);
377 if (endloc > dbg->de_debug_macinfo.dss_size) {
378 free_macro_stack(dbg,&msdata);
379 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
380 return (DW_DLV_ERROR);
381 }
382 uc = *pnext;
383 pdmd->dmd_offset = (pnext - macro_base);
384 pdmd->dmd_type = uc;
385 pdmd->dmd_fileindex = fileindex;
386 pdmd->dmd_lineno = 0;
387 pdmd->dmd_macro = 0;
388 ++pnext; /* get past the type code */
389 switch (uc) {
390 case DW_MACINFO_define:
391 case DW_MACINFO_undef:
392 /* line, string */
393 case DW_MACINFO_vendor_ext:
394 /* number, string */
395 v1 = _dwarf_decode_u_leb128(pnext, &len);
396 pdmd->dmd_lineno = v1;
397
398 pnext += len;
399 if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
400 free_macro_stack(dbg,&msdata);
401 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
402 _dwarf_error(dbg, error,
403 DW_DLE_DEBUG_MACRO_INCONSISTENT);
404 return (DW_DLV_ERROR);
405 }
406 slen = strlen((char *) pnext) + 1;
407 strcpy((char *) latest_str_loc, (char *) pnext);
408 pdmd->dmd_macro = (char *) latest_str_loc;
409 latest_str_loc += slen;
410 pnext += slen;
411 if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
412 free_macro_stack(dbg,&msdata);
413 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
414 _dwarf_error(dbg, error,
415 DW_DLE_DEBUG_MACRO_INCONSISTENT);
416 return (DW_DLV_ERROR);
417 }
418 break;
419 case DW_MACINFO_start_file:
420 /* Line, file index */
421 v1 = _dwarf_decode_u_leb128(pnext, &len);
422 pdmd->dmd_lineno = v1;
423 pnext += len;
424 if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
425 free_macro_stack(dbg,&msdata);
426 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
427 _dwarf_error(dbg, error,
428 DW_DLE_DEBUG_MACRO_INCONSISTENT);
429 return (DW_DLV_ERROR);
430 }
431 v1 = _dwarf_decode_u_leb128(pnext, &len);
432 pdmd->dmd_fileindex = v1;
433 (void) _dwarf_macro_stack_push_index(dbg, fileindex,
434 &msdata);
435 /* We ignore the error, we just let fileindex ** be -1 when
436 we pop this one. */
437 fileindex = v1;
438 pnext += len;
439 if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
440 free_macro_stack(dbg,&msdata);
441 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
442 _dwarf_error(dbg, error,
443 DW_DLE_DEBUG_MACRO_INCONSISTENT);
444 return (DW_DLV_ERROR);
445 }
446 break;
447
448 case DW_MACINFO_end_file:
449 fileindex = _dwarf_macro_stack_pop_index(&msdata);
450 break; /* no string or number here */
451 case 0:
452 /* Type code of 0 means the end of cu's entries. */
453 done = 1;
454 break;
455 default:
456 /* Bogus macinfo! */
457 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
458 free_macro_stack(dbg,&msdata);
459 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
460 return (DW_DLV_ERROR);
461 }
462 }
463 *entry_count = count;
464 *details = (Dwarf_Macro_Details *) return_data;
465 free_macro_stack(dbg,&msdata);
466 return DW_DLV_OK;
467 }
468