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