1/*
2  Copyright (C) 2015-2019 David Anderson. All Rights Reserved.
3
4  This program is free software; you can redistribute it and/or modify it
5  under the terms of version 2.1 of the GNU Lesser General Public License
6  as published by the Free Software Foundation.
7
8  This program is distributed in the hope that it would be useful, but
9  WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
12  Further, this software is distributed without any warranty that it is
13  free of the rightful claim of any third person regarding infringement
14  or the like.  Any license provided herein, whether implied or
15  otherwise, applies only to this software file.  Patent licenses, if
16  any, provided herein do not apply to combinations of this program with
17  other software, or any other product whatsoever.
18
19  You should have received a copy of the GNU Lesser General Public
20  License along with this program; if not, write the Free Software
21  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
22  USA.
23
24*/
25
26#include "config.h"
27#include <stdio.h>
28#include <limits.h>
29#ifdef HAVE_STDLIB_H
30#include <stdlib.h>
31#endif /* HAVE_STDLIB_H */
32#ifdef HAVE_MALLOC_H
33/* Useful include for some Windows compilers. */
34#include <malloc.h>
35#endif /* HAVE_MALLOC_H */
36#include "dwarf_incl.h"
37#include "dwarf_alloc.h"
38#include "dwarf_error.h"
39#include "dwarf_util.h"
40#include "dwarf_macro5.h"
41
42#define TRUE 1
43#define FALSE 0
44
45/*  Section 6.3: Macro Information:
46    Each macro unit ends with an entry
47    containing an opcode of 0. */
48
49static const Dwarf_Small dwarf_udata_string_form[]  = {DW_FORM_udata,DW_FORM_string};
50static const Dwarf_Small dwarf_udata_udata_form[]   = {DW_FORM_udata,DW_FORM_udata};
51static const Dwarf_Small dwarf_udata_strp_form[]    = {DW_FORM_udata,DW_FORM_strp};
52static const Dwarf_Small dwarf_udata_strp_sup_form[] = {DW_FORM_udata,DW_FORM_strp_sup};
53static const Dwarf_Small dwarf_secoffset_form[]     = {DW_FORM_sec_offset};
54static const Dwarf_Small dwarf_udata_strx_form[]    = {DW_FORM_udata,DW_FORM_strx};
55
56struct Dwarf_Macro_Forms_s dw5formsarray[] = {
57    {0,0,0},
58    {DW_MACRO_define,2,dwarf_udata_string_form},
59    {DW_MACRO_undef,2,dwarf_udata_string_form},
60    {DW_MACRO_start_file,2,dwarf_udata_udata_form},
61    {DW_MACRO_end_file,0,0},
62
63    {DW_MACRO_define_strp,2,dwarf_udata_strp_form},
64    {DW_MACRO_undef_strp,2,dwarf_udata_strp_form},
65    {DW_MACRO_import,1,dwarf_secoffset_form},
66
67    {DW_MACRO_define_sup,2,dwarf_udata_strp_sup_form},
68    {DW_MACRO_undef_sup,2,dwarf_udata_strp_sup_form},
69    {DW_MACRO_import_sup,1,dwarf_secoffset_form},
70
71    {DW_MACRO_define_strx,2,dwarf_udata_strx_form},
72    {DW_MACRO_undef_strx,2,dwarf_udata_strx_form},
73};
74
75
76
77/* Represents DWARF 5 macro info */
78/* .debug_macro predefined, in order by value  */
79static const struct Dwarf_Macro_OperationsList_s dwarf_default_macro_opslist = {
8013, dw5formsarray
81};
82
83
84static int _dwarf_internal_macro_context_by_offset(Dwarf_Debug dbg,
85    Dwarf_Unsigned offset,
86    Dwarf_Unsigned  * version_out,
87    Dwarf_Macro_Context * macro_context_out,
88    Dwarf_Unsigned *macro_ops_count_out,
89    Dwarf_Unsigned *macro_ops_data_length,
90    char **srcfiles,
91    Dwarf_Signed srcfilescount,
92    const char *comp_dir,
93    const char *comp_name,
94    Dwarf_CU_Context cu_context,
95    Dwarf_Error * error);
96
97static int _dwarf_internal_macro_context(Dwarf_Die die,
98    Dwarf_Bool offset_specified,
99    Dwarf_Unsigned offset,
100    Dwarf_Unsigned  * version_out,
101    Dwarf_Macro_Context * macro_context_out,
102    Dwarf_Unsigned *macro_unit_offset_out,
103    Dwarf_Unsigned *macro_ops_count_out,
104    Dwarf_Unsigned *macro_ops_data_length,
105    Dwarf_Error * error);
106
107static int
108is_std_moperator(Dwarf_Small op)
109{
110    if (op >= 1 && op <= DW_MACRO_undef_strx) {
111        return TRUE;
112    }
113    return FALSE;
114}
115
116static int
117_dwarf_skim_forms(Dwarf_Debug dbg,
118    Dwarf_Macro_Context mcontext,
119    Dwarf_Small *mdata_start,
120    unsigned formcount,
121    const Dwarf_Small *forms,
122    Dwarf_Small *section_end,
123    Dwarf_Unsigned *forms_length,
124    Dwarf_Error *error)
125{
126    unsigned i = 0;
127    Dwarf_Small curform = 0 ;
128    Dwarf_Unsigned totallen = 0;
129    Dwarf_Unsigned v = 0;
130    Dwarf_Unsigned ret_value = 0;
131    Dwarf_Unsigned length;
132    Dwarf_Small *mdata = mdata_start;
133    Dwarf_Unsigned leb128_length = 0;
134
135    for( ; i < formcount; ++i) {
136        curform = forms[i];
137        if (mdata >= section_end) {
138            _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
139            return DW_DLV_ERROR;
140        }
141        switch(curform) {
142        default:
143            _dwarf_error(dbg,error,
144                DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE);
145            return DW_DLV_ERROR;
146        case DW_FORM_block1:
147            v =  *(Dwarf_Small *) mdata;
148            totallen += v+1;
149            mdata += v+1;
150            break;
151        case DW_FORM_block2:
152            READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
153                mdata, DWARF_HALF_SIZE,
154                error,section_end);
155            v = ret_value + DWARF_HALF_SIZE;
156            totallen += v;
157            mdata += v;
158            break;
159        case DW_FORM_block4:
160            READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
161                mdata, DWARF_32BIT_SIZE,
162                error,section_end);
163            v = ret_value + DWARF_32BIT_SIZE;
164            totallen += v;
165            mdata += v;
166            break;
167        case DW_FORM_data1:
168            v = 1;
169            totallen += v;
170            mdata += v;
171            break;
172        case DW_FORM_data2:
173            v = 2;
174            totallen += v;
175            mdata += v;
176            break;
177        case DW_FORM_data4:
178            v = 4;
179            totallen += v;
180            mdata += v;
181            break;
182        case DW_FORM_data8:
183            v = 8;
184            totallen += v;
185            mdata += v;
186            break;
187        case DW_FORM_data16:
188            v = 8;
189            totallen += v;
190            mdata += v;
191            break;
192        case DW_FORM_string: {
193            int res = _dwarf_check_string_valid(dbg,
194                mdata,mdata, section_end,
195                DW_DLE_MACRO_STRING_BAD,error);
196            if(res != DW_DLV_OK) {
197                return res;
198            }
199            v = strlen((char *) mdata) + 1;
200            totallen += v;
201            mdata += v;
202            }
203            break;
204        case DW_FORM_block:
205            DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length,
206                dbg, error,section_end);
207            v = length + leb128_length;
208            totallen += v;
209            break;
210        case DW_FORM_flag:
211            v = 1;
212            totallen += v;
213            mdata += v;
214            break;
215        case DW_FORM_sec_offset:
216            /* If 32bit dwarf, is 4. Else is 64bit dwarf and is 8. */
217            v = mcontext->mc_offset_size;
218            totallen += v;
219            mdata += v;
220            break;
221        case DW_FORM_sdata:
222            /*  Discard the decoded value, we just want the length
223                of the value. */
224            DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length,
225                dbg, error,section_end);
226            totallen += v;
227            break;
228        case DW_FORM_strx:
229            DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length,
230                dbg, error,section_end);
231            totallen += leb128_length;;
232            break;
233        case DW_FORM_strp:
234            v = mcontext->mc_offset_size;
235            mdata += v;
236            totallen += v;
237            break;
238        case DW_FORM_udata:
239            /*  Discard the decoded value, we just want the length
240                of the value. */
241            DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length,
242                dbg, error,section_end);
243            totallen += leb128_length;
244            break;
245        }
246    }
247    if (mdata > section_end) {
248        _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
249        return DW_DLV_ERROR;
250    }
251    *forms_length = totallen;
252    return DW_DLV_OK;
253}
254
255#if 0 /* FOR DEBUGGING */
256static void
257dump_bytes(Dwarf_Small * start, long len)
258{
259    Dwarf_Small *end = start + len;
260    Dwarf_Small *cur = start;
261    unsigned pos = 0;
262
263    printf("dump %ld bytes, start at 0x%lx\n",len,(unsigned long)start);
264    printf("0x");
265    for (; cur < end;pos++, cur++) {
266        if (!(pos %4)) {
267            printf(" ");
268        }
269        printf("%02x",*cur);
270    }
271    printf("\n");
272}
273Dwarf_Bool
274is_defundef(unsigned op)
275{
276    switch(op){
277    case DW_MACRO_define:
278    case DW_MACRO_undef:
279    case DW_MACRO_define_strp:
280    case DW_MACRO_undef_strp:
281    case DW_MACRO_define_strx:
282    case DW_MACRO_undef_strx:
283    case DW_MACRO_define_sup:
284    case DW_MACRO_undef_sup:
285        return TRUE;
286    }
287    return FALSE;
288}
289#endif /* FOR DEBUGGING */
290
291
292/*  On first call (for this macro_context),
293    build_ops_array is FALSE. On second,
294    it is TRUE and we know the count so we allocate and fill in
295    the ops array. */
296static int
297_dwarf_get_macro_ops_count_internal(Dwarf_Macro_Context macro_context,
298    Dwarf_Bool build_ops_array,
299    Dwarf_Error *error)
300{
301    Dwarf_Debug dbg = 0;
302    Dwarf_Small *mdata = 0;
303    Dwarf_Small *section_end = 0;
304    Dwarf_Small *section_base = 0;
305    Dwarf_Unsigned opcount = 0;
306    Dwarf_Unsigned known_ops_count = 0;
307    struct Dwarf_Macro_Operator_s *opsarray = 0;
308    struct Dwarf_Macro_Operator_s *curopsentry = 0;
309    int res = 0;
310
311    dbg = macro_context->mc_dbg;
312    if (build_ops_array) {
313        known_ops_count = macro_context->mc_macro_ops_count;
314        opsarray = (struct Dwarf_Macro_Operator_s *)
315            calloc(known_ops_count,sizeof(struct Dwarf_Macro_Operator_s));
316        if(!opsarray) {
317            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
318            return DW_DLV_ERROR;
319        }
320        curopsentry = opsarray;
321        macro_context->mc_ops = opsarray;
322    }
323    section_base = dbg->de_debug_macro.dss_data;
324    section_end = section_base + dbg->de_debug_macro.dss_size;
325    mdata = macro_context->mc_macro_ops;
326
327    while (mdata < section_end) {
328        Dwarf_Small op = 0;
329
330        op = *mdata;
331        ++opcount;
332        ++mdata;
333        if (!op) {
334            Dwarf_Unsigned opslen = 0;
335            /*  End of ops, this is terminator, count the ending 0
336                as an operator so dwarfdump can print it.  */
337            opslen = mdata - macro_context->mc_macro_ops;
338            macro_context->mc_macro_ops_count = opcount;
339            macro_context->mc_ops_data_length = opslen;
340            macro_context->mc_total_length = opslen +
341                macro_context->mc_macro_header_length;
342            return DW_DLV_OK;
343        }
344        if (is_std_moperator(op)) {
345            struct Dwarf_Macro_Forms_s * ourform =
346                dw5formsarray + op;
347            /* ASSERT: op == ourform->mf_code */
348            unsigned formcount = ourform->mf_formcount;
349            const Dwarf_Small *forms = ourform->mf_formbytes;
350            Dwarf_Unsigned forms_length = 0;
351
352            res = _dwarf_skim_forms(dbg,macro_context,mdata,
353                formcount,forms,
354                section_end,
355                &forms_length,error);
356            if ( res != DW_DLV_OK) {
357                return res;
358            }
359            if(build_ops_array) {
360                curopsentry->mo_opcode = op;
361                curopsentry->mo_form = ourform;
362                curopsentry->mo_data = mdata;
363            }
364            mdata += forms_length;
365        } else {
366            /* FIXME Add support for user defined ops. */
367            _dwarf_error(dbg, error, DW_DLE_MACRO_OP_UNHANDLED);
368            return DW_DLV_ERROR;
369        }
370        if (mdata > section_end)  {
371            _dwarf_error(dbg, error, DW_DLE_MACRO_PAST_END);
372            return DW_DLV_ERROR;
373        }
374        if (build_ops_array) {
375            curopsentry++;
376        }
377    }
378    _dwarf_error(dbg, error, DW_DLE_MACRO_PAST_END);
379    return DW_DLV_ERROR;
380}
381
382int
383dwarf_get_macro_op(Dwarf_Macro_Context macro_context,
384    Dwarf_Unsigned op_number,
385    Dwarf_Unsigned * op_start_section_offset,
386    Dwarf_Half    * macro_operator,
387    Dwarf_Half    * forms_count,
388    const Dwarf_Small **   formcode_array,
389    Dwarf_Error *error)
390{
391    struct Dwarf_Macro_Operator_s *curop = 0;
392    Dwarf_Debug dbg = 0;
393    if (!macro_context || macro_context->mc_sentinel != 0xada) {
394        if(macro_context) {
395            dbg = macro_context->mc_dbg;
396        }
397        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER);
398        return DW_DLV_ERROR;
399    }
400    dbg = macro_context->mc_dbg;
401    if (op_number >= macro_context->mc_macro_ops_count) {
402        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX);
403        return DW_DLV_ERROR;
404    }
405    curop = macro_context->mc_ops + op_number;
406
407    /*  ASSERT: *op_start_section_offset ==
408        (curop->mo_data -1) - dbg->de_debug_macro.dss_data  */
409    *op_start_section_offset =
410        ((curop->mo_data -1) - macro_context->mc_macro_header) +
411        macro_context->mc_section_offset;
412    *macro_operator = curop->mo_opcode;
413    if (curop->mo_form) {
414        *forms_count  = curop->mo_form->mf_formcount;
415        *formcode_array = curop->mo_form->mf_formbytes;
416    } else {
417        /* ASSERT: macro_operator == 0 */
418        *forms_count  = 0;
419        *formcode_array = 0;
420    }
421    return DW_DLV_OK;
422}
423
424
425/*  Here a DW_DLV_NO_ENTRY return means the macro operator
426    is not a def/undef operator. */
427int
428dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context,
429    Dwarf_Unsigned op_number,
430    Dwarf_Unsigned * line_number,
431    Dwarf_Unsigned * index,
432    Dwarf_Unsigned * offset,
433    Dwarf_Half     * forms_count,
434    const char     ** macro_string,
435    Dwarf_Error *error)
436{
437    Dwarf_Debug dbg = 0;
438    Dwarf_Small *mdata = 0;
439    int res = 0;
440    Dwarf_Small *startptr = 0;
441    Dwarf_Small *endptr = 0;
442    Dwarf_Half lformscount = 0;
443    struct Dwarf_Macro_Operator_s *curop = 0;
444    unsigned macop = 0;
445
446    if (!macro_context || macro_context->mc_sentinel != 0xada) {
447        if(macro_context) {
448            dbg = macro_context->mc_dbg;
449        }
450        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER);
451        return DW_DLV_ERROR;
452    }
453    dbg = macro_context->mc_dbg;
454    if (op_number >= macro_context->mc_macro_ops_count) {
455        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX);
456        return DW_DLV_ERROR;
457    }
458    curop = macro_context->mc_ops + op_number;
459    macop = curop->mo_opcode;
460    startptr = macro_context->mc_macro_header;
461    endptr = startptr + macro_context->mc_total_length;
462    mdata = curop->mo_data;
463    lformscount = curop->mo_form->mf_formcount;
464    if (lformscount != 2) {
465        /*_dwarf_error(dbg, error,DW_DLE_MACRO_OPCODE_FORM_BAD);*/
466        return DW_DLV_NO_ENTRY;
467    }
468    switch(macop){
469    case DW_MACRO_define:
470    case DW_MACRO_undef: {
471        Dwarf_Unsigned linenum = 0;
472        const char * content = 0;
473
474        DECODE_LEB128_UWORD_CK(mdata,linenum,
475            dbg, error,endptr);
476        content = (const char *)mdata;
477        res = _dwarf_check_string_valid(dbg,
478            startptr,mdata, endptr,
479            DW_DLE_MACRO_STRING_BAD,error);
480        if(res != DW_DLV_OK) {
481            return res;
482        }
483        *line_number = linenum;
484        *index = 0;
485        *offset = 0;
486        *forms_count = lformscount;
487        *macro_string = content;
488        }
489        return DW_DLV_OK;
490    case DW_MACRO_define_strp:
491    case DW_MACRO_undef_strp: {
492        Dwarf_Unsigned linenum = 0;
493        Dwarf_Unsigned stringoffset = 0;
494        Dwarf_Small form1 =  curop->mo_form->mf_formbytes[1];
495        char * localstr = 0;
496
497
498        DECODE_LEB128_UWORD_CK(mdata,linenum,
499            dbg, error,endptr);
500        READ_UNALIGNED_CK(dbg,stringoffset,Dwarf_Unsigned,
501            mdata,macro_context->mc_offset_size,
502            error,endptr);
503        res = _dwarf_extract_local_debug_str_string_given_offset(dbg,
504            form1,
505            stringoffset,
506            &localstr,
507            error);
508        *index = 0;
509        *line_number = linenum;
510        *offset = stringoffset;
511        *forms_count = lformscount;
512        if (res == DW_DLV_ERROR) {
513            *macro_string = "<Error: getting local .debug_str>";
514            return res;
515        } else if (res == DW_DLV_NO_ENTRY) {
516            *macro_string = "<Error: NO_ENTRY on .debug_string (strp)>";
517        } else {
518            *macro_string = (const char *)localstr;
519        }
520        }
521        return DW_DLV_OK;
522    case DW_MACRO_define_strx:
523    case DW_MACRO_undef_strx: {
524        Dwarf_Unsigned linenum = 0;
525        Dwarf_Unsigned stringindex = 0;
526        Dwarf_Unsigned offsettostr= 0;
527        int ress = 0;
528        Dwarf_Byte_Ptr mdata_copy = 0;
529        Dwarf_Small form1 =  curop->mo_form->mf_formbytes[1];
530
531        DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr);
532        *line_number = linenum;
533        mdata_copy = mdata;
534        DECODE_LEB128_UWORD_CK(mdata_copy,stringindex, dbg, error,endptr);
535        /* mdata_copy is for call below */
536
537
538        *index = stringindex;
539        *forms_count = lformscount;
540
541        /* Redoes the index-getting. Gets offset. */
542        ress = _dwarf_extract_string_offset_via_str_offsets(dbg,
543            mdata_copy,
544            endptr,
545            DW_AT_macros, /*arbitrary, unused by called routine. */
546            form1,
547            macro_context->mc_cu_context,
548            &offsettostr,
549            error);
550        if (ress  == DW_DLV_ERROR) {
551            return ress;
552        }
553        if (ress == DW_DLV_OK) {
554            char *localstr = 0;
555
556            *index = stringindex;
557            *offset = offsettostr;
558            ress = _dwarf_extract_local_debug_str_string_given_offset(dbg,
559                form1,
560                offsettostr,
561                &localstr,
562                error);
563            if(ress == DW_DLV_ERROR) {
564                return ress;
565            } else if (ress == DW_DLV_NO_ENTRY){
566                *macro_string = "<:No string available>";
567            } else {
568                *macro_string = (const char *)localstr;
569                /* All is ok. */
570            }
571        } else {
572            *index = stringindex;
573            *offset = 0;
574            *macro_string = "<.debug_str_offsets not available>";
575        }
576        }
577        return DW_DLV_OK;
578    case DW_MACRO_define_sup:
579    case DW_MACRO_undef_sup: {
580        Dwarf_Unsigned linenum = 0;
581        Dwarf_Unsigned supoffset = 0;
582        char *localstring = 0;
583        int resup = 0;
584        Dwarf_Error lerr = 0;
585
586        DECODE_LEB128_UWORD_CK(mdata,linenum,
587            dbg, error,endptr);
588        READ_UNALIGNED_CK(dbg,supoffset,Dwarf_Unsigned,
589            mdata,macro_context->mc_offset_size,
590            error,endptr);
591        *line_number = linenum;
592        *index = 0;
593        *offset = supoffset;
594        *forms_count = lformscount;
595        resup = _dwarf_get_string_from_tied(dbg, supoffset,
596            &localstring, &lerr);
597        if (resup != DW_DLV_OK) {
598            if (resup == DW_DLV_ERROR) {
599                int myerrno = dwarf_errno(lerr);
600                if(myerrno == DW_DLE_NO_TIED_FILE_AVAILABLE) {
601                    *macro_string =
602                        (char *)"<DW_FORM_str_sup-no-tied_file>";
603                } else {
604                    _dwarf_error(dbg,error,myerrno);
605                    *macro_string =
606                        (char *)"<Error: DW_FORM_str_sup-got-error>";
607                }
608                dwarf_dealloc(dbg,lerr,DW_DLA_ERROR);
609            } else {
610                *macro_string = "<DW_FORM_str_sup-no-entry>";
611            }
612            return resup;
613        }
614        *macro_string = (const char *)localstring;
615        /*  If NO ENTRY available, return DW_DLV_NO_ENTRY.
616            We suspect this is better than DW_DLV_OK.  */
617        return resup;
618        }
619    default:
620        _dwarf_error(dbg,error,DW_DLE_MACRO_OP_UNHANDLED);
621        return DW_DLV_ERROR;
622    }
623    return DW_DLV_NO_ENTRY;
624}
625
626/*  ASSERT: we elsewhere guarantee room to copy into.
627    If trimtarg ==1, trim trailing slash in targ.
628    Caller should not pass in 'src'
629    with leading /  */
630static void
631specialcat(char *targ,char *src,int trimtarg)
632{
633    char *last = 0;
634
635    while( *targ) {
636        last = targ;
637        targ++;
638    }
639    /* TARG now points at terminating NUL */
640    /* LAST points at final character in targ. */
641    if (trimtarg ) {
642        if(last && *last == '/') {
643            /* Truncate. */
644            *last = 0;
645            targ = last;
646            /* TARG again points at terminating NUL */
647        }
648    }
649    while (*src) {
650        *targ = *src;
651        targ++;
652        src++;
653    }
654    *targ = 0;
655}
656
657/* If returns NULL caller must handle it. */
658static const char *
659construct_from_dir_and_name(const char *dir,
660   const char *name)
661{
662    int truelen = 0;
663    char *final = 0;
664
665    /* Allow for NUL char and added /  */
666    truelen = strlen(dir) + strlen(name) + 1 +1;
667    final = (char *)malloc(truelen);
668    if(!final) {
669        return NULL;
670    }
671    final[0] = 0;
672    specialcat(final,(char *)dir,1);
673    strcat(final,"/");
674    specialcat(final,(char *)name,0);
675    return final;
676}
677
678/* If returns NULL caller must handle it. */
679static const char *
680construct_at_path_from_parts(Dwarf_Macro_Context mc)
681{
682    if (mc->mc_file_path) {
683        return mc->mc_file_path;
684    }
685    if(!mc->mc_at_comp_dir || !mc->mc_at_comp_dir[0]) {
686        return mc->mc_at_name;
687    }
688    if (!mc->mc_at_name || !mc->mc_at_name[0]) {
689        return NULL;
690    }
691    if(_dwarf_file_name_is_full_path((Dwarf_Small *)mc->mc_at_name)) {
692        return mc->mc_at_name;
693    }
694    /* Dwarf_Macro_Context destructor will free this. */
695    mc->mc_file_path = construct_from_dir_and_name(
696        mc->mc_at_comp_dir,mc->mc_at_name);
697    return mc->mc_file_path;
698}
699
700
701int
702dwarf_get_macro_startend_file(Dwarf_Macro_Context macro_context,
703    Dwarf_Unsigned op_number,
704    Dwarf_Unsigned * line_number,
705    Dwarf_Unsigned * name_index_to_line_tab,
706    const char     ** src_file_name,
707    Dwarf_Error *error)
708{
709    Dwarf_Debug dbg = 0;
710    Dwarf_Small *mdata = 0;
711    unsigned macop = 0;
712    struct Dwarf_Macro_Operator_s *curop = 0;
713    Dwarf_Byte_Ptr startptr =  0;
714    Dwarf_Byte_Ptr endptr =  0;
715
716    if (!macro_context || macro_context->mc_sentinel != 0xada) {
717        if(macro_context) {
718            dbg = macro_context->mc_dbg;
719        }
720        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER);
721        return DW_DLV_ERROR;
722    }
723    dbg = macro_context->mc_dbg;
724    if (op_number >= macro_context->mc_macro_ops_count) {
725        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX);
726        return DW_DLV_ERROR;
727    }
728    startptr = macro_context->mc_macro_header;
729    endptr = startptr + macro_context->mc_total_length;
730
731    curop = macro_context->mc_ops + op_number;
732    macop = curop->mo_opcode;
733    mdata = curop->mo_data;
734    if (macop != DW_MACRO_start_file && macop != DW_MACRO_end_file) {
735        return DW_DLV_NO_ENTRY;
736    }
737    if (macop == DW_MACRO_start_file) {
738        Dwarf_Unsigned linenum = 0;
739        Dwarf_Unsigned srcindex = 0;
740        Dwarf_Signed trueindex = 0;
741
742        DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr);
743        DECODE_LEB128_UWORD_CK(mdata,srcindex, dbg, error,endptr);
744        *line_number = linenum;
745        *name_index_to_line_tab = srcindex;
746        /*  For DWARF 2,3,4, decrement by 1.
747            FOR DWARF 5 do not decrement. */
748        if(macro_context->mc_version_number >= 5) {
749            trueindex = srcindex;
750            if (trueindex < 0) {
751                *src_file_name = "<source-file-index-low-no-name-available>";
752                return DW_DLV_OK;
753            }
754            if (trueindex < macro_context->mc_srcfiles_count) {
755                *src_file_name = macro_context->mc_srcfiles[trueindex];
756                return DW_DLV_OK;
757            } else {
758                *src_file_name =
759                    "<src-index-high-no-source-file-name-available>";
760                return DW_DLV_OK;
761            }
762        } else {
763            /* Unsigned to signed here. */
764            trueindex = srcindex;
765            /* Protects against crazy big srcindex, overflow territory. */
766            if (trueindex < 0 ) {
767                /* Something insane here. */
768                *src_file_name = "<source-file-index-low-no-name-available>";
769                return DW_DLV_OK;
770            }
771            /* Protects against crazy big srcindex, overflow territory. */
772            if (trueindex > (macro_context->mc_srcfiles_count+1)) {
773                /* Something insane here. */
774                *src_file_name =
775                    "<source-file-index-high-no-name-available>";
776                return DW_DLV_OK;
777            }
778            --trueindex;
779            if (trueindex > macro_context->mc_srcfiles_count) {
780                *src_file_name =
781                    "<adjusted-source-file-index-high-no-name-available>";
782            }
783            if (srcindex > 0 &&
784                trueindex < macro_context->mc_srcfiles_count) {
785                *src_file_name = macro_context->mc_srcfiles[trueindex];
786            } else {
787                const char *mcatcomp = construct_at_path_from_parts(
788                    macro_context);
789                if(mcatcomp) {
790                    *src_file_name = mcatcomp;
791                } else {
792                    *src_file_name = "<no-source-file-name-available>";
793                }
794            }
795        }
796    } else {
797        /* DW_MACRO_end_file. No operands. */
798    }
799    return DW_DLV_OK;
800}
801
802/*  Target_offset is the offset in a .debug_macro section,
803    of a macro unit header.
804    Returns DW_DLV_NO_ENTRY if the macro operator is not
805    one of the import operators.  */
806int
807dwarf_get_macro_import(Dwarf_Macro_Context macro_context,
808    Dwarf_Unsigned   op_number,
809    Dwarf_Unsigned * target_offset,
810    Dwarf_Error *error)
811{
812    Dwarf_Unsigned supoffset = 0;
813    Dwarf_Debug dbg = 0;
814    unsigned macop = 0;
815    struct Dwarf_Macro_Operator_s *curop = 0;
816    Dwarf_Small *mdata = 0;
817    Dwarf_Byte_Ptr startptr =  0;
818    Dwarf_Byte_Ptr endptr =  0;
819
820    if (!macro_context || macro_context->mc_sentinel != 0xada) {
821        if(macro_context) {
822            dbg = macro_context->mc_dbg;
823        }
824        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER);
825        return DW_DLV_ERROR;
826    }
827    startptr = macro_context->mc_macro_header;
828    endptr = startptr + macro_context->mc_total_length;
829    dbg = macro_context->mc_dbg;
830    if (op_number >= macro_context->mc_macro_ops_count) {
831        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX);
832        return DW_DLV_ERROR;
833    }
834    curop = macro_context->mc_ops + op_number;
835    macop = curop->mo_opcode;
836    mdata = curop->mo_data;
837    if (macop != DW_MACRO_import && macop != DW_MACRO_import_sup) {
838        return DW_DLV_NO_ENTRY;
839    }
840    READ_UNALIGNED_CK(dbg,supoffset,Dwarf_Unsigned,
841        mdata,macro_context->mc_offset_size,
842        error,endptr);
843    *target_offset = supoffset;
844    return DW_DLV_OK;
845}
846
847/* */
848static int
849valid_macro_form(Dwarf_Half form)
850{
851    switch(form) {
852    case DW_FORM_block:
853    case DW_FORM_block1:
854    case DW_FORM_block2:
855    case DW_FORM_block4:
856    case DW_FORM_data1:
857    case DW_FORM_data2:
858    case DW_FORM_data4:
859    case DW_FORM_data8:
860    case DW_FORM_data16:
861    case DW_FORM_sdata:
862    case DW_FORM_udata:
863    case DW_FORM_flag:
864    case DW_FORM_sec_offset:
865    case DW_FORM_string:
866    case DW_FORM_strp:
867    case DW_FORM_strx:
868        return TRUE;
869    }
870    return FALSE;
871}
872
873static int
874validate_opcode(Dwarf_Debug dbg,
875   struct Dwarf_Macro_Forms_s *curform,
876   Dwarf_Error * error)
877{
878    unsigned i = 0;
879    struct Dwarf_Macro_Forms_s *stdfptr = 0;
880    if (curform->mf_code >= DW_MACRO_lo_user) {
881        /* Nothing to check. user level. */
882        return DW_DLV_OK;
883    }
884    if (curform->mf_code > DW_MACRO_undef_strx) {
885        _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_BAD);
886        return (DW_DLV_ERROR);
887    }
888    if (!curform->mf_code){
889        _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_BAD);
890        return (DW_DLV_ERROR);
891    }
892    stdfptr = &dwarf_default_macro_opslist.mol_data[curform->mf_code];
893
894    if (curform->mf_formcount != stdfptr->mf_formcount) {
895        _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_FORM_BAD);
896        return (DW_DLV_ERROR);
897    }
898    for(i = 0; i < curform->mf_formcount; ++i) {
899        if (curform->mf_formbytes[i] != stdfptr->mf_formbytes[1]) {
900            _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_FORM_BAD);
901            return (DW_DLV_ERROR);
902        }
903    }
904    return DW_DLV_OK;
905}
906
907static int
908read_operands_table(Dwarf_Macro_Context macro_context,
909    Dwarf_Small * macro_header,
910    Dwarf_Small * macro_data,
911    Dwarf_Small * section_base,
912    Dwarf_Unsigned section_size,
913    Dwarf_Unsigned *table_size_out,
914    Dwarf_Error *error)
915{
916    Dwarf_Small* table_data_start = macro_data;
917    Dwarf_Unsigned local_size = 0;
918    Dwarf_Unsigned cur_offset = 0;
919    Dwarf_Small operand_table_count = 0;
920    unsigned i = 0;
921    struct Dwarf_Macro_Forms_s *curformentry = 0;
922    Dwarf_Debug dbg = 0;
923    Dwarf_Byte_Ptr startptr = 0;
924    Dwarf_Byte_Ptr endptr = 0;
925
926    if (!macro_context || macro_context->mc_sentinel != 0xada) {
927        if(macro_context) {
928            dbg = macro_context->mc_dbg;
929        }
930        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER);
931        return DW_DLV_ERROR;
932    }
933
934    dbg = macro_context->mc_dbg;
935    cur_offset = (1+ macro_data) - macro_header;
936    if (cur_offset >= section_size) {
937        _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
938        return (DW_DLV_ERROR);
939    }
940
941    startptr = macro_context->mc_macro_header;
942    endptr = startptr + macro_context->mc_total_length;
943    READ_UNALIGNED_CK(dbg,operand_table_count,Dwarf_Small,
944        macro_data,sizeof(Dwarf_Small),error,endptr);
945    macro_data += sizeof(Dwarf_Small);
946    /* Estimating minimum size */
947    local_size = operand_table_count * 4;
948
949    cur_offset = (local_size+ macro_data) - section_base;
950    if (cur_offset >= section_size) {
951        _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
952        return (DW_DLV_ERROR);
953    }
954    /* first, get size of table. */
955    table_data_start = macro_data;
956    for (i = 0; i < operand_table_count; ++i) {
957        /*  Compiler warning about unused opcode_number
958            variable should be ignored. */
959        UNUSEDARG Dwarf_Small opcode_number = 0;
960        Dwarf_Unsigned formcount = 0;
961        READ_UNALIGNED_CK(dbg,opcode_number,Dwarf_Small,
962            macro_data,sizeof(Dwarf_Small),error,endptr);
963        macro_data += sizeof(Dwarf_Small);
964
965        DECODE_LEB128_UWORD_CK(macro_data,formcount,
966            dbg, error, endptr);
967        cur_offset = (formcount+ macro_data) - section_base;
968        if (cur_offset >= section_size) {
969            _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
970            return (DW_DLV_ERROR);
971        }
972        /* The 1 ubyte forms follow. Step past them. */
973        macro_data += formcount;
974    }
975    /* reset for reread. */
976    macro_data = table_data_start;
977    /* allocate table */
978    macro_context->mc_opcode_forms =  (struct Dwarf_Macro_Forms_s *)
979        calloc(operand_table_count,
980            sizeof(struct Dwarf_Macro_Forms_s));
981    macro_context->mc_opcode_count = operand_table_count;
982    if(!macro_context->mc_opcode_forms) {
983        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
984        return DW_DLV_ERROR;
985    }
986
987    curformentry = macro_context->mc_opcode_forms;
988    for (i = 0; i < operand_table_count; ++i,++curformentry) {
989        Dwarf_Small opcode_number = 0;
990        Dwarf_Unsigned formcount = 0;
991        int res = 0;
992
993        cur_offset = (2 + macro_data) - section_base;
994        if (cur_offset >= section_size) {
995            _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
996            return (DW_DLV_ERROR);
997        }
998        READ_UNALIGNED_CK(dbg,opcode_number,Dwarf_Small,
999            macro_data,sizeof(Dwarf_Small),
1000            error,endptr);
1001        macro_data += sizeof(Dwarf_Small);
1002        DECODE_LEB128_UWORD_CK(macro_data,formcount,
1003            dbg, error, endptr);
1004
1005        curformentry->mf_code = opcode_number;
1006        curformentry->mf_formcount = formcount;
1007
1008        cur_offset = (formcount+ macro_data) - section_base;
1009        if (cur_offset >= section_size) {
1010            _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
1011            return (DW_DLV_ERROR);
1012        }
1013        curformentry->mf_formbytes = macro_data;
1014        macro_data += formcount;
1015        if (opcode_number  > DW_MACRO_undef_strx ) {
1016            Dwarf_Half k = 0;
1017            for(k = 0; k < formcount; ++k) {
1018                if (!valid_macro_form(curformentry->mf_formbytes[k])) {
1019                    _dwarf_error(dbg, error, DW_DLE_MACRO_OP_UNHANDLED);
1020                    return (DW_DLV_ERROR);
1021                }
1022            }
1023        }
1024        res = validate_opcode(macro_context->mc_dbg,curformentry, error);
1025        if(res != DW_DLV_OK) {
1026            return res;
1027        }
1028    }
1029    *table_size_out = macro_data - table_data_start;
1030    return DW_DLV_OK;
1031}
1032
1033/*  This is not the normal srcfiles from dwarf_srcfiles.
1034    See translate translate_srcfiles_to_srcfiles2().
1035    It is a list, but the contents were directly malloc,
1036    not _dwarf_get_alloc.
1037*/
1038static void
1039dealloc_macro_srcfiles(char ** srcfiles,
1040    Dwarf_Signed srcfiles_count)
1041{
1042    Dwarf_Signed i = 0;
1043    if (!srcfiles || !srcfiles_count) {
1044        return;
1045    }
1046    for (i = 0; i < srcfiles_count; ++i) {
1047        if (srcfiles[i]) {
1048            free(srcfiles[i]);
1049            srcfiles[i] = 0;
1050        }
1051    }
1052    free(srcfiles);
1053}
1054
1055/*  This makes the macro context safe from
1056    duplicate frees in case of error. */
1057static int
1058translate_srcfiles_to_srcfiles2(char **srcfiles,
1059   Dwarf_Signed srcfiles_count,
1060   char **srcfiles2)
1061{
1062    Dwarf_Signed i = 0;
1063
1064    for(i = 0; i < srcfiles_count; ++i) {
1065        char * ostr = 0;
1066        char * newstr = 0;
1067        size_t slen = 0;
1068
1069        ostr = srcfiles[i];
1070        slen = strlen(ostr);
1071        newstr =  calloc(1,slen+1);
1072        if (!newstr) {
1073            return DW_DLV_ERROR;
1074        }
1075        strcpy(newstr,ostr);
1076        srcfiles2[i] = newstr;
1077    }
1078    return DW_DLV_OK;
1079}
1080
1081static void
1082drop_srcfiles(Dwarf_Debug dbg,char ** srcfiles,
1083    Dwarf_Signed srcfiles_count)
1084{
1085    Dwarf_Signed i = 0;
1086    for (i = 0; i < srcfiles_count; ++i) {
1087        if(srcfiles[i]) {
1088            dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING);
1089        }
1090    }
1091    dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST);
1092}
1093
1094
1095static int
1096_dwarf_internal_macro_context(Dwarf_Die die,
1097    Dwarf_Bool        offset_specified,
1098    Dwarf_Unsigned    offset_in,
1099    Dwarf_Unsigned  * version_out,
1100    Dwarf_Macro_Context * macro_context_out,
1101    Dwarf_Unsigned      * macro_unit_offset_out,
1102    Dwarf_Unsigned      * macro_ops_count_out,
1103    Dwarf_Unsigned      * macro_ops_data_length,
1104    Dwarf_Error * error)
1105{
1106    Dwarf_CU_Context   cu_context = 0;
1107
1108    /*  The Dwarf_Debug this die belongs to. */
1109    Dwarf_Debug dbg = 0;
1110    int resattr = DW_DLV_ERROR;
1111    int lres = DW_DLV_ERROR;
1112    int res = DW_DLV_ERROR;
1113    Dwarf_Unsigned macro_offset = 0;
1114    Dwarf_Attribute macro_attr = 0;
1115    Dwarf_Signed srcfiles_count = 0;
1116    Dwarf_Signed srcfiles2_count = 0;
1117    char ** srcfiles = 0;
1118
1119    /*  srcfiles uses dwarf_get_alloc for strings
1120        so dealloc_macro_srcfiles() here will result in double-dealloc
1121        when dwarf_finish() happens to see the string deallocs
1122        before the macro context dealloc (the context dealloc
1123        will call dealloc_macro_srcfiles() !).
1124
1125        Also see the comment at _dwarf_macro_destructor() here.
1126    */
1127    char ** srcfiles2 = 0;
1128
1129    const char *comp_dir = 0;
1130    const char *comp_name = 0;
1131
1132    /*  ***** BEGIN CODE ***** */
1133    if (error != NULL) {
1134        *error = NULL;
1135    }
1136
1137    CHECK_DIE(die, DW_DLV_ERROR);
1138    cu_context = die->di_cu_context;
1139    dbg = cu_context->cc_dbg;
1140
1141    /*  Doing the load here results in duplication of the
1142        section-load call  (in the by_offset
1143        interface below) but detects the missing section
1144        quickly. */
1145    res = _dwarf_load_section(dbg, &dbg->de_debug_macro,error);
1146    if (res != DW_DLV_OK) {
1147        return res;
1148    }
1149    if (!dbg->de_debug_macro.dss_size) {
1150        return (DW_DLV_NO_ENTRY);
1151    }
1152    resattr = dwarf_attr(die, DW_AT_macros, &macro_attr, error);
1153    if (resattr == DW_DLV_NO_ENTRY) {
1154        resattr = dwarf_attr(die, DW_AT_GNU_macros, &macro_attr, error);
1155    }
1156    if (resattr != DW_DLV_OK) {
1157        return resattr;
1158    }
1159    if (!offset_specified) {
1160        lres = dwarf_global_formref(macro_attr, &macro_offset, error);
1161        if (lres != DW_DLV_OK) {
1162            dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR);
1163            return lres;
1164        }
1165    } else {
1166        macro_offset = offset_in;
1167    }
1168    lres = dwarf_srcfiles(die,&srcfiles,&srcfiles_count, error);
1169    if (lres == DW_DLV_ERROR) {
1170        dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR);
1171        return lres;
1172    }
1173    lres = _dwarf_internal_get_die_comp_dir(die, &comp_dir,
1174        &comp_name,error);
1175    if (lres == DW_DLV_ERROR) {
1176        drop_srcfiles(dbg,srcfiles,srcfiles_count);
1177        srcfiles = 0;
1178        srcfiles_count = 0;
1179        dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR);
1180        srcfiles = 0;
1181        return lres;
1182    }
1183    *macro_unit_offset_out = macro_offset;
1184    /*  We cannot use space allocated by
1185        _dwarf_get_alloc() in the macro_context
1186        we will allocate shortly.
1187        So copy from what we have to a similar data set
1188        but malloc space directly. */
1189
1190    if (srcfiles_count > 0) {
1191        srcfiles2 = (char **) calloc(srcfiles_count, sizeof(char *));
1192        if (!srcfiles2) {
1193            dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR);
1194            drop_srcfiles(dbg,srcfiles,srcfiles_count);
1195            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1196            return (DW_DLV_ERROR);
1197        }
1198        lres  = translate_srcfiles_to_srcfiles2(srcfiles,
1199            srcfiles_count,srcfiles2);
1200        drop_srcfiles(dbg,srcfiles,srcfiles_count);
1201        srcfiles2_count = srcfiles_count;
1202        srcfiles = 0;
1203        srcfiles_count = 0;
1204        if (lres != DW_DLV_OK) {
1205            dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR);
1206            dealloc_macro_srcfiles(srcfiles2, srcfiles2_count);
1207            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1208            return lres;
1209        }
1210    } else {
1211        drop_srcfiles(dbg,srcfiles,srcfiles_count);
1212        srcfiles = 0;
1213        srcfiles_count = 0;
1214    }
1215
1216    dwarf_dealloc(dbg,macro_attr,DW_DLA_ATTR);
1217    /*  NO ENTRY or OK we accept, though NO ENTRY means there
1218        are no source files available. */
1219    lres = _dwarf_internal_macro_context_by_offset(dbg,
1220        macro_offset,version_out,macro_context_out,
1221        macro_ops_count_out,
1222        macro_ops_data_length,
1223        srcfiles2,srcfiles2_count,
1224        comp_dir,
1225        comp_name,
1226        cu_context,
1227        error);
1228    /*  In case of ERROR or NO_ENTRY srcfiles2 is already freed. */
1229    return lres;
1230}
1231
1232static int
1233_dwarf_internal_macro_context_by_offset(Dwarf_Debug dbg,
1234    Dwarf_Unsigned offset,
1235    Dwarf_Unsigned  * version_out,
1236    Dwarf_Macro_Context * macro_context_out,
1237    Dwarf_Unsigned      * macro_ops_count_out,
1238    Dwarf_Unsigned      * macro_ops_data_length,
1239    char **srcfiles,
1240    Dwarf_Signed srcfilescount,
1241    const char *comp_dir,
1242    const char *comp_name,
1243    Dwarf_CU_Context cu_context,
1244    Dwarf_Error * error)
1245{
1246    Dwarf_Unsigned line_table_offset = 0;
1247    Dwarf_Small * macro_header = 0;
1248    Dwarf_Small * macro_data = 0;
1249    Dwarf_Unsigned version = 0;
1250    Dwarf_Unsigned flags = 0;
1251    Dwarf_Small offset_size = 4;
1252    Dwarf_Unsigned cur_offset = 0;
1253    Dwarf_Unsigned section_size = 0;
1254    Dwarf_Small *section_base = 0;
1255    Dwarf_Small *section_end = 0;
1256    Dwarf_Unsigned optablesize = 0;
1257    Dwarf_Unsigned macro_offset = offset;
1258    int res = 0;
1259    Dwarf_Macro_Context macro_context = 0;
1260    Dwarf_Bool build_ops_array = FALSE;
1261
1262    res = _dwarf_load_section(dbg, &dbg->de_debug_macro,error);
1263    if (res != DW_DLV_OK) {
1264        dealloc_macro_srcfiles(srcfiles,srcfilescount);
1265        return res;
1266    }
1267    if (!dbg->de_debug_macro.dss_size) {
1268        dealloc_macro_srcfiles(srcfiles,srcfilescount);
1269        return (DW_DLV_NO_ENTRY);
1270    }
1271
1272    section_base = dbg->de_debug_macro.dss_data;
1273    section_size = dbg->de_debug_macro.dss_size;
1274    /*  The '3'  ensures the header initial bytes present too. */
1275    if ((3+macro_offset) >= section_size) {
1276        dealloc_macro_srcfiles(srcfiles,srcfilescount);
1277        _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
1278        return (DW_DLV_ERROR);
1279    }
1280    macro_header = macro_offset + section_base;
1281    macro_data = macro_header;
1282    section_end = section_base +section_size;
1283
1284
1285    macro_context = (Dwarf_Macro_Context)
1286        _dwarf_get_alloc(dbg,DW_DLA_MACRO_CONTEXT,1);
1287    if (!macro_context) {
1288        dealloc_macro_srcfiles(srcfiles,srcfilescount);
1289        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1290        return DW_DLV_ERROR;
1291    }
1292
1293    if ((section_base + DWARF_HALF_SIZE + sizeof(Dwarf_Small)) >                     section_end ) {
1294        dealloc_macro_srcfiles(srcfiles,srcfilescount);
1295        dwarf_dealloc_macro_context(macro_context);
1296        _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
1297        return DW_DLV_ERROR;
1298    }
1299    /* Note here so if error return we get these freed eventually. */
1300    macro_context->mc_srcfiles = srcfiles;
1301    macro_context->mc_srcfiles_count = srcfilescount;
1302    macro_context->mc_cu_context =  cu_context;
1303
1304    res = _dwarf_read_unaligned_ck_wrapper(dbg,
1305        &version,macro_data,DWARF_HALF_SIZE,section_end,
1306        error);
1307    if (res != DW_DLV_OK) {
1308        dwarf_dealloc_macro_context(macro_context);
1309        return res;
1310    }
1311    macro_data +=  DWARF_HALF_SIZE;
1312    res = _dwarf_read_unaligned_ck_wrapper(dbg,
1313        &flags,macro_data,sizeof(Dwarf_Small),section_end,
1314        error);
1315    if (res != DW_DLV_OK) {
1316        dwarf_dealloc_macro_context(macro_context);
1317        return res;
1318    }
1319    macro_data += sizeof(Dwarf_Small);
1320
1321    macro_context->mc_at_comp_dir = comp_dir;
1322    macro_context->mc_at_name = comp_name;
1323    macro_context->mc_macro_header = macro_header;
1324    macro_context->mc_section_offset = macro_offset;
1325    macro_context->mc_version_number = version;
1326    macro_context->mc_flags = flags;
1327    macro_context->mc_dbg = dbg;
1328    macro_context->mc_offset_size_flag =
1329        flags& MACRO_OFFSET_SIZE_FLAG?TRUE:FALSE;
1330    macro_context->mc_debug_line_offset_flag =
1331        flags& MACRO_LINE_OFFSET_FLAG?TRUE:FALSE;
1332    macro_context->mc_operands_table_flag =
1333        flags& MACRO_OP_TABLE_FLAG?TRUE:FALSE;
1334    offset_size = macro_context->mc_offset_size_flag?8:4;
1335    macro_context->mc_offset_size = offset_size;
1336    if (macro_context->mc_debug_line_offset_flag) {
1337        cur_offset = (offset_size+ macro_data) - section_base;
1338        if (cur_offset >= section_size) {
1339            dwarf_dealloc_macro_context(macro_context);
1340            _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD);
1341            return (DW_DLV_ERROR);
1342        }
1343        res = _dwarf_read_unaligned_ck_wrapper(dbg,
1344            &line_table_offset,macro_data,
1345            offset_size,section_end,
1346            error);
1347        if (res != DW_DLV_OK) {
1348            dwarf_dealloc_macro_context(macro_context);
1349            return res;
1350        }
1351        macro_data += offset_size;
1352        macro_context->mc_debug_line_offset = line_table_offset;
1353    }
1354    if (macro_context->mc_operands_table_flag) {
1355        res = read_operands_table(macro_context,
1356            macro_header,
1357            macro_data,
1358            section_base,
1359            section_size,
1360            &optablesize,
1361            error);
1362        if (res != DW_DLV_OK) {
1363            dwarf_dealloc_macro_context(macro_context);
1364            return res;
1365        }
1366    }
1367
1368    macro_data += optablesize;
1369    macro_context->mc_macro_ops = macro_data;
1370    macro_context->mc_macro_header_length =macro_data - macro_header;
1371
1372    build_ops_array = FALSE;
1373    res = _dwarf_get_macro_ops_count_internal(macro_context,
1374        build_ops_array,
1375        error);
1376    if (res != DW_DLV_OK) {
1377        dwarf_dealloc_macro_context(macro_context);
1378        return res;
1379    }
1380    build_ops_array = TRUE;
1381    res = _dwarf_get_macro_ops_count_internal(macro_context,
1382        build_ops_array,
1383        error);
1384    if (res != DW_DLV_OK) {
1385        dwarf_dealloc_macro_context(macro_context);
1386        return res;
1387    }
1388    *macro_ops_count_out = macro_context->mc_macro_ops_count;
1389    *macro_ops_data_length = macro_context->mc_ops_data_length;
1390    *version_out = version;
1391    *macro_context_out = macro_context;
1392    return DW_DLV_OK;
1393}
1394
1395int dwarf_macro_context_head(Dwarf_Macro_Context head,
1396    Dwarf_Half     * version,
1397    Dwarf_Unsigned * mac_offset,
1398    Dwarf_Unsigned * mac_len,
1399    Dwarf_Unsigned * mac_header_len,
1400    unsigned *       flags,
1401    Dwarf_Bool *     has_line_offset,
1402    Dwarf_Unsigned * line_offset,
1403    Dwarf_Bool *     has_offset_size_64,
1404    Dwarf_Bool *     has_operands_table,
1405    Dwarf_Half *     opcode_count,
1406    Dwarf_Error *error)
1407{
1408    if (!head || head->mc_sentinel != 0xada) {
1409        Dwarf_Debug dbg = 0;
1410        if(head) {
1411            dbg = head->mc_dbg;
1412        }
1413        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER);
1414        return DW_DLV_ERROR;
1415    }
1416    *version = head->mc_version_number;
1417    *mac_offset = head->mc_section_offset;
1418    *mac_len    = head->mc_total_length;
1419    *mac_header_len = head->mc_macro_header_length;
1420    *flags = head->mc_flags;
1421    *line_offset = head->mc_debug_line_offset;
1422    *has_line_offset = head->mc_debug_line_offset_flag;
1423    *has_offset_size_64 = head->mc_offset_size_flag;
1424    *has_operands_table = head->mc_operands_table_flag;
1425    *opcode_count = head->mc_opcode_count;
1426    return DW_DLV_OK;
1427}
1428int dwarf_macro_operands_table(Dwarf_Macro_Context head,
1429    Dwarf_Half  index, /* 0 to opcode_count -1 */
1430    Dwarf_Half  *opcode_number,
1431    Dwarf_Half  *operand_count,
1432    const Dwarf_Small **operand_array,
1433    Dwarf_Error *error)
1434{
1435    struct Dwarf_Macro_Forms_s * ops = 0;
1436    Dwarf_Debug dbg = 0;
1437    if (!head || head->mc_sentinel != 0xada) {
1438        if(head) {
1439            dbg = head->mc_dbg;
1440        }
1441        _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER);
1442        return DW_DLV_ERROR;
1443    }
1444    dbg = head->mc_dbg;
1445    if (index >= head->mc_opcode_count) {
1446        _dwarf_error(dbg, error, DW_DLE_BAD_MACRO_INDEX);
1447        return DW_DLV_ERROR;
1448    }
1449    ops = head->mc_opcode_forms + index;
1450    *opcode_number = ops->mf_code;
1451    *operand_count = ops->mf_formcount;
1452    *operand_array = ops->mf_formbytes;
1453    return DW_DLV_OK;
1454}
1455
1456/*  The base interface to the .debug_macro section data
1457    for a specific CU.
1458
1459    The version number passed back by *version_out
1460    may be 4 (a gnu extension of DWARF)  or 5. */
1461int
1462dwarf_get_macro_context(Dwarf_Die cu_die,
1463    Dwarf_Unsigned      * version_out,
1464    Dwarf_Macro_Context * macro_context,
1465    Dwarf_Unsigned      * macro_unit_offset_out,
1466    Dwarf_Unsigned      * macro_ops_count_out,
1467    Dwarf_Unsigned      * macro_ops_data_length,
1468    Dwarf_Error * error)
1469{
1470    int res = 0;
1471    Dwarf_Bool offset_specified = FALSE;
1472    Dwarf_Unsigned offset = 0;
1473
1474    res =  _dwarf_internal_macro_context(cu_die,
1475        offset_specified,
1476        offset,
1477        version_out,
1478        macro_context,
1479        macro_unit_offset_out,
1480        macro_ops_count_out,
1481        macro_ops_data_length,
1482        error);
1483    return res;
1484}
1485
1486/*  Like  dwarf_get_macro_context but
1487    here we use a specfied offset  instead  of
1488    the offset in the cu_die. */
1489int
1490dwarf_get_macro_context_by_offset(Dwarf_Die cu_die,
1491    Dwarf_Unsigned offset,
1492    Dwarf_Unsigned      * version_out,
1493    Dwarf_Macro_Context * macro_context,
1494    Dwarf_Unsigned      * macro_ops_count_out,
1495    Dwarf_Unsigned      * macro_ops_data_length,
1496    Dwarf_Error * error)
1497{
1498    int res = 0;
1499    Dwarf_Bool offset_specified = TRUE;
1500    Dwarf_Unsigned macro_unit_offset_out = 0;
1501
1502    res = _dwarf_internal_macro_context(cu_die,
1503        offset_specified,
1504        offset,
1505        version_out,
1506        macro_context,
1507        &macro_unit_offset_out,
1508        macro_ops_count_out,
1509        macro_ops_data_length,
1510        error);
1511    return res;
1512}
1513
1514int dwarf_get_macro_section_name(Dwarf_Debug dbg,
1515   const char **sec_name_out,
1516   UNUSEDARG Dwarf_Error *error)
1517{
1518    struct Dwarf_Section_s *sec = 0;
1519
1520    sec = &dbg->de_debug_macro;
1521    if (sec->dss_size == 0) {
1522        /* We don't have such a  section at all. */
1523        return DW_DLV_NO_ENTRY;
1524    }
1525    *sec_name_out = sec->dss_name;
1526    return DW_DLV_OK;
1527}
1528
1529void
1530dwarf_dealloc_macro_context(Dwarf_Macro_Context mc)
1531{
1532    Dwarf_Debug dbg = 0;
1533
1534    if (!mc) {
1535        return;
1536    }
1537    dbg = mc->mc_dbg;
1538    /* See _dwarf_macro_destructor() here */
1539    dwarf_dealloc(dbg,mc,DW_DLA_MACRO_CONTEXT);
1540}
1541
1542int
1543_dwarf_macro_constructor(Dwarf_Debug dbg, void *m)
1544{
1545    /* Nothing to do, the space is zeroed out */
1546    Dwarf_Macro_Context mc= (Dwarf_Macro_Context)m;
1547    /* Arbitrary sentinel. For debugging. */
1548    mc->mc_sentinel = 0xada;
1549    mc->mc_dbg = dbg;
1550    return DW_DLV_OK;
1551}
1552
1553/*  Here we free various fields of Dwarf_Macro_Context.
1554    The fields do not get dealloc'd.
1555    If we had a separate destructor for hand-calling
1556    (meaning when an error is detected during creation
1557    of a  Dwarf_Macro_Context)
1558    and one for calling by dwarf_dealloc() then
1559    we could have the hand-calling dwarf_dealloc the fields
1560    and the one called on the dealloc of a  Dwarf_Macro_Context
1561    could leave the _dwarf_get_alloc() fields for for
1562    normal dwarf_finish() cleanup.
1563
1564    But for now we share this destructor for both purposes
1565    so no fields are _dwarf_get_alloc() and all are free-d
1566    here..
1567*/
1568void
1569_dwarf_macro_destructor(void *m)
1570{
1571    Dwarf_Macro_Context mc= (Dwarf_Macro_Context)m;
1572
1573    dealloc_macro_srcfiles(mc->mc_srcfiles, mc->mc_srcfiles_count);
1574    mc->mc_srcfiles = 0;
1575    mc->mc_srcfiles_count = 0;
1576    free((void *)mc->mc_file_path);
1577    mc->mc_file_path = 0;
1578    free(mc->mc_ops);
1579    mc->mc_ops = 0;
1580    free(mc->mc_opcode_forms);
1581    mc->mc_opcode_forms = 0;
1582    memset(mc,0,sizeof(*mc));
1583    /* Just a recognizable sentinel. For debugging.  No real meaning. */
1584    mc->mc_sentinel = 0xdeadbeef;
1585}
1586