xref: /titanic_41/usr/src/tools/ctf/dwarf/common/dwarf_macro.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe 
3*07dc1947SRichard Lowe   Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
4*07dc1947SRichard Lowe   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
549d3bc91SRichard Lowe 
649d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
749d3bc91SRichard Lowe   under the terms of version 2.1 of the GNU Lesser General Public License
849d3bc91SRichard Lowe   as published by the Free Software Foundation.
949d3bc91SRichard Lowe 
1049d3bc91SRichard Lowe   This program is distributed in the hope that it would be useful, but
1149d3bc91SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc91SRichard Lowe   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc91SRichard Lowe 
1449d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
1549d3bc91SRichard Lowe   free of the rightful claim of any third person regarding infringement
1649d3bc91SRichard Lowe   or the like.  Any license provided herein, whether implied or
1749d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
1849d3bc91SRichard Lowe   any, provided herein do not apply to combinations of this program with
1949d3bc91SRichard Lowe   other software, or any other product whatsoever.
2049d3bc91SRichard Lowe 
2149d3bc91SRichard Lowe   You should have received a copy of the GNU Lesser General Public
2249d3bc91SRichard Lowe   License along with this program; if not, write the Free Software
23*07dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc91SRichard Lowe   USA.
2549d3bc91SRichard Lowe 
26*07dc1947SRichard Lowe   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2749d3bc91SRichard Lowe   Mountain View, CA 94043, or:
2849d3bc91SRichard Lowe 
2949d3bc91SRichard Lowe   http://www.sgi.com
3049d3bc91SRichard Lowe 
3149d3bc91SRichard Lowe   For further information regarding this notice, see:
3249d3bc91SRichard Lowe 
3349d3bc91SRichard Lowe   http://oss.sgi.com/projects/GenInfo/NoticeExplan
3449d3bc91SRichard Lowe 
3549d3bc91SRichard Lowe */
36*07dc1947SRichard Lowe /* The address of the Free Software Foundation is
37*07dc1947SRichard Lowe    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*07dc1947SRichard Lowe    Boston, MA 02110-1301, USA.
39*07dc1947SRichard Lowe    SGI has moved from the Crittenden Lane address.
40*07dc1947SRichard Lowe */
41*07dc1947SRichard Lowe 
4249d3bc91SRichard Lowe 
4349d3bc91SRichard Lowe 
4449d3bc91SRichard Lowe 
4549d3bc91SRichard Lowe #include "config.h"
4649d3bc91SRichard Lowe #include "dwarf_incl.h"
4749d3bc91SRichard Lowe #include <stdio.h>
4849d3bc91SRichard Lowe #include <limits.h>
49*07dc1947SRichard Lowe #ifdef HAVE_STDLIB_H
50*07dc1947SRichard Lowe #include <stdlib.h>
51*07dc1947SRichard Lowe #endif /* HAVE_STDLIB_H */
5249d3bc91SRichard Lowe #include "dwarf_macro.h"
5349d3bc91SRichard Lowe 
5449d3bc91SRichard Lowe 
5549d3bc91SRichard Lowe #define LEFTPAREN '('
5649d3bc91SRichard Lowe #define RIGHTPAREN ')'
5749d3bc91SRichard Lowe #define SPACE ' '
5849d3bc91SRichard Lowe 
5949d3bc91SRichard Lowe /*
6049d3bc91SRichard Lowe         Given the dwarf macro string, return a pointer to
6149d3bc91SRichard Lowe         the value.  Returns pointer to 0 byte at end of string
6249d3bc91SRichard Lowe         if no value found (meaning the value is the empty string).
6349d3bc91SRichard Lowe 
6449d3bc91SRichard Lowe         Only understands well-formed dwarf macinfo strings.
6549d3bc91SRichard Lowe */
6649d3bc91SRichard Lowe char *
dwarf_find_macro_value_start(char * str)6749d3bc91SRichard Lowe dwarf_find_macro_value_start(char *str)
6849d3bc91SRichard Lowe {
6949d3bc91SRichard Lowe     char *lcp;
7049d3bc91SRichard Lowe     int funclike = 0;
7149d3bc91SRichard Lowe 
7249d3bc91SRichard Lowe     for (lcp = str; *lcp; ++lcp) {
7349d3bc91SRichard Lowe         switch (*lcp) {
7449d3bc91SRichard Lowe         case LEFTPAREN:
7549d3bc91SRichard Lowe             funclike = 1;
7649d3bc91SRichard Lowe             break;
7749d3bc91SRichard Lowe         case RIGHTPAREN:
7849d3bc91SRichard Lowe             /* lcp+1 must be a space, and following char is the value */
7949d3bc91SRichard Lowe             return lcp + 2;
8049d3bc91SRichard Lowe         case SPACE:
8149d3bc91SRichard Lowe             /* we allow extraneous spaces inside macro parameter **
8249d3bc91SRichard Lowe                list, just in case... This is not really needed. */
8349d3bc91SRichard Lowe             if (!funclike) {
8449d3bc91SRichard Lowe                 return lcp + 1;
8549d3bc91SRichard Lowe             }
8649d3bc91SRichard Lowe             break;
8749d3bc91SRichard Lowe         }
8849d3bc91SRichard Lowe     }
8949d3bc91SRichard Lowe     /* never found value: returns pointer to the 0 byte at end of
9049d3bc91SRichard Lowe        string */
9149d3bc91SRichard Lowe     return lcp;
9249d3bc91SRichard Lowe 
9349d3bc91SRichard Lowe }
9449d3bc91SRichard Lowe 
9549d3bc91SRichard Lowe 
9649d3bc91SRichard Lowe /*
9749d3bc91SRichard Lowe    Try to keep fileindex correct in every Macro_Details
9849d3bc91SRichard Lowe    record by tracking file starts and ends.
9949d3bc91SRichard Lowe    Uses high water mark: space reused, not freed.
10049d3bc91SRichard Lowe    Presumption is that this makes sense for most uses.
10149d3bc91SRichard Lowe    STARTERMAX is set so that the array need not be expanded for
10249d3bc91SRichard Lowe    most files: it is the initial include file depth.
10349d3bc91SRichard Lowe */
104*07dc1947SRichard Lowe struct macro_stack_s {
105*07dc1947SRichard Lowe     Dwarf_Signed *st_base;
106*07dc1947SRichard Lowe     long max;
107*07dc1947SRichard Lowe     long next_to_use;
108*07dc1947SRichard Lowe     int was_fault;
109*07dc1947SRichard Lowe };
110*07dc1947SRichard Lowe 
111*07dc1947SRichard Lowe static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms);
112*07dc1947SRichard Lowe static void
free_macro_stack(Dwarf_Debug dbg,struct macro_stack_s * ms)113*07dc1947SRichard Lowe free_macro_stack(Dwarf_Debug dbg, struct macro_stack_s *ms)
114*07dc1947SRichard Lowe {
115*07dc1947SRichard Lowe     dwarf_dealloc(dbg,ms->st_base,DW_DLA_STRING);
116*07dc1947SRichard Lowe     _dwarf_reset_index_macro_stack(ms);
117*07dc1947SRichard Lowe }
11849d3bc91SRichard Lowe 
11949d3bc91SRichard Lowe #define STARTERMAX 10
12049d3bc91SRichard Lowe static void
_dwarf_reset_index_macro_stack(struct macro_stack_s * ms)121*07dc1947SRichard Lowe _dwarf_reset_index_macro_stack(struct macro_stack_s *ms)
12249d3bc91SRichard Lowe {
123*07dc1947SRichard Lowe     ms->st_base = 0;
124*07dc1947SRichard Lowe     ms->max = 0;
125*07dc1947SRichard Lowe     ms->next_to_use = 0;
126*07dc1947SRichard Lowe     ms->was_fault = 0;
12749d3bc91SRichard Lowe }
12849d3bc91SRichard Lowe static int
_dwarf_macro_stack_push_index(Dwarf_Debug dbg,Dwarf_Signed indx,struct macro_stack_s * ms)129*07dc1947SRichard Lowe _dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx,
130*07dc1947SRichard Lowe     struct macro_stack_s *ms)
13149d3bc91SRichard Lowe {
13249d3bc91SRichard Lowe     Dwarf_Signed *newbase;
13349d3bc91SRichard Lowe 
134*07dc1947SRichard Lowe     if (ms->next_to_use >= ms->max) {
13549d3bc91SRichard Lowe         long new_size;
13649d3bc91SRichard Lowe 
137*07dc1947SRichard Lowe         if (ms->max == 0) {
138*07dc1947SRichard Lowe             ms->max = STARTERMAX;
13949d3bc91SRichard Lowe         }
140*07dc1947SRichard Lowe         new_size = ms->max * 2;
14149d3bc91SRichard Lowe         newbase =
14249d3bc91SRichard Lowe             _dwarf_get_alloc(dbg, DW_DLA_STRING,
14349d3bc91SRichard Lowe                              new_size * sizeof(Dwarf_Signed));
14449d3bc91SRichard Lowe         if (newbase == 0) {
14549d3bc91SRichard Lowe             /* just leave the old array in place */
146*07dc1947SRichard Lowe             ms->was_fault = 1;
14749d3bc91SRichard Lowe             return DW_DLV_ERROR;
14849d3bc91SRichard Lowe         }
149*07dc1947SRichard Lowe         if(ms->st_base) {
150*07dc1947SRichard Lowe             memcpy(newbase, ms->st_base,
151*07dc1947SRichard Lowe                ms->next_to_use * sizeof(Dwarf_Signed));
152*07dc1947SRichard Lowe             dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING);
15349d3bc91SRichard Lowe         }
154*07dc1947SRichard Lowe         ms->st_base = newbase;
155*07dc1947SRichard Lowe         ms->max = new_size;
156*07dc1947SRichard Lowe     }
157*07dc1947SRichard Lowe     ms->st_base[ms->next_to_use] = indx;
158*07dc1947SRichard Lowe     ++ms->next_to_use;
15949d3bc91SRichard Lowe     return DW_DLV_OK;
16049d3bc91SRichard Lowe }
161*07dc1947SRichard Lowe 
16249d3bc91SRichard Lowe static Dwarf_Signed
_dwarf_macro_stack_pop_index(struct macro_stack_s * ms)163*07dc1947SRichard Lowe _dwarf_macro_stack_pop_index(struct macro_stack_s *ms)
16449d3bc91SRichard Lowe {
165*07dc1947SRichard Lowe     if (ms->was_fault) {
16649d3bc91SRichard Lowe         return -1;
16749d3bc91SRichard Lowe     }
168*07dc1947SRichard Lowe     if (ms->next_to_use > 0) {
169*07dc1947SRichard Lowe         ms->next_to_use--;
170*07dc1947SRichard Lowe         return (ms->st_base[ms->next_to_use]);
171*07dc1947SRichard Lowe     } else {
172*07dc1947SRichard Lowe         ms->was_fault = 1;
17349d3bc91SRichard Lowe     }
17449d3bc91SRichard Lowe     return -1;
17549d3bc91SRichard Lowe }
17649d3bc91SRichard Lowe 
17749d3bc91SRichard Lowe /* starting at macro_offset in .debug_macinfo,
17849d3bc91SRichard Lowe         if maximum_count is 0, treat as if it is infinite.
17949d3bc91SRichard Lowe         get macro data up thru
18049d3bc91SRichard Lowe         maximum_count entries or the end of a compilation
18149d3bc91SRichard Lowe         unit's entries (whichever comes first).
18249d3bc91SRichard Lowe */
18349d3bc91SRichard Lowe 
18449d3bc91SRichard Lowe 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)18549d3bc91SRichard Lowe dwarf_get_macro_details(Dwarf_Debug dbg,
18649d3bc91SRichard Lowe     Dwarf_Off macro_offset,
18749d3bc91SRichard Lowe     Dwarf_Unsigned maximum_count,
18849d3bc91SRichard Lowe     Dwarf_Signed * entry_count,
18949d3bc91SRichard Lowe     Dwarf_Macro_Details ** details,
19049d3bc91SRichard Lowe     Dwarf_Error * error)
19149d3bc91SRichard Lowe {
192*07dc1947SRichard Lowe     Dwarf_Small *macro_base = 0;
193*07dc1947SRichard Lowe     Dwarf_Small *pnext = 0;
194*07dc1947SRichard Lowe     Dwarf_Unsigned endloc = 0;
195*07dc1947SRichard Lowe     unsigned char uc = 0;
196*07dc1947SRichard Lowe     unsigned long depth = 0;
197*07dc1947SRichard Lowe         /* By section 6.3.2 Dwarf3 draft 8/9,
198*07dc1947SRichard Lowe         the base file should appear as
199*07dc1947SRichard Lowe         DW_MACINFO_start_file. See
200*07dc1947SRichard Lowe         http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg03442.html
201*07dc1947SRichard Lowe         on "[Bug debug/20253] New: [3.4/4.0 regression]:
202*07dc1947SRichard Lowe         Macro debug info broken due to lexer change" for how
203*07dc1947SRichard Lowe         gcc is broken in some versions. We no longer use
204*07dc1947SRichard Lowe         depth as a stopping point, it's not needed as a
205*07dc1947SRichard Lowe         stopping point anyway.  */
206*07dc1947SRichard Lowe     int res = 0;
20749d3bc91SRichard Lowe     /* count space used by strings */
20849d3bc91SRichard Lowe     unsigned long str_space = 0;
20949d3bc91SRichard Lowe     int done = 0;
210*07dc1947SRichard Lowe     unsigned long space_needed = 0;
211*07dc1947SRichard Lowe     unsigned long string_offset = 0;
212*07dc1947SRichard Lowe     Dwarf_Small *return_data = 0;
213*07dc1947SRichard Lowe     Dwarf_Small *pdata = 0;
21449d3bc91SRichard Lowe     unsigned long final_count = 0;
21549d3bc91SRichard Lowe     Dwarf_Signed fileindex = -1;
216*07dc1947SRichard Lowe     Dwarf_Small *latest_str_loc = 0;
217*07dc1947SRichard Lowe     struct macro_stack_s msdata;
21849d3bc91SRichard Lowe 
219*07dc1947SRichard Lowe     unsigned long count = 0;
22049d3bc91SRichard Lowe     unsigned long max_count = (unsigned long) maximum_count;
22149d3bc91SRichard Lowe 
222*07dc1947SRichard Lowe     _dwarf_reset_index_macro_stack(&msdata);
22349d3bc91SRichard Lowe     if (dbg == NULL) {
22449d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
225*07dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
22649d3bc91SRichard Lowe         return (DW_DLV_ERROR);
22749d3bc91SRichard Lowe     }
22849d3bc91SRichard Lowe 
229*07dc1947SRichard Lowe     res = _dwarf_load_section(dbg, &dbg->de_debug_macinfo,error);
23049d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
231*07dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
23249d3bc91SRichard Lowe         return res;
23349d3bc91SRichard Lowe     }
23449d3bc91SRichard Lowe 
235*07dc1947SRichard Lowe     macro_base = dbg->de_debug_macinfo.dss_data;
23649d3bc91SRichard Lowe     if (macro_base == NULL) {
237*07dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
23849d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
23949d3bc91SRichard Lowe     }
240*07dc1947SRichard Lowe     if (macro_offset >= dbg->de_debug_macinfo.dss_size) {
241*07dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
24249d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
24349d3bc91SRichard Lowe     }
24449d3bc91SRichard Lowe 
24549d3bc91SRichard Lowe     pnext = macro_base + macro_offset;
24649d3bc91SRichard Lowe     if (maximum_count == 0) {
24749d3bc91SRichard Lowe         max_count = ULONG_MAX;
24849d3bc91SRichard Lowe     }
24949d3bc91SRichard Lowe 
25049d3bc91SRichard Lowe 
25149d3bc91SRichard Lowe     /* how many entries and how much space will they take? */
25249d3bc91SRichard Lowe 
25349d3bc91SRichard Lowe     endloc = (pnext - macro_base);
254*07dc1947SRichard Lowe     if (endloc >= dbg->de_debug_macinfo.dss_size) {
255*07dc1947SRichard Lowe         if (endloc == dbg->de_debug_macinfo.dss_size) {
25649d3bc91SRichard Lowe             /* normal: found last entry */
257*07dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
25849d3bc91SRichard Lowe             return DW_DLV_NO_ENTRY;
25949d3bc91SRichard Lowe         }
26049d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
261*07dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
26249d3bc91SRichard Lowe         return (DW_DLV_ERROR);
26349d3bc91SRichard Lowe     }
26449d3bc91SRichard Lowe     for (count = 0; !done && count < max_count; ++count) {
26549d3bc91SRichard Lowe         unsigned long slen;
26649d3bc91SRichard Lowe         Dwarf_Word len;
26749d3bc91SRichard Lowe 
26849d3bc91SRichard Lowe         uc = *pnext;
26949d3bc91SRichard Lowe         ++pnext;                /* get past the type code */
27049d3bc91SRichard Lowe         switch (uc) {
27149d3bc91SRichard Lowe         case DW_MACINFO_define:
27249d3bc91SRichard Lowe         case DW_MACINFO_undef:
27349d3bc91SRichard Lowe             /* line, string */
27449d3bc91SRichard Lowe         case DW_MACINFO_vendor_ext:
27549d3bc91SRichard Lowe             /* number, string */
27649d3bc91SRichard Lowe             (void) _dwarf_decode_u_leb128(pnext, &len);
27749d3bc91SRichard Lowe 
27849d3bc91SRichard Lowe             pnext += len;
279*07dc1947SRichard Lowe             if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
280*07dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
28149d3bc91SRichard Lowe                 _dwarf_error(dbg, error,
28249d3bc91SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
28349d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
28449d3bc91SRichard Lowe             }
28549d3bc91SRichard Lowe             slen = strlen((char *) pnext) + 1;
28649d3bc91SRichard Lowe             pnext += slen;
287*07dc1947SRichard Lowe             if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
288*07dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
28949d3bc91SRichard Lowe                 _dwarf_error(dbg, error,
29049d3bc91SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
29149d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
29249d3bc91SRichard Lowe             }
29349d3bc91SRichard Lowe             str_space += slen;
29449d3bc91SRichard Lowe             break;
29549d3bc91SRichard Lowe         case DW_MACINFO_start_file:
29649d3bc91SRichard Lowe             /* line, file index */
29749d3bc91SRichard Lowe             (void) _dwarf_decode_u_leb128(pnext, &len);
29849d3bc91SRichard Lowe             pnext += len;
299*07dc1947SRichard Lowe             if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
300*07dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
30149d3bc91SRichard Lowe                 _dwarf_error(dbg, error,
30249d3bc91SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
30349d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
30449d3bc91SRichard Lowe             }
30549d3bc91SRichard Lowe             (void) _dwarf_decode_u_leb128(pnext, &len);
30649d3bc91SRichard Lowe             pnext += len;
307*07dc1947SRichard Lowe             if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
308*07dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
30949d3bc91SRichard Lowe                 _dwarf_error(dbg, error,
31049d3bc91SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
31149d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
31249d3bc91SRichard Lowe             }
31349d3bc91SRichard Lowe             ++depth;
31449d3bc91SRichard Lowe             break;
31549d3bc91SRichard Lowe 
31649d3bc91SRichard Lowe         case DW_MACINFO_end_file:
31749d3bc91SRichard Lowe             if (--depth == 0) {
318*07dc1947SRichard Lowe                 /* done = 1; no, do not stop here, at least one gcc had
319*07dc1947SRichard Lowe                    the wrong depth settings in the gcc 3.4 timeframe. */
32049d3bc91SRichard Lowe             }
32149d3bc91SRichard Lowe             break;              /* no string or number here */
32249d3bc91SRichard Lowe         case 0:
32349d3bc91SRichard Lowe             /* end of cu's entries */
32449d3bc91SRichard Lowe             done = 1;
32549d3bc91SRichard Lowe             break;
32649d3bc91SRichard Lowe         default:
327*07dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
32849d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
32949d3bc91SRichard Lowe             return (DW_DLV_ERROR);
33049d3bc91SRichard Lowe             /* bogus macinfo! */
33149d3bc91SRichard Lowe         }
33249d3bc91SRichard Lowe 
33349d3bc91SRichard Lowe         endloc = (pnext - macro_base);
334*07dc1947SRichard Lowe         if (endloc == dbg->de_debug_macinfo.dss_size) {
33549d3bc91SRichard Lowe             done = 1;
336*07dc1947SRichard Lowe         } else if (endloc > dbg->de_debug_macinfo.dss_size) {
33749d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
338*07dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
33949d3bc91SRichard Lowe             return (DW_DLV_ERROR);
34049d3bc91SRichard Lowe         }
34149d3bc91SRichard Lowe     }
34249d3bc91SRichard Lowe     if (count == 0) {
343*07dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
34449d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INTERNAL_ERR);
34549d3bc91SRichard Lowe         return (DW_DLV_ERROR);
34649d3bc91SRichard Lowe     }
34749d3bc91SRichard Lowe 
34849d3bc91SRichard Lowe     /* we have 'count' array entries to allocate and str_space bytes of
34949d3bc91SRichard Lowe        string space to provide for. */
35049d3bc91SRichard Lowe 
35149d3bc91SRichard Lowe     string_offset = count * sizeof(Dwarf_Macro_Details);
35249d3bc91SRichard Lowe 
35349d3bc91SRichard Lowe     /* extra 2 not really needed */
35449d3bc91SRichard Lowe     space_needed = string_offset + str_space + 2;
35549d3bc91SRichard Lowe     return_data = pdata =
35649d3bc91SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed);
35749d3bc91SRichard Lowe     latest_str_loc = pdata + string_offset;
35849d3bc91SRichard Lowe     if (pdata == 0) {
359*07dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
36049d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE);
36149d3bc91SRichard Lowe         return (DW_DLV_ERROR);
36249d3bc91SRichard Lowe     }
36349d3bc91SRichard Lowe     pnext = macro_base + macro_offset;
36449d3bc91SRichard Lowe 
36549d3bc91SRichard Lowe     done = 0;
36649d3bc91SRichard Lowe 
367*07dc1947SRichard Lowe     /* A series ends with a type code of 0. */
368*07dc1947SRichard Lowe 
36949d3bc91SRichard Lowe     for (final_count = 0; !done && final_count < count; ++final_count) {
37049d3bc91SRichard Lowe         unsigned long slen;
37149d3bc91SRichard Lowe         Dwarf_Word len;
37249d3bc91SRichard Lowe         Dwarf_Unsigned v1;
37349d3bc91SRichard Lowe         Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata +
374*07dc1947SRichard Lowe             (final_count * sizeof (Dwarf_Macro_Details)));
37549d3bc91SRichard Lowe 
37649d3bc91SRichard Lowe         endloc = (pnext - macro_base);
377*07dc1947SRichard Lowe         if (endloc > dbg->de_debug_macinfo.dss_size) {
378*07dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
37949d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
38049d3bc91SRichard Lowe             return (DW_DLV_ERROR);
38149d3bc91SRichard Lowe         }
38249d3bc91SRichard Lowe         uc = *pnext;
38349d3bc91SRichard Lowe         pdmd->dmd_offset = (pnext - macro_base);
38449d3bc91SRichard Lowe         pdmd->dmd_type = uc;
38549d3bc91SRichard Lowe         pdmd->dmd_fileindex = fileindex;
38649d3bc91SRichard Lowe         pdmd->dmd_lineno = 0;
38749d3bc91SRichard Lowe         pdmd->dmd_macro = 0;
38849d3bc91SRichard Lowe         ++pnext;                /* get past the type code */
38949d3bc91SRichard Lowe         switch (uc) {
39049d3bc91SRichard Lowe         case DW_MACINFO_define:
39149d3bc91SRichard Lowe         case DW_MACINFO_undef:
39249d3bc91SRichard Lowe             /* line, string */
39349d3bc91SRichard Lowe         case DW_MACINFO_vendor_ext:
39449d3bc91SRichard Lowe             /* number, string */
39549d3bc91SRichard Lowe             v1 = _dwarf_decode_u_leb128(pnext, &len);
39649d3bc91SRichard Lowe             pdmd->dmd_lineno = v1;
39749d3bc91SRichard Lowe 
39849d3bc91SRichard Lowe             pnext += len;
399*07dc1947SRichard Lowe             if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
400*07dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
401*07dc1947SRichard Lowe                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
40249d3bc91SRichard Lowe                 _dwarf_error(dbg, error,
40349d3bc91SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
40449d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
40549d3bc91SRichard Lowe             }
40649d3bc91SRichard Lowe             slen = strlen((char *) pnext) + 1;
40749d3bc91SRichard Lowe             strcpy((char *) latest_str_loc, (char *) pnext);
40849d3bc91SRichard Lowe             pdmd->dmd_macro = (char *) latest_str_loc;
40949d3bc91SRichard Lowe             latest_str_loc += slen;
41049d3bc91SRichard Lowe             pnext += slen;
411*07dc1947SRichard Lowe             if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
412*07dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
413*07dc1947SRichard Lowe                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
41449d3bc91SRichard Lowe                 _dwarf_error(dbg, error,
41549d3bc91SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
41649d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
41749d3bc91SRichard Lowe             }
41849d3bc91SRichard Lowe             break;
41949d3bc91SRichard Lowe         case DW_MACINFO_start_file:
420*07dc1947SRichard Lowe             /* Line, file index */
42149d3bc91SRichard Lowe             v1 = _dwarf_decode_u_leb128(pnext, &len);
42249d3bc91SRichard Lowe             pdmd->dmd_lineno = v1;
42349d3bc91SRichard Lowe             pnext += len;
424*07dc1947SRichard Lowe             if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
425*07dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
426*07dc1947SRichard Lowe                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
42749d3bc91SRichard Lowe                 _dwarf_error(dbg, error,
42849d3bc91SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
42949d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
43049d3bc91SRichard Lowe             }
43149d3bc91SRichard Lowe             v1 = _dwarf_decode_u_leb128(pnext, &len);
43249d3bc91SRichard Lowe             pdmd->dmd_fileindex = v1;
433*07dc1947SRichard Lowe             (void) _dwarf_macro_stack_push_index(dbg, fileindex,
434*07dc1947SRichard Lowe                                                  &msdata);
435*07dc1947SRichard Lowe             /* We ignore the error, we just let fileindex ** be -1 when
436*07dc1947SRichard Lowe                we pop this one. */
43749d3bc91SRichard Lowe             fileindex = v1;
43849d3bc91SRichard Lowe             pnext += len;
439*07dc1947SRichard Lowe             if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
440*07dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
441*07dc1947SRichard Lowe                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
44249d3bc91SRichard Lowe                 _dwarf_error(dbg, error,
44349d3bc91SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
44449d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
44549d3bc91SRichard Lowe             }
44649d3bc91SRichard Lowe             break;
44749d3bc91SRichard Lowe 
44849d3bc91SRichard Lowe         case DW_MACINFO_end_file:
449*07dc1947SRichard Lowe             fileindex = _dwarf_macro_stack_pop_index(&msdata);
45049d3bc91SRichard Lowe             break;              /* no string or number here */
45149d3bc91SRichard Lowe         case 0:
452*07dc1947SRichard Lowe             /* Type code of 0 means the end of cu's entries. */
45349d3bc91SRichard Lowe             done = 1;
45449d3bc91SRichard Lowe             break;
45549d3bc91SRichard Lowe         default:
456*07dc1947SRichard Lowe             /* Bogus macinfo! */
457*07dc1947SRichard Lowe             dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
458*07dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
45949d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
46049d3bc91SRichard Lowe             return (DW_DLV_ERROR);
46149d3bc91SRichard Lowe         }
46249d3bc91SRichard Lowe     }
46349d3bc91SRichard Lowe     *entry_count = count;
46449d3bc91SRichard Lowe     *details = (Dwarf_Macro_Details *) return_data;
465*07dc1947SRichard Lowe     free_macro_stack(dbg,&msdata);
46649d3bc91SRichard Lowe     return DW_DLV_OK;
46749d3bc91SRichard Lowe }
468