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
49 static const Dwarf_Small dwarf_udata_string_form[] = {DW_FORM_udata,DW_FORM_string};
50 static const Dwarf_Small dwarf_udata_udata_form[] = {DW_FORM_udata,DW_FORM_udata};
51 static const Dwarf_Small dwarf_udata_strp_form[] = {DW_FORM_udata,DW_FORM_strp};
52 static const Dwarf_Small dwarf_udata_strp_sup_form[] = {DW_FORM_udata,DW_FORM_strp_sup};
53 static const Dwarf_Small dwarf_secoffset_form[] = {DW_FORM_sec_offset};
54 static const Dwarf_Small dwarf_udata_strx_form[] = {DW_FORM_udata,DW_FORM_strx};
55
56 struct 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 */
79 static const struct Dwarf_Macro_OperationsList_s dwarf_default_macro_opslist = {
80 13, dw5formsarray
81 };
82
83
84 static 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
97 static 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
107 static int
is_std_moperator(Dwarf_Small op)108 is_std_moperator(Dwarf_Small op)
109 {
110 if (op >= 1 && op <= DW_MACRO_undef_strx) {
111 return TRUE;
112 }
113 return FALSE;
114 }
115
116 static int
_dwarf_skim_forms(Dwarf_Debug dbg,Dwarf_Macro_Context mcontext,Dwarf_Small * mdata_start,unsigned formcount,const Dwarf_Small * forms,Dwarf_Small * section_end,Dwarf_Unsigned * forms_length,Dwarf_Error * error)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 */
256 static void
257 dump_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 }
273 Dwarf_Bool
274 is_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. */
296 static int
_dwarf_get_macro_ops_count_internal(Dwarf_Macro_Context macro_context,Dwarf_Bool build_ops_array,Dwarf_Error * error)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
382 int
dwarf_get_macro_op(Dwarf_Macro_Context macro_context,Dwarf_Unsigned op_number,Dwarf_Unsigned * op_start_section_offset,Dwarf_Half * macro_operator,Dwarf_Half * forms_count,const Dwarf_Small ** formcode_array,Dwarf_Error * error)383 dwarf_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. */
427 int
dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context,Dwarf_Unsigned op_number,Dwarf_Unsigned * line_number,Dwarf_Unsigned * index,Dwarf_Unsigned * offset,Dwarf_Half * forms_count,const char ** macro_string,Dwarf_Error * error)428 dwarf_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 / */
630 static void
specialcat(char * targ,char * src,int trimtarg)631 specialcat(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. */
658 static const char *
construct_from_dir_and_name(const char * dir,const char * name)659 construct_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. */
679 static const char *
construct_at_path_from_parts(Dwarf_Macro_Context mc)680 construct_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
701 int
dwarf_get_macro_startend_file(Dwarf_Macro_Context macro_context,Dwarf_Unsigned op_number,Dwarf_Unsigned * line_number,Dwarf_Unsigned * name_index_to_line_tab,const char ** src_file_name,Dwarf_Error * error)702 dwarf_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. */
806 int
dwarf_get_macro_import(Dwarf_Macro_Context macro_context,Dwarf_Unsigned op_number,Dwarf_Unsigned * target_offset,Dwarf_Error * error)807 dwarf_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 /* */
848 static int
valid_macro_form(Dwarf_Half form)849 valid_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
873 static int
validate_opcode(Dwarf_Debug dbg,struct Dwarf_Macro_Forms_s * curform,Dwarf_Error * error)874 validate_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
907 static int
read_operands_table(Dwarf_Macro_Context macro_context,Dwarf_Small * macro_header,Dwarf_Small * macro_data,Dwarf_Small * section_base,Dwarf_Unsigned section_size,Dwarf_Unsigned * table_size_out,Dwarf_Error * error)908 read_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 */
1038 static void
dealloc_macro_srcfiles(char ** srcfiles,Dwarf_Signed srcfiles_count)1039 dealloc_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. */
1057 static int
translate_srcfiles_to_srcfiles2(char ** srcfiles,Dwarf_Signed srcfiles_count,char ** srcfiles2)1058 translate_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
1081 static void
drop_srcfiles(Dwarf_Debug dbg,char ** srcfiles,Dwarf_Signed srcfiles_count)1082 drop_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
1095 static int
_dwarf_internal_macro_context(Dwarf_Die die,Dwarf_Bool offset_specified,Dwarf_Unsigned offset_in,Dwarf_Unsigned * version_out,Dwarf_Macro_Context * macro_context_out,Dwarf_Unsigned * macro_unit_offset_out,Dwarf_Unsigned * macro_ops_count_out,Dwarf_Unsigned * macro_ops_data_length,Dwarf_Error * error)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, ¯o_attr, error);
1153 if (resattr == DW_DLV_NO_ENTRY) {
1154 resattr = dwarf_attr(die, DW_AT_GNU_macros, ¯o_attr, error);
1155 }
1156 if (resattr != DW_DLV_OK) {
1157 return resattr;
1158 }
1159 if (!offset_specified) {
1160 lres = dwarf_global_formref(macro_attr, ¯o_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
1232 static int
_dwarf_internal_macro_context_by_offset(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Unsigned * version_out,Dwarf_Macro_Context * macro_context_out,Dwarf_Unsigned * macro_ops_count_out,Dwarf_Unsigned * macro_ops_data_length,char ** srcfiles,Dwarf_Signed srcfilescount,const char * comp_dir,const char * comp_name,Dwarf_CU_Context cu_context,Dwarf_Error * error)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
dwarf_macro_context_head(Dwarf_Macro_Context head,Dwarf_Half * version,Dwarf_Unsigned * mac_offset,Dwarf_Unsigned * mac_len,Dwarf_Unsigned * mac_header_len,unsigned * flags,Dwarf_Bool * has_line_offset,Dwarf_Unsigned * line_offset,Dwarf_Bool * has_offset_size_64,Dwarf_Bool * has_operands_table,Dwarf_Half * opcode_count,Dwarf_Error * error)1395 int 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 }
dwarf_macro_operands_table(Dwarf_Macro_Context head,Dwarf_Half index,Dwarf_Half * opcode_number,Dwarf_Half * operand_count,const Dwarf_Small ** operand_array,Dwarf_Error * error)1428 int 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. */
1461 int
dwarf_get_macro_context(Dwarf_Die cu_die,Dwarf_Unsigned * version_out,Dwarf_Macro_Context * macro_context,Dwarf_Unsigned * macro_unit_offset_out,Dwarf_Unsigned * macro_ops_count_out,Dwarf_Unsigned * macro_ops_data_length,Dwarf_Error * error)1462 dwarf_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. */
1489 int
dwarf_get_macro_context_by_offset(Dwarf_Die cu_die,Dwarf_Unsigned offset,Dwarf_Unsigned * version_out,Dwarf_Macro_Context * macro_context,Dwarf_Unsigned * macro_ops_count_out,Dwarf_Unsigned * macro_ops_data_length,Dwarf_Error * error)1490 dwarf_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 ¯o_unit_offset_out,
1508 macro_ops_count_out,
1509 macro_ops_data_length,
1510 error);
1511 return res;
1512 }
1513
dwarf_get_macro_section_name(Dwarf_Debug dbg,const char ** sec_name_out,UNUSEDARG Dwarf_Error * error)1514 int 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
1529 void
dwarf_dealloc_macro_context(Dwarf_Macro_Context mc)1530 dwarf_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
1542 int
_dwarf_macro_constructor(Dwarf_Debug dbg,void * m)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 */
1568 void
_dwarf_macro_destructor(void * m)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