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