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