149d3bc91SRichard Lowe /*
207dc1947SRichard Lowe   Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
3*4d9fdb46SRobert Mustacchi   Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved.
4*4d9fdb46SRobert Mustacchi   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
549d3bc91SRichard Lowe 
649d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
7*4d9fdb46SRobert Mustacchi   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
12*4d9fdb46SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc91SRichard Lowe 
1449d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
15*4d9fdb46SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16*4d9fdb46SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
1749d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
18*4d9fdb46SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19*4d9fdb46SRobert Mustacchi   other software, or any other product whatsoever.
2049d3bc91SRichard Lowe 
21*4d9fdb46SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22*4d9fdb46SRobert Mustacchi   License along with this program; if not, write the Free Software
2307dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc91SRichard Lowe   USA.
2549d3bc91SRichard Lowe 
2607dc1947SRichard Lowe */
2707dc1947SRichard Lowe 
2849d3bc91SRichard Lowe #include "config.h"
2949d3bc91SRichard Lowe #include <stdio.h>
3049d3bc91SRichard Lowe #include <limits.h>
3107dc1947SRichard Lowe #ifdef HAVE_STDLIB_H
3207dc1947SRichard Lowe #include <stdlib.h>
3307dc1947SRichard Lowe #endif /* HAVE_STDLIB_H */
34*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
35*4d9fdb46SRobert Mustacchi #include "dwarf_alloc.h"
36*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
37*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
3849d3bc91SRichard Lowe #include "dwarf_macro.h"
3949d3bc91SRichard Lowe 
4049d3bc91SRichard Lowe 
4149d3bc91SRichard Lowe #define LEFTPAREN '('
4249d3bc91SRichard Lowe #define RIGHTPAREN ')'
4349d3bc91SRichard Lowe #define SPACE ' '
4449d3bc91SRichard Lowe 
45*4d9fdb46SRobert Mustacchi /*  Given the dwarf macro string, return a pointer to
46*4d9fdb46SRobert Mustacchi     the value.  Returns pointer to 0 byte at end of string
47*4d9fdb46SRobert Mustacchi     if no value found (meaning the value is the empty string).
4849d3bc91SRichard Lowe 
49*4d9fdb46SRobert Mustacchi     Only understands well-formed dwarf macinfo strings.
5049d3bc91SRichard Lowe */
5149d3bc91SRichard Lowe char *
dwarf_find_macro_value_start(char * str)5249d3bc91SRichard Lowe dwarf_find_macro_value_start(char *str)
5349d3bc91SRichard Lowe {
5449d3bc91SRichard Lowe     char *lcp;
5549d3bc91SRichard Lowe     int funclike = 0;
5649d3bc91SRichard Lowe 
5749d3bc91SRichard Lowe     for (lcp = str; *lcp; ++lcp) {
5807dc1947SRichard Lowe         switch (*lcp) {
5907dc1947SRichard Lowe         case LEFTPAREN:
6007dc1947SRichard Lowe             funclike = 1;
6107dc1947SRichard Lowe             break;
6207dc1947SRichard Lowe         case RIGHTPAREN:
6307dc1947SRichard Lowe             /* lcp+1 must be a space, and following char is the value */
6407dc1947SRichard Lowe             return lcp + 2;
6507dc1947SRichard Lowe         case SPACE:
66*4d9fdb46SRobert Mustacchi             /*  We allow extraneous spaces inside macro parameter **
67*4d9fdb46SRobert Mustacchi                 list, just in case... This is not really needed. */
6807dc1947SRichard Lowe             if (!funclike) {
6907dc1947SRichard Lowe                 return lcp + 1;
7007dc1947SRichard Lowe             }
7107dc1947SRichard Lowe             break;
7207dc1947SRichard Lowe         }
7349d3bc91SRichard Lowe     }
74*4d9fdb46SRobert Mustacchi     /*  Never found value: returns pointer to the 0 byte at end of
75*4d9fdb46SRobert Mustacchi         string. */
7649d3bc91SRichard Lowe     return lcp;
7749d3bc91SRichard Lowe 
7849d3bc91SRichard Lowe }
7949d3bc91SRichard Lowe 
8049d3bc91SRichard Lowe 
8149d3bc91SRichard Lowe /*
8249d3bc91SRichard Lowe    Try to keep fileindex correct in every Macro_Details
8349d3bc91SRichard Lowe    record by tracking file starts and ends.
8449d3bc91SRichard Lowe    Uses high water mark: space reused, not freed.
8549d3bc91SRichard Lowe    Presumption is that this makes sense for most uses.
8649d3bc91SRichard Lowe    STARTERMAX is set so that the array need not be expanded for
8749d3bc91SRichard Lowe    most files: it is the initial include file depth.
8849d3bc91SRichard Lowe */
8907dc1947SRichard Lowe struct macro_stack_s {
9007dc1947SRichard Lowe     Dwarf_Signed *st_base;
91*4d9fdb46SRobert Mustacchi     long st_max;
92*4d9fdb46SRobert Mustacchi     long st_next_to_use;
93*4d9fdb46SRobert Mustacchi     int  st_was_fault;
9407dc1947SRichard Lowe };
9507dc1947SRichard Lowe 
9607dc1947SRichard Lowe static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms);
9707dc1947SRichard Lowe static void
free_macro_stack(Dwarf_Debug dbg,struct macro_stack_s * ms)9807dc1947SRichard Lowe free_macro_stack(Dwarf_Debug dbg, struct macro_stack_s *ms)
9907dc1947SRichard Lowe {
10007dc1947SRichard Lowe     dwarf_dealloc(dbg,ms->st_base,DW_DLA_STRING);
10107dc1947SRichard Lowe     _dwarf_reset_index_macro_stack(ms);
10207dc1947SRichard Lowe }
10349d3bc91SRichard Lowe 
10449d3bc91SRichard Lowe #define STARTERMAX 10
10549d3bc91SRichard Lowe static void
_dwarf_reset_index_macro_stack(struct macro_stack_s * ms)10607dc1947SRichard Lowe _dwarf_reset_index_macro_stack(struct macro_stack_s *ms)
10749d3bc91SRichard Lowe {
10807dc1947SRichard Lowe     ms->st_base = 0;
109*4d9fdb46SRobert Mustacchi     ms->st_max = 0;
110*4d9fdb46SRobert Mustacchi     ms->st_next_to_use = 0;
111*4d9fdb46SRobert Mustacchi     ms->st_was_fault = 0;
11249d3bc91SRichard Lowe }
11349d3bc91SRichard Lowe static int
_dwarf_macro_stack_push_index(Dwarf_Debug dbg,Dwarf_Signed indx,struct macro_stack_s * ms)11407dc1947SRichard Lowe _dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx,
11507dc1947SRichard Lowe     struct macro_stack_s *ms)
11649d3bc91SRichard Lowe {
11749d3bc91SRichard Lowe 
118*4d9fdb46SRobert Mustacchi     if (!ms->st_max || ms->st_next_to_use >= ms->st_max) {
119*4d9fdb46SRobert Mustacchi         long new_size = ms->st_max;
120*4d9fdb46SRobert Mustacchi         Dwarf_Signed *newbase = 0;
12107dc1947SRichard Lowe 
122*4d9fdb46SRobert Mustacchi         if (!new_size) {
123*4d9fdb46SRobert Mustacchi             new_size = STARTERMAX;
12407dc1947SRichard Lowe         }
125*4d9fdb46SRobert Mustacchi         new_size = new_size * 2;
12607dc1947SRichard Lowe         newbase =
127*4d9fdb46SRobert Mustacchi             (Dwarf_Signed *)_dwarf_get_alloc(dbg, DW_DLA_STRING,
128*4d9fdb46SRobert Mustacchi                 new_size * sizeof(Dwarf_Signed));
129*4d9fdb46SRobert Mustacchi         if (!newbase) {
13007dc1947SRichard Lowe             /* just leave the old array in place */
131*4d9fdb46SRobert Mustacchi             ms->st_was_fault = 1;
13207dc1947SRichard Lowe             return DW_DLV_ERROR;
13307dc1947SRichard Lowe         }
134*4d9fdb46SRobert Mustacchi         if (ms->st_base) {
13507dc1947SRichard Lowe             memcpy(newbase, ms->st_base,
136*4d9fdb46SRobert Mustacchi                 ms->st_next_to_use * sizeof(Dwarf_Signed));
13707dc1947SRichard Lowe             dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING);
13807dc1947SRichard Lowe         }
13907dc1947SRichard Lowe         ms->st_base = newbase;
140*4d9fdb46SRobert Mustacchi         ms->st_max = new_size;
14149d3bc91SRichard Lowe     }
142*4d9fdb46SRobert Mustacchi     ms->st_base[ms->st_next_to_use] = indx;
143*4d9fdb46SRobert Mustacchi     ++ms->st_next_to_use;
14449d3bc91SRichard Lowe     return DW_DLV_OK;
14549d3bc91SRichard Lowe }
14607dc1947SRichard Lowe 
14749d3bc91SRichard Lowe static Dwarf_Signed
_dwarf_macro_stack_pop_index(struct macro_stack_s * ms)14807dc1947SRichard Lowe _dwarf_macro_stack_pop_index(struct macro_stack_s *ms)
14949d3bc91SRichard Lowe {
150*4d9fdb46SRobert Mustacchi     if (ms->st_was_fault) {
15107dc1947SRichard Lowe         return -1;
15249d3bc91SRichard Lowe     }
153*4d9fdb46SRobert Mustacchi     if (ms->st_next_to_use > 0) {
154*4d9fdb46SRobert Mustacchi         ms->st_next_to_use--;
155*4d9fdb46SRobert Mustacchi         return (ms->st_base[ms->st_next_to_use]);
15607dc1947SRichard Lowe     } else {
157*4d9fdb46SRobert Mustacchi         ms->st_was_fault = 1;
15849d3bc91SRichard Lowe     }
15949d3bc91SRichard Lowe     return -1;
16049d3bc91SRichard Lowe }
16149d3bc91SRichard Lowe 
162*4d9fdb46SRobert Mustacchi /*  Starting at macro_offset in .debug_macinfo,
163*4d9fdb46SRobert Mustacchi     if maximum_count is 0, treat as if it is infinite.
164*4d9fdb46SRobert Mustacchi     get macro data up thru
165*4d9fdb46SRobert Mustacchi     maximum_count entries or the end of a compilation
166*4d9fdb46SRobert Mustacchi     unit's entries (whichever comes first).
167*4d9fdb46SRobert Mustacchi 
168*4d9fdb46SRobert Mustacchi     .debug_macinfo never appears in a .dwp Package File.
169*4d9fdb46SRobert Mustacchi     So offset adjustment for such is not needed.
17049d3bc91SRichard Lowe */
17149d3bc91SRichard Lowe 
17249d3bc91SRichard 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)17349d3bc91SRichard Lowe dwarf_get_macro_details(Dwarf_Debug dbg,
17407dc1947SRichard Lowe     Dwarf_Off macro_offset,
17507dc1947SRichard Lowe     Dwarf_Unsigned maximum_count,
17607dc1947SRichard Lowe     Dwarf_Signed * entry_count,
17707dc1947SRichard Lowe     Dwarf_Macro_Details ** details,
17807dc1947SRichard Lowe     Dwarf_Error * error)
17949d3bc91SRichard Lowe {
18007dc1947SRichard Lowe     Dwarf_Small *macro_base = 0;
181*4d9fdb46SRobert Mustacchi     Dwarf_Small *macro_end = 0;
18207dc1947SRichard Lowe     Dwarf_Small *pnext = 0;
18307dc1947SRichard Lowe     Dwarf_Unsigned endloc = 0;
18407dc1947SRichard Lowe     unsigned char uc = 0;
185*4d9fdb46SRobert Mustacchi     unsigned long depth = 0;
18607dc1947SRichard Lowe         /* By section 6.3.2 Dwarf3 draft 8/9,
18707dc1947SRichard Lowe         the base file should appear as
18807dc1947SRichard Lowe         DW_MACINFO_start_file. See
18907dc1947SRichard Lowe         http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg03442.html
19007dc1947SRichard Lowe         on "[Bug debug/20253] New: [3.4/4.0 regression]:
19107dc1947SRichard Lowe         Macro debug info broken due to lexer change" for how
19207dc1947SRichard Lowe         gcc is broken in some versions. We no longer use
19307dc1947SRichard Lowe         depth as a stopping point, it's not needed as a
19407dc1947SRichard Lowe         stopping point anyway.  */
19507dc1947SRichard Lowe     int res = 0;
19649d3bc91SRichard Lowe     /* count space used by strings */
19749d3bc91SRichard Lowe     unsigned long str_space = 0;
19849d3bc91SRichard Lowe     int done = 0;
19907dc1947SRichard Lowe     unsigned long space_needed = 0;
20007dc1947SRichard Lowe     unsigned long string_offset = 0;
20107dc1947SRichard Lowe     Dwarf_Small *return_data = 0;
20207dc1947SRichard Lowe     Dwarf_Small *pdata = 0;
20349d3bc91SRichard Lowe     unsigned long final_count = 0;
20449d3bc91SRichard Lowe     Dwarf_Signed fileindex = -1;
20507dc1947SRichard Lowe     Dwarf_Small *latest_str_loc = 0;
20607dc1947SRichard Lowe     struct macro_stack_s msdata;
20749d3bc91SRichard Lowe 
20807dc1947SRichard Lowe     unsigned long count = 0;
20949d3bc91SRichard Lowe     unsigned long max_count = (unsigned long) maximum_count;
21049d3bc91SRichard Lowe 
21107dc1947SRichard Lowe     _dwarf_reset_index_macro_stack(&msdata);
21249d3bc91SRichard Lowe     if (dbg == NULL) {
21307dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
21407dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
21507dc1947SRichard Lowe         return (DW_DLV_ERROR);
21649d3bc91SRichard Lowe     }
21749d3bc91SRichard Lowe 
21807dc1947SRichard Lowe     res = _dwarf_load_section(dbg, &dbg->de_debug_macinfo,error);
21949d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
22007dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
22107dc1947SRichard Lowe         return res;
22249d3bc91SRichard Lowe     }
223*4d9fdb46SRobert Mustacchi     if (!dbg->de_debug_abbrev.dss_size) {
224*4d9fdb46SRobert Mustacchi         free_macro_stack(dbg,&msdata);
225*4d9fdb46SRobert Mustacchi         return (DW_DLV_NO_ENTRY);
226*4d9fdb46SRobert Mustacchi     }
22749d3bc91SRichard Lowe 
22807dc1947SRichard Lowe     macro_base = dbg->de_debug_macinfo.dss_data;
22949d3bc91SRichard Lowe     if (macro_base == NULL) {
23007dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
23107dc1947SRichard Lowe         return (DW_DLV_NO_ENTRY);
23249d3bc91SRichard Lowe     }
23307dc1947SRichard Lowe     if (macro_offset >= dbg->de_debug_macinfo.dss_size) {
23407dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
23507dc1947SRichard Lowe         return (DW_DLV_NO_ENTRY);
23649d3bc91SRichard Lowe     }
237*4d9fdb46SRobert Mustacchi     macro_end = macro_base + dbg->de_debug_macinfo.dss_size;
238*4d9fdb46SRobert Mustacchi     /*   FIXME debugfission is NOT handled here.  */
23949d3bc91SRichard Lowe 
24049d3bc91SRichard Lowe     pnext = macro_base + macro_offset;
24149d3bc91SRichard Lowe     if (maximum_count == 0) {
24207dc1947SRichard Lowe         max_count = ULONG_MAX;
24349d3bc91SRichard Lowe     }
24449d3bc91SRichard Lowe 
24549d3bc91SRichard Lowe 
24649d3bc91SRichard Lowe     /* how many entries and how much space will they take? */
24749d3bc91SRichard Lowe 
24849d3bc91SRichard Lowe     endloc = (pnext - macro_base);
24907dc1947SRichard Lowe     if (endloc >= dbg->de_debug_macinfo.dss_size) {
25007dc1947SRichard Lowe         if (endloc == dbg->de_debug_macinfo.dss_size) {
25107dc1947SRichard Lowe             /* normal: found last entry */
25207dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
25307dc1947SRichard Lowe             return DW_DLV_NO_ENTRY;
25407dc1947SRichard Lowe         }
25507dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
25607dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
25707dc1947SRichard Lowe         return (DW_DLV_ERROR);
25849d3bc91SRichard Lowe     }
25949d3bc91SRichard Lowe     for (count = 0; !done && count < max_count; ++count) {
260*4d9fdb46SRobert Mustacchi         unsigned long slen = 0;
261*4d9fdb46SRobert Mustacchi 
262*4d9fdb46SRobert Mustacchi         /* Set but not used */
263*4d9fdb46SRobert Mustacchi         UNUSEDARG Dwarf_Unsigned utemp = 0;
26407dc1947SRichard Lowe 
26507dc1947SRichard Lowe         uc = *pnext;
26607dc1947SRichard Lowe         ++pnext;                /* get past the type code */
26707dc1947SRichard Lowe         switch (uc) {
26807dc1947SRichard Lowe         case DW_MACINFO_define:
26907dc1947SRichard Lowe         case DW_MACINFO_undef:
27007dc1947SRichard Lowe             /* line, string */
27107dc1947SRichard Lowe         case DW_MACINFO_vendor_ext:
27207dc1947SRichard Lowe             /* number, string */
273*4d9fdb46SRobert Mustacchi             DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error,
274*4d9fdb46SRobert Mustacchi                 macro_end);
275*4d9fdb46SRobert Mustacchi             if (((Dwarf_Unsigned)(pnext - macro_base)) >=
276*4d9fdb46SRobert Mustacchi                 dbg->de_debug_macinfo.dss_size) {
27707dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
27807dc1947SRichard Lowe                 _dwarf_error(dbg, error,
27907dc1947SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
28007dc1947SRichard Lowe                 return (DW_DLV_ERROR);
28107dc1947SRichard Lowe             }
282*4d9fdb46SRobert Mustacchi             res = _dwarf_check_string_valid(dbg,
283*4d9fdb46SRobert Mustacchi                 macro_base,pnext,macro_end,
284*4d9fdb46SRobert Mustacchi                 DW_DLE_MACINFO_STRING_BAD,error);
285*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
286*4d9fdb46SRobert Mustacchi                 return res;
287*4d9fdb46SRobert Mustacchi             }
28807dc1947SRichard Lowe             slen = strlen((char *) pnext) + 1;
28907dc1947SRichard Lowe             pnext += slen;
290*4d9fdb46SRobert Mustacchi             if (((Dwarf_Unsigned)(pnext - macro_base)) >=
291*4d9fdb46SRobert Mustacchi                 dbg->de_debug_macinfo.dss_size) {
29207dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
29307dc1947SRichard Lowe                 _dwarf_error(dbg, error,
29407dc1947SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
29507dc1947SRichard Lowe                 return (DW_DLV_ERROR);
29607dc1947SRichard Lowe             }
29707dc1947SRichard Lowe             str_space += slen;
29807dc1947SRichard Lowe             break;
29907dc1947SRichard Lowe         case DW_MACINFO_start_file:
30007dc1947SRichard Lowe             /* line, file index */
301*4d9fdb46SRobert Mustacchi             DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error,
302*4d9fdb46SRobert Mustacchi                 macro_end);
303*4d9fdb46SRobert Mustacchi             if (((Dwarf_Unsigned)(pnext - macro_base)) >=
304*4d9fdb46SRobert Mustacchi                 dbg->de_debug_macinfo.dss_size) {
30507dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
30607dc1947SRichard Lowe                 _dwarf_error(dbg, error,
30707dc1947SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
30807dc1947SRichard Lowe                 return (DW_DLV_ERROR);
30907dc1947SRichard Lowe             }
310*4d9fdb46SRobert Mustacchi             DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error,
311*4d9fdb46SRobert Mustacchi                 macro_end);
312*4d9fdb46SRobert Mustacchi             if (((Dwarf_Unsigned)(pnext - macro_base)) >=
313*4d9fdb46SRobert Mustacchi                 dbg->de_debug_macinfo.dss_size) {
31407dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
31507dc1947SRichard Lowe                 _dwarf_error(dbg, error,
31607dc1947SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
31707dc1947SRichard Lowe                 return (DW_DLV_ERROR);
31807dc1947SRichard Lowe             }
31907dc1947SRichard Lowe             ++depth;
32007dc1947SRichard Lowe             break;
32107dc1947SRichard Lowe 
32207dc1947SRichard Lowe         case DW_MACINFO_end_file:
32307dc1947SRichard Lowe             if (--depth == 0) {
324*4d9fdb46SRobert Mustacchi                 /*  done = 1; no, do not stop here, at least one gcc had
325*4d9fdb46SRobert Mustacchi                     the wrong depth settings in the gcc 3.4 timeframe. */
32607dc1947SRichard Lowe             }
327*4d9fdb46SRobert Mustacchi             /* no string or number here */
328*4d9fdb46SRobert Mustacchi             break;
32907dc1947SRichard Lowe         case 0:
33007dc1947SRichard Lowe             /* end of cu's entries */
33107dc1947SRichard Lowe             done = 1;
33207dc1947SRichard Lowe             break;
33307dc1947SRichard Lowe         default:
33407dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
33507dc1947SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
33607dc1947SRichard Lowe             return (DW_DLV_ERROR);
33707dc1947SRichard Lowe             /* bogus macinfo! */
33807dc1947SRichard Lowe         }
33907dc1947SRichard Lowe 
34007dc1947SRichard Lowe         endloc = (pnext - macro_base);
34107dc1947SRichard Lowe         if (endloc == dbg->de_debug_macinfo.dss_size) {
34207dc1947SRichard Lowe             done = 1;
34307dc1947SRichard Lowe         } else if (endloc > dbg->de_debug_macinfo.dss_size) {
34407dc1947SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
34507dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
34607dc1947SRichard Lowe             return (DW_DLV_ERROR);
34707dc1947SRichard Lowe         }
34849d3bc91SRichard Lowe     }
349*4d9fdb46SRobert Mustacchi     /*  ASSERT: The above loop will never let us get here
350*4d9fdb46SRobert Mustacchi         with count < 1. No need to test for a zero count.
35149d3bc91SRichard Lowe 
352*4d9fdb46SRobert Mustacchi         We have 'count' array entries to allocate and
353*4d9fdb46SRobert Mustacchi         str_space bytes of string space to provide for. */
35449d3bc91SRichard Lowe 
35549d3bc91SRichard Lowe     string_offset = count * sizeof(Dwarf_Macro_Details);
35649d3bc91SRichard Lowe 
35749d3bc91SRichard Lowe     /* extra 2 not really needed */
35849d3bc91SRichard Lowe     space_needed = string_offset + str_space + 2;
35949d3bc91SRichard Lowe     return_data = pdata =
360*4d9fdb46SRobert Mustacchi         (Dwarf_Small *)_dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed);
36149d3bc91SRichard Lowe     latest_str_loc = pdata + string_offset;
36249d3bc91SRichard Lowe     if (pdata == 0) {
36307dc1947SRichard Lowe         free_macro_stack(dbg,&msdata);
36407dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE);
36507dc1947SRichard Lowe         return (DW_DLV_ERROR);
36649d3bc91SRichard Lowe     }
36749d3bc91SRichard Lowe     pnext = macro_base + macro_offset;
36849d3bc91SRichard Lowe 
36949d3bc91SRichard Lowe     done = 0;
37007dc1947SRichard Lowe 
37107dc1947SRichard Lowe     /* A series ends with a type code of 0. */
37207dc1947SRichard Lowe 
37349d3bc91SRichard Lowe     for (final_count = 0; !done && final_count < count; ++final_count) {
374*4d9fdb46SRobert Mustacchi         unsigned long slen = 0;
375*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned v1 = 0;
37607dc1947SRichard Lowe         Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata +
37707dc1947SRichard Lowe             (final_count * sizeof (Dwarf_Macro_Details)));
37807dc1947SRichard Lowe 
37907dc1947SRichard Lowe         endloc = (pnext - macro_base);
38007dc1947SRichard Lowe         if (endloc > dbg->de_debug_macinfo.dss_size) {
38107dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
38207dc1947SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
38307dc1947SRichard Lowe             return (DW_DLV_ERROR);
38407dc1947SRichard Lowe         }
38507dc1947SRichard Lowe         uc = *pnext;
38607dc1947SRichard Lowe         pdmd->dmd_offset = (pnext - macro_base);
38707dc1947SRichard Lowe         pdmd->dmd_type = uc;
38807dc1947SRichard Lowe         pdmd->dmd_fileindex = fileindex;
38907dc1947SRichard Lowe         pdmd->dmd_lineno = 0;
39007dc1947SRichard Lowe         pdmd->dmd_macro = 0;
39107dc1947SRichard Lowe         ++pnext;                /* get past the type code */
39207dc1947SRichard Lowe         switch (uc) {
39307dc1947SRichard Lowe         case DW_MACINFO_define:
39407dc1947SRichard Lowe         case DW_MACINFO_undef:
39507dc1947SRichard Lowe             /* line, string */
39607dc1947SRichard Lowe         case DW_MACINFO_vendor_ext:
39707dc1947SRichard Lowe             /* number, string */
398*4d9fdb46SRobert Mustacchi             DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error,
399*4d9fdb46SRobert Mustacchi                 macro_end);
40007dc1947SRichard Lowe             pdmd->dmd_lineno = v1;
40107dc1947SRichard Lowe 
402*4d9fdb46SRobert Mustacchi             if (((Dwarf_Unsigned)(pnext - macro_base)) >=
403*4d9fdb46SRobert Mustacchi                 dbg->de_debug_macinfo.dss_size) {
40407dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
40507dc1947SRichard Lowe                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
40607dc1947SRichard Lowe                 _dwarf_error(dbg, error,
40707dc1947SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
40807dc1947SRichard Lowe                 return (DW_DLV_ERROR);
40907dc1947SRichard Lowe             }
410*4d9fdb46SRobert Mustacchi             res = _dwarf_check_string_valid(dbg,
411*4d9fdb46SRobert Mustacchi                 macro_base,pnext,macro_end,
412*4d9fdb46SRobert Mustacchi                 DW_DLE_MACINFO_STRING_BAD,error);
413*4d9fdb46SRobert Mustacchi             if (res != DW_DLV_OK) {
414*4d9fdb46SRobert Mustacchi                 return res;
415*4d9fdb46SRobert Mustacchi             }
41607dc1947SRichard Lowe             slen = strlen((char *) pnext) + 1;
41707dc1947SRichard Lowe             strcpy((char *) latest_str_loc, (char *) pnext);
41807dc1947SRichard Lowe             pdmd->dmd_macro = (char *) latest_str_loc;
41907dc1947SRichard Lowe             latest_str_loc += slen;
42007dc1947SRichard Lowe             pnext += slen;
421*4d9fdb46SRobert Mustacchi             if (((Dwarf_Unsigned)(pnext - macro_base)) >=
422*4d9fdb46SRobert Mustacchi                 dbg->de_debug_macinfo.dss_size) {
42307dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
42407dc1947SRichard Lowe                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
42507dc1947SRichard Lowe                 _dwarf_error(dbg, error,
42607dc1947SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
42707dc1947SRichard Lowe                 return (DW_DLV_ERROR);
42807dc1947SRichard Lowe             }
42907dc1947SRichard Lowe             break;
43007dc1947SRichard Lowe         case DW_MACINFO_start_file:
43107dc1947SRichard Lowe             /* Line, file index */
432*4d9fdb46SRobert Mustacchi             DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error,
433*4d9fdb46SRobert Mustacchi                 macro_end);
43407dc1947SRichard Lowe             pdmd->dmd_lineno = v1;
435*4d9fdb46SRobert Mustacchi             if (((Dwarf_Unsigned)(pnext - macro_base)) >=
436*4d9fdb46SRobert Mustacchi                 dbg->de_debug_macinfo.dss_size) {
43707dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
43807dc1947SRichard Lowe                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
43907dc1947SRichard Lowe                 _dwarf_error(dbg, error,
44007dc1947SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
44107dc1947SRichard Lowe                 return (DW_DLV_ERROR);
44207dc1947SRichard Lowe             }
443*4d9fdb46SRobert Mustacchi             DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error,
444*4d9fdb46SRobert Mustacchi                 macro_end);
44507dc1947SRichard Lowe             pdmd->dmd_fileindex = v1;
44607dc1947SRichard Lowe             (void) _dwarf_macro_stack_push_index(dbg, fileindex,
447*4d9fdb46SRobert Mustacchi                 &msdata);
448*4d9fdb46SRobert Mustacchi             /*  We ignore the error, we just let fileindex ** be -1 when
449*4d9fdb46SRobert Mustacchi                 we pop this one. */
45007dc1947SRichard Lowe             fileindex = v1;
451*4d9fdb46SRobert Mustacchi             if (((Dwarf_Unsigned)(pnext - macro_base)) >=
452*4d9fdb46SRobert Mustacchi                 dbg->de_debug_macinfo.dss_size) {
45307dc1947SRichard Lowe                 free_macro_stack(dbg,&msdata);
45407dc1947SRichard Lowe                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
45507dc1947SRichard Lowe                 _dwarf_error(dbg, error,
45607dc1947SRichard Lowe                     DW_DLE_DEBUG_MACRO_INCONSISTENT);
45707dc1947SRichard Lowe                 return (DW_DLV_ERROR);
45807dc1947SRichard Lowe             }
45907dc1947SRichard Lowe             break;
46007dc1947SRichard Lowe 
46107dc1947SRichard Lowe         case DW_MACINFO_end_file:
46207dc1947SRichard Lowe             fileindex = _dwarf_macro_stack_pop_index(&msdata);
46307dc1947SRichard Lowe             break;              /* no string or number here */
46407dc1947SRichard Lowe         case 0:
46507dc1947SRichard Lowe             /* Type code of 0 means the end of cu's entries. */
46607dc1947SRichard Lowe             done = 1;
46707dc1947SRichard Lowe             break;
46807dc1947SRichard Lowe         default:
46907dc1947SRichard Lowe             /* Bogus macinfo! */
47007dc1947SRichard Lowe             dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
47107dc1947SRichard Lowe             free_macro_stack(dbg,&msdata);
47207dc1947SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
47307dc1947SRichard Lowe             return (DW_DLV_ERROR);
47407dc1947SRichard Lowe         }
47549d3bc91SRichard Lowe     }
47649d3bc91SRichard Lowe     *entry_count = count;
47749d3bc91SRichard Lowe     *details = (Dwarf_Macro_Details *) return_data;
47807dc1947SRichard Lowe     free_macro_stack(dbg,&msdata);
47949d3bc91SRichard Lowe     return DW_DLV_OK;
48049d3bc91SRichard Lowe }
481