Coverage Report

Created: 2023-12-08 06:43

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