1 /*
2 Portions Copyright (C) 2017-2019 David Anderson. All Rights Reserved.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of version 2.1 of the GNU Lesser General Public License
6 as published by the Free Software Foundation.
7
8 This program is distributed in the hope that it would be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
12 Further, this software is distributed without any warranty that it is
13 free of the rightful claim of any third person regarding infringement
14 or the like. Any license provided herein, whether implied or
15 otherwise, applies only to this software file. Patent licenses, if
16 any, provided herein do not apply to combinations of this program with
17 other software, or any other product whatsoever.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this program; if not, write the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
22 USA.
23
24 */
25
26 /* This provides access to the DWARF5 .debug_names section. */
27
28 #include "config.h"
29 #include <stdio.h>
30 #ifdef HAVE_STDLIB_H
31 #include <stdlib.h>
32 #endif /* HAVE_STDLIB_H */
33 #include "dwarf_incl.h"
34 #include "dwarf_alloc.h"
35 #include "dwarf_error.h"
36 #include "dwarf_util.h"
37 #include "dwarf_global.h"
38 #include "dwarf_dnames.h"
39 #include "dwarfstring.h"
40
41 #define FALSE 0
42 #define TRUE 1
43
44 /* freedabs attempts to do some cleanup in the face
45 of an error. */
46 static void
freedabs(struct Dwarf_D_Abbrev_s * dab)47 freedabs(struct Dwarf_D_Abbrev_s *dab)
48 {
49 struct Dwarf_D_Abbrev_s *tmp = 0;
50 for(; dab; dab = tmp) {
51 tmp = dab->da_next;
52 free(dab);
53 }
54 }
55
56 /* Encapsulates DECODE_LEB128_UWORD_CK
57 so the caller can free resources
58 in case of problems. */
59 static int
read_uword_ab(Dwarf_Small ** lp,Dwarf_Unsigned * out_p,Dwarf_Debug dbg,Dwarf_Error * err,Dwarf_Small * lpend)60 read_uword_ab(Dwarf_Small **lp,
61 Dwarf_Unsigned *out_p,
62 Dwarf_Debug dbg,
63 Dwarf_Error *err,
64 Dwarf_Small *lpend)
65
66 {
67 Dwarf_Small *inptr = *lp;
68 Dwarf_Unsigned out = 0;
69
70 /* The macro updates inptr */
71 DECODE_LEB128_UWORD_CK(inptr,
72 out, dbg,err,lpend);
73 *lp = inptr;
74 *out_p = out;
75 return DW_DLV_OK;
76 }
77
78
79 static int
fill_in_abbrevs_table(struct Dwarf_Dnames_index_header_s * dn,Dwarf_Error * error)80 fill_in_abbrevs_table(struct Dwarf_Dnames_index_header_s * dn,
81 Dwarf_Error * error)
82 {
83 Dwarf_Small *abdata = dn->din_abbreviations;
84 Dwarf_Unsigned ablen = dn->din_abbrev_table_size;
85 Dwarf_Small *tabend = abdata+ablen;
86 Dwarf_Small *abcur = 0;
87 Dwarf_Unsigned code = 0;
88 Dwarf_Unsigned tag = 0;
89 int foundabend = FALSE;
90 unsigned abcount = 0;
91 struct Dwarf_D_Abbrev_s *firstdab = 0;
92 struct Dwarf_D_Abbrev_s *lastdab = 0;
93 struct Dwarf_D_Abbrev_s *curdab = 0;
94 Dwarf_Debug dbg = dn->din_dbg;
95
96 for (abcur = abdata; abcur < tabend; ) {
97 Dwarf_Unsigned idx = 0;
98 Dwarf_Unsigned form = 0;
99 Dwarf_Small *inner = 0;
100 unsigned idxcount = 0;
101 int res = 0;
102
103 res = read_uword_ab(&abcur,&code,dbg,error,tabend);
104 if (res != DW_DLV_OK) {
105 freedabs(firstdab);
106 return res;
107 }
108 if (code == 0) {
109 foundabend = TRUE;
110 break;
111 }
112
113 res = read_uword_ab(&abcur,&tag,dbg,error,tabend);
114 if (res != DW_DLV_OK) {
115 freedabs(firstdab);
116 return res;
117 }
118 inner = abcur;
119 curdab = (struct Dwarf_D_Abbrev_s *)calloc(1,
120 sizeof(struct Dwarf_D_Abbrev_s));
121 if(!curdab) {
122 freedabs(firstdab);
123 firstdab = 0;
124 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
125 return DW_DLV_ERROR;
126 }
127 curdab->da_tag = tag;
128 curdab->da_abbrev_code = code;
129 abcount++;
130 for(;;) {
131 res = read_uword_ab(&inner,&idx,dbg,error,tabend);
132 if (res != DW_DLV_OK) {
133 free(curdab);
134 freedabs(firstdab);
135 firstdab = 0;
136 return res;
137 }
138 res = read_uword_ab(&inner,&form,dbg,error,tabend);
139 if (res != DW_DLV_OK) {
140 free(curdab);
141 freedabs(firstdab);
142 firstdab = 0;
143 return res;
144 }
145 if (!idx && !form) {
146 break;
147 }
148 if (idxcount >= ABB_PAIRS_MAX) {
149 free(curdab);
150 freedabs(firstdab);
151 firstdab = 0;
152 _dwarf_error(dbg, error,
153 DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW);
154 return DW_DLV_ERROR;
155 }
156 curdab->da_pairs[idxcount].ap_index = idx;
157 curdab->da_pairs[idxcount].ap_form = form;
158 idxcount++;
159 }
160 curdab->da_pairs_count = idxcount;
161 abcur = inner +1;
162 if (!firstdab) {
163 firstdab = curdab;
164 lastdab = curdab;
165 } else {
166 /* Add new on the end, last */
167 lastdab->da_next = curdab;
168 }
169 }
170 if (!foundabend) {
171 freedabs(firstdab);
172 _dwarf_error(dbg, error,
173 DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION);
174 return DW_DLV_OK;
175 }
176 {
177 unsigned ct = 0;
178 struct Dwarf_D_Abbrev_s *tmpa = 0;
179
180 dn->din_abbrev_list = (struct Dwarf_D_Abbrev_s *)calloc(
181 abcount,sizeof(struct Dwarf_D_Abbrev_s));
182 if(!dn->din_abbrev_list) {
183 freedabs(firstdab);
184 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
185 return DW_DLV_ERROR;
186 }
187 dn->din_abbrev_list_count = abcount;
188 tmpa = firstdab;
189 for(ct = 0; tmpa && ct < abcount; ++ct) {
190 struct Dwarf_D_Abbrev_s *tmpb =tmpa->da_next;
191 /* da_next no longer means anything */
192 dn->din_abbrev_list[ct] = *tmpa;
193 dn->din_abbrev_list[ct].da_next = 0;
194 tmpa = tmpb;
195 }
196 freedabs(firstdab);
197 tmpa = 0;
198 firstdab = 0;
199 lastdab = 0;
200 /* Now the list has turned into an array. We can ignore
201 the list aspect. */
202 }
203 return DW_DLV_OK;
204 }
205
206 static int
get_inhdr_cur(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,struct Dwarf_Dnames_index_header_s ** cur,Dwarf_Error * error)207 get_inhdr_cur(Dwarf_Dnames_Head dn,
208 Dwarf_Unsigned index_number,
209 struct Dwarf_Dnames_index_header_s **cur,
210 Dwarf_Error *error)
211 {
212 Dwarf_Debug dbg = 0;
213
214 if (!dn) {
215 _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_NULL_POINTER);
216 return DW_DLV_ERROR;
217 }
218 dbg = dn->dn_dbg;
219 if (index_number >= dn->dn_inhdr_count) {
220 _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG);
221 return DW_DLV_ERROR;
222 }
223 *cur = dn->dn_inhdr_first + index_number;
224 return DW_DLV_OK;
225 }
226
227
228 static int
read_uword_val(Dwarf_Debug dbg,Dwarf_Small ** ptr_in,Dwarf_Small * endptr,int errcode,Dwarf_Unsigned * val_out,Dwarf_Unsigned area_length,Dwarf_Error * error)229 read_uword_val(Dwarf_Debug dbg,
230 Dwarf_Small **ptr_in,
231 Dwarf_Small *endptr,
232 int errcode,
233 Dwarf_Unsigned *val_out,
234 Dwarf_Unsigned area_length,
235 Dwarf_Error *error)
236 {
237 Dwarf_Unsigned val = 0;
238 Dwarf_Small *ptr = *ptr_in;
239
240 READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned,
241 ptr, DWARF_32BIT_SIZE,
242 error,endptr);
243 ptr += DWARF_32BIT_SIZE;
244 if (ptr >= endptr) {
245 _dwarf_error(dbg, error,errcode);
246 return DW_DLV_ERROR;
247 }
248 /* Some of the fields are not length fields, but
249 if non-zero the size will be longer than
250 the value, so we do the following
251 overall sanity check to avoid overflows. */
252 if (val > area_length) {
253 _dwarf_error(dbg, error,errcode);
254 return DW_DLV_ERROR;
255 }
256 *val_out = val;
257 *ptr_in = ptr;
258 return DW_DLV_OK;
259 }
260
261 /* We do not alter the dn data here. */
262 static int
read_a_name_index(Dwarf_Dnames_Head dn,Dwarf_Unsigned section_offset,Dwarf_Small ** curptr_in,Dwarf_Small * end_section,Dwarf_Unsigned remaining_section_size,struct Dwarf_Dnames_index_header_s ** index_header_out,Dwarf_Error * error)263 read_a_name_index(Dwarf_Dnames_Head dn,
264 Dwarf_Unsigned section_offset,
265 Dwarf_Small **curptr_in,
266 Dwarf_Small *end_section,
267 Dwarf_Unsigned remaining_section_size,
268 struct Dwarf_Dnames_index_header_s ** index_header_out,
269 Dwarf_Error *error)
270 {
271 Dwarf_Unsigned area_length = 0;
272 int local_length_size;
273 int local_extension_size = 0;
274 Dwarf_Small *past_length = 0;
275 Dwarf_Small *end_dnames = 0;
276 Dwarf_Half version = 0;
277 Dwarf_Half padding = 0;
278 Dwarf_Unsigned comp_unit_count = 0;
279 Dwarf_Unsigned local_type_unit_count = 0;
280 Dwarf_Unsigned foreign_type_unit_count = 0;
281 Dwarf_Unsigned bucket_count = 0;
282 Dwarf_Unsigned name_count = 0;
283 Dwarf_Unsigned abbrev_table_size = 0; /* bytes */
284 Dwarf_Unsigned augmentation_string_size = 0; /* bytes */
285 int res = 0;
286 const char *str_utf8 = 0;
287 Dwarf_Small *curptr = *curptr_in;
288 struct Dwarf_Dnames_index_header_s *di_header = 0;
289 Dwarf_Debug dbg = dn->dn_dbg;
290
291 READ_AREA_LENGTH_CK(dbg, area_length, Dwarf_Unsigned,
292 curptr, local_length_size,
293 local_extension_size,error,
294 remaining_section_size,end_section);
295
296 /* curptr now points past the length field */
297 past_length = curptr;
298
299 /* Two stage length test so overflow is caught. */
300 if (area_length > remaining_section_size) {
301 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
302 return DW_DLV_ERROR;
303 }
304 if ((area_length + local_length_size + local_extension_size) >
305 remaining_section_size) {
306 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
307 return DW_DLV_ERROR;
308 }
309 end_dnames = curptr + area_length;
310
311 READ_UNALIGNED_CK(dbg, version, Dwarf_Half,
312 curptr, DWARF_HALF_SIZE,
313 error,end_dnames);
314 curptr += DWARF_HALF_SIZE;
315 if (curptr >= end_dnames) {
316 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
317 return DW_DLV_ERROR;
318 }
319 if (version != DWARF_DNAMES_VERSION5) {
320 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
321 return (DW_DLV_ERROR);
322 }
323 READ_UNALIGNED_CK(dbg, padding, Dwarf_Half,
324 curptr, DWARF_HALF_SIZE,
325 error,end_dnames);
326 curptr += DWARF_HALF_SIZE;
327 if (curptr >= end_dnames) {
328 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
329 return DW_DLV_ERROR;
330 }
331 if (padding) {
332 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
333 return (DW_DLV_ERROR);
334 }
335 res = read_uword_val(dbg, &curptr,
336 end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
337 &comp_unit_count,area_length,error);
338 if (res != DW_DLV_OK) {
339 return res;
340 }
341 res = read_uword_val(dbg, &curptr,
342 end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
343 &local_type_unit_count,area_length,error);
344 if (res != DW_DLV_OK) {
345 return res;
346 }
347 res = read_uword_val(dbg, &curptr,
348 end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
349 &foreign_type_unit_count,area_length,error);
350 if (res != DW_DLV_OK) {
351 return res;
352 }
353 res = read_uword_val(dbg, &curptr,
354 end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
355 &bucket_count,area_length,error);
356 if (res != DW_DLV_OK) {
357 return res;
358 }
359 res = read_uword_val(dbg, &curptr,
360 end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
361 &name_count,area_length,error);
362 if (res != DW_DLV_OK) {
363 return res;
364 }
365
366 res = read_uword_val(dbg, &curptr,
367 end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
368 &abbrev_table_size,area_length,error);
369 if (res != DW_DLV_OK) {
370 return res;
371 }
372 res = read_uword_val(dbg, &curptr,
373 end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
374 &augmentation_string_size,area_length,error);
375 if (res != DW_DLV_OK) {
376 return res;
377 }
378
379 str_utf8 = (const char *) curptr;
380
381 curptr+= augmentation_string_size;
382 if (curptr >= end_dnames) {
383 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
384 return DW_DLV_ERROR;
385 }
386
387 di_header = (struct Dwarf_Dnames_index_header_s *)
388 calloc(1,sizeof(*di_header));
389 if(!di_header) {
390 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
391 return (DW_DLV_ERROR);
392 }
393
394 di_header->din_dbg = dbg;
395 di_header->din_section_offset = section_offset;
396 di_header->din_indextable_data = past_length;
397 di_header->din_indextable_length = area_length;
398 di_header->din_version = version;
399 di_header->din_comp_unit_count = comp_unit_count;
400 di_header->din_local_type_unit_count = local_type_unit_count ;
401 di_header->din_foreign_type_unit_count = foreign_type_unit_count ;
402 di_header->din_bucket_count = bucket_count ;
403 di_header->din_name_count = name_count ;
404 di_header->din_abbrev_table_size = abbrev_table_size;
405 di_header->din_augmentation_string_size = augmentation_string_size;
406 di_header->din_augmentation_string = calloc(1,
407 augmentation_string_size +1);
408 strncpy(di_header->din_augmentation_string,str_utf8,
409 augmentation_string_size);
410
411 {
412 /* This deals with a zero length string too. */
413 Dwarf_Unsigned len = augmentation_string_size;
414 char *cp = 0;
415 char *cpend = 0;
416 Dwarf_Bool foundnull = FALSE;
417
418 cp = di_header->din_augmentation_string;
419 cpend = cp + len;
420 for( ; cp<cpend; ++cp) {
421 if (!*cp) {
422 foundnull = TRUE;
423 break;
424 }
425 }
426 if (!foundnull) {
427 /* Force a NUL terminator in the extra byte
428 we calloc-d. */
429 cp[len] = 0;
430 } else {
431 /* Ensure that there is no corruption in
432 the padding. */
433 for( ; cp < cpend; ++cp) {
434 if(*cp) {
435 free(di_header);
436 _dwarf_error(dbg, error,
437 DW_DLE_DEBUG_NAMES_PAD_NON_ZERO);
438 return DW_DLV_ERROR;
439 }
440 }
441 }
442 }
443 di_header->din_cu_list = curptr;
444 curptr += dbg->de_length_size * comp_unit_count;
445 if(curptr > end_dnames) {
446 free(di_header->din_augmentation_string);
447 free(di_header);
448 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
449 return DW_DLV_ERROR;
450 }
451 di_header->din_local_tu_list = curptr;
452
453 curptr += dbg->de_length_size * local_type_unit_count;
454 if(curptr > end_dnames) {
455 free(di_header->din_augmentation_string);
456 free(di_header);
457 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
458 return DW_DLV_ERROR;
459 }
460 di_header->din_foreign_tu_list = curptr;
461 curptr += sizeof(Dwarf_Sig8) * foreign_type_unit_count;
462 if(curptr > end_dnames) {
463 free(di_header->din_augmentation_string);
464 free(di_header);
465 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
466 return DW_DLV_ERROR;
467 }
468
469 di_header->din_buckets = curptr;
470 curptr += DWARF_32BIT_SIZE * bucket_count;
471 if(curptr > end_dnames) {
472 free(di_header->din_augmentation_string);
473 free(di_header);
474 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
475 return DW_DLV_ERROR;
476 }
477
478 di_header->din_hash_table = curptr;
479 curptr += sizeof(Dwarf_Sig8) * name_count;
480 if(curptr > end_dnames) {
481 free(di_header->din_augmentation_string);
482 free(di_header);
483 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
484 return DW_DLV_ERROR;
485 }
486
487 di_header->din_string_offsets = curptr;
488 curptr += DWARF_32BIT_SIZE * name_count;
489 if(curptr > end_dnames) {
490 free(di_header->din_augmentation_string);
491 free(di_header);
492 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
493 return DW_DLV_ERROR;
494 }
495
496 di_header->din_entry_offsets = curptr;
497 curptr += DWARF_32BIT_SIZE * name_count;
498 if(curptr > end_dnames) {
499 free(di_header->din_augmentation_string);
500 free(di_header);
501 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
502 return DW_DLV_ERROR;
503 }
504 di_header->din_abbreviations = curptr;
505 curptr += abbrev_table_size;
506 if(curptr > end_dnames) {
507 free(di_header->din_augmentation_string);
508 free(di_header);
509 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
510 return DW_DLV_ERROR;
511 }
512
513 di_header->din_entry_pool = curptr;
514 di_header->din_offset_size = local_length_size;
515
516 di_header->din_entry_pool_size = end_dnames - curptr;
517
518 *curptr_in = curptr;
519 *index_header_out = di_header;
520 res = fill_in_abbrevs_table(di_header,error);
521 if (res != DW_DLV_OK) {
522 free(di_header->din_augmentation_string);
523 free(di_header);
524 return res;
525 }
526 return DW_DLV_OK;
527 }
528
529 #define FAKE_LAST_USED 0xffffffff
530
531 static void
free_inhdr_content(struct Dwarf_Dnames_index_header_s * f)532 free_inhdr_content(struct Dwarf_Dnames_index_header_s *f)
533 {
534 free(f->din_augmentation_string);
535 free(f->din_abbrev_list);
536 }
537 static void
free_inhdr_list(struct Dwarf_Dnames_index_header_s * f)538 free_inhdr_list(struct Dwarf_Dnames_index_header_s *f)
539 {
540 struct Dwarf_Dnames_index_header_s *tmp = 0;
541
542 for( ; f ; f = tmp) {
543 tmp = f->din_next;
544 free_inhdr_content(f);
545 free(f);
546 }
547 }
548
549 /* There may be one debug index for an entire object file,
550 for multiple CUs or there can be individual indexes
551 for some CUs.
552 see DWARF5 6.1.1.3 Per_CU versus Per-Module Indexes. */
553 int
dwarf_debugnames_header(Dwarf_Debug dbg,Dwarf_Dnames_Head * dn_out,Dwarf_Unsigned * dn_count_out,Dwarf_Error * error)554 dwarf_debugnames_header(Dwarf_Debug dbg,
555 Dwarf_Dnames_Head * dn_out,
556 Dwarf_Unsigned * dn_count_out,
557 Dwarf_Error *error)
558 {
559 Dwarf_Unsigned remaining = 0;
560 Dwarf_Dnames_Head dn_header = 0;
561 Dwarf_Unsigned section_size;
562 Dwarf_Small *start_section = 0;
563 Dwarf_Small *end_section = 0;
564 Dwarf_Small *curptr = 0;
565 struct Dwarf_Dnames_index_header_s *inhdr_last = 0;
566 struct Dwarf_Dnames_index_header_s *inhdr_first = 0;
567 unsigned inhdr_count = 0;
568 int res = 0;
569
570 if(!dbg) {
571 _dwarf_error(dbg, error,DW_DLE_DBG_NULL);
572 return DW_DLV_ERROR;
573 }
574
575 res = _dwarf_load_section(dbg, &dbg->de_debug_names, error);
576 if (res != DW_DLV_OK) {
577 return res;
578 }
579
580 section_size = dbg->de_debug_names.dss_size;
581 if(!section_size){
582 return DW_DLV_NO_ENTRY;
583 }
584 start_section = dbg->de_debug_names.dss_data;
585 curptr = start_section;
586 end_section = start_section + section_size;
587 remaining = section_size;
588 dn_header = (Dwarf_Dnames_Head)_dwarf_get_alloc(dbg,
589 DW_DLA_DNAMES_HEAD, 1);
590 if(!dn_header) {
591 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
592 return DW_DLV_ERROR;
593 }
594 dn_header->dn_section_data = start_section;
595 dn_header->dn_section_size = section_size;
596 dn_header->dn_section_end = start_section + section_size;
597 dn_header->dn_dbg = dbg;
598 for( ; curptr < end_section; ) {
599 struct Dwarf_Dnames_index_header_s * index_header = 0;
600 Dwarf_Small *curptr_start = curptr;
601 Dwarf_Unsigned usedspace = 0;
602 Dwarf_Unsigned section_offset = curptr - start_section;
603
604 res = read_a_name_index(dn_header,
605 section_offset,
606 &curptr,
607 end_section,
608 remaining,
609 &index_header,
610 error);
611 if (res == DW_DLV_ERROR) {
612 free_inhdr_list(inhdr_first);
613 dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD);
614 return res;
615 }
616 if (res == DW_DLV_NO_ENTRY) {
617 /* Impossible. A bug. Or possibly
618 a bunch of zero pad? */
619 free_inhdr_list(inhdr_first);
620 dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD);
621 break;
622 }
623 /* Add the new one to the list. */
624 if(!inhdr_first) {
625 inhdr_count = 1;
626 inhdr_first = index_header;
627 inhdr_last = index_header;
628 } else {
629 struct Dwarf_Dnames_index_header_s *tmp = inhdr_last;
630 inhdr_last = index_header;
631 tmp->din_next = index_header;
632 inhdr_count++;
633 }
634 usedspace = curptr - curptr_start;
635 remaining -= - usedspace;
636 if (remaining < 5) {
637 /* No more in here, just padding. Check for zero
638 in padding. */
639 if ((curptr +remaining) < end_section) {
640 free_inhdr_list(inhdr_first);
641 dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD);
642 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_OFF_END);
643 return DW_DLV_ERROR;
644 }
645 for ( ; curptr < end_section; ++curptr) {
646 if(*curptr) {
647 /* One could argue this is a harmless error,
648 but for now assume it is real corruption. */
649 free_inhdr_list(inhdr_first);
650 dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD);
651 _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_PAD_NON_ZERO);
652 return DW_DLV_ERROR;
653 }
654 }
655 }
656 }
657 {
658 struct Dwarf_Dnames_index_header_s *cur = 0;
659 int n = 0;
660
661 dn_header->dn_inhdr_first =
662 (struct Dwarf_Dnames_index_header_s *)
663 calloc(inhdr_count,sizeof(struct Dwarf_Dnames_index_header_s));
664 for(n = 0,cur = inhdr_first; cur; ++n ) {
665 /* We are copying these structs so do not
666 free them at this time. */
667 struct Dwarf_Dnames_index_header_s *tmp = cur->din_next;
668 dn_header->dn_inhdr_first[n] = *cur;
669 cur = tmp;
670 }
671 }
672 *dn_out = dn_header;
673 *dn_count_out = inhdr_count;
674 return DW_DLV_OK;
675 }
676
677
dwarf_debugnames_sizes(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned * section_offset,Dwarf_Unsigned * version,Dwarf_Unsigned * offset_size,Dwarf_Unsigned * comp_unit_count,Dwarf_Unsigned * local_type_unit_count,Dwarf_Unsigned * foreign_type_unit_count,Dwarf_Unsigned * bucket_count,Dwarf_Unsigned * name_count,Dwarf_Unsigned * indextable_overall_length,Dwarf_Unsigned * abbrev_table_size,Dwarf_Unsigned * entry_pool_size,Dwarf_Unsigned * augmentation_string_size,Dwarf_Error * error)678 int dwarf_debugnames_sizes(Dwarf_Dnames_Head dn,
679 Dwarf_Unsigned index_number,
680
681 Dwarf_Unsigned * section_offset,
682 Dwarf_Unsigned * version, /* 5 */
683 Dwarf_Unsigned * offset_size, /* 4 or 8 */
684
685 /* The counts are entry counts, not bye sizes. */
686 Dwarf_Unsigned * comp_unit_count,
687 Dwarf_Unsigned * local_type_unit_count,
688 Dwarf_Unsigned * foreign_type_unit_count,
689 Dwarf_Unsigned * bucket_count,
690 Dwarf_Unsigned * name_count,
691
692 /* The following are counted in bytes */
693 Dwarf_Unsigned * indextable_overall_length,
694 Dwarf_Unsigned * abbrev_table_size,
695 Dwarf_Unsigned * entry_pool_size,
696 Dwarf_Unsigned * augmentation_string_size,
697
698 Dwarf_Error * error)
699 {
700 struct Dwarf_Dnames_index_header_s *cur = 0;
701 int res = 0;
702
703 res = get_inhdr_cur(dn,index_number,&cur,error);
704 if(res != DW_DLV_OK) {
705 return res;
706 }
707
708 if (section_offset) {
709 *section_offset = cur->din_section_offset;
710 }
711 if (version) {
712 *version = cur->din_version;
713 }
714 if (offset_size) {
715 *offset_size = cur->din_offset_size;
716 }
717 if (comp_unit_count) {
718 *comp_unit_count = cur->din_comp_unit_count;
719 }
720 if (local_type_unit_count) {
721 *local_type_unit_count = cur->din_local_type_unit_count;
722 }
723 if (foreign_type_unit_count) {
724 *foreign_type_unit_count = cur->din_foreign_type_unit_count;
725 }
726 if (bucket_count) {
727 *bucket_count = cur->din_bucket_count;
728 }
729 if (name_count) {
730 *name_count = cur->din_name_count;
731 }
732 if (abbrev_table_size) {
733 *abbrev_table_size = cur->din_abbrev_table_size;
734 }
735 if (entry_pool_size) {
736 *entry_pool_size = cur->din_entry_pool_size;
737 }
738 if (augmentation_string_size) {
739 *augmentation_string_size = cur->din_augmentation_string_size;
740 }
741 if (indextable_overall_length) {
742 *indextable_overall_length = cur->din_indextable_length;
743 }
744 return DW_DLV_OK;
745 }
746
747 int
dwarf_debugnames_cu_entry(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned offset_number,Dwarf_Unsigned * offset_count,Dwarf_Unsigned * offset,Dwarf_Error * error)748 dwarf_debugnames_cu_entry(Dwarf_Dnames_Head dn,
749 Dwarf_Unsigned index_number,
750 Dwarf_Unsigned offset_number,
751 Dwarf_Unsigned * offset_count,
752 Dwarf_Unsigned * offset,
753 Dwarf_Error * error)
754 {
755 struct Dwarf_Dnames_index_header_s *cur = 0;
756 Dwarf_Debug dbg = 0;
757 int res;
758
759 res = get_inhdr_cur(dn,index_number,&cur,error);
760 if (res != DW_DLV_OK) {
761 return res;
762 }
763 dbg = dn->dn_dbg;
764
765 if (offset_number >= cur->din_comp_unit_count) {
766 if (offset_count) {
767 *offset_count = cur->din_comp_unit_count;
768 }
769 return DW_DLV_NO_ENTRY;
770 }
771
772
773 if (offset) {
774 Dwarf_Unsigned offsetval = 0;
775 Dwarf_Small *ptr = cur->din_cu_list +
776 offset_number *cur->din_offset_size;
777 Dwarf_Small *endptr = cur->din_local_tu_list;
778
779 READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
780 ptr, cur->din_offset_size,
781 error,endptr);
782 *offset = offsetval;
783 }
784 if (offset_count) {
785 *offset_count = cur->din_comp_unit_count;
786 }
787 return DW_DLV_OK;
788 }
789
790 int
dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned offset_number,Dwarf_Unsigned * offset_count,Dwarf_Unsigned * offset,Dwarf_Error * error)791 dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head dn,
792 Dwarf_Unsigned index_number,
793 Dwarf_Unsigned offset_number,
794 Dwarf_Unsigned * offset_count,
795 Dwarf_Unsigned * offset,
796 Dwarf_Error * error)
797 {
798 struct Dwarf_Dnames_index_header_s *cur = 0;
799 Dwarf_Debug dbg = 0;
800 int res;
801
802 res = get_inhdr_cur(dn,index_number,&cur,error);
803 if (res != DW_DLV_OK) {
804 return res;
805 }
806 dbg = dn->dn_dbg;
807
808 if (offset_number >= cur->din_local_type_unit_count) {
809 if (offset_count) {
810 *offset_count = cur->din_local_type_unit_count;
811 }
812 return DW_DLV_NO_ENTRY;
813 }
814
815
816 if (offset) {
817 Dwarf_Unsigned offsetval = 0;
818 Dwarf_Small *ptr = cur->din_local_tu_list +
819 offset_number *cur->din_offset_size;
820 Dwarf_Small *endptr = cur->din_foreign_tu_list;
821
822 READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
823 ptr, cur->din_offset_size,
824 error,endptr);
825 *offset = offsetval;
826 }
827 if (offset_count) {
828 *offset_count = cur->din_local_type_unit_count;
829 }
830 return DW_DLV_OK;
831 }
832
833
834
835 /* Here the sig_number ranges from
836 local_type_unit_count to
837 local_type_unit_count+foreign_type_unit_count-1
838 because the foreign indices are a continuation
839 of the local tu indices.
840 */
841 int
dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned sig_number,Dwarf_Unsigned * sig_minimum,Dwarf_Unsigned * sig_count,Dwarf_Sig8 * signature,Dwarf_Error * error)842 dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head dn,
843 Dwarf_Unsigned index_number,
844 Dwarf_Unsigned sig_number,
845
846 /* these index starting at local_type_unit_count */
847 Dwarf_Unsigned * sig_minimum,
848 Dwarf_Unsigned * sig_count,
849 Dwarf_Sig8 * signature,
850 Dwarf_Error * error)
851 {
852 struct Dwarf_Dnames_index_header_s *cur = 0;
853 Dwarf_Debug dbg = 0;
854 int res;
855 unsigned legal_low = 0;
856 unsigned legal_high = 0;
857
858 res = get_inhdr_cur(dn,index_number,&cur,error);
859 if (res != DW_DLV_OK) {
860 return res;
861 }
862 dbg = dn->dn_dbg;
863 legal_low = cur->din_local_type_unit_count;
864 legal_high = legal_low + cur->din_foreign_type_unit_count;
865 if (sig_number < legal_low) {
866 _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG);
867 return DW_DLV_ERROR;
868 }
869 if (sig_number >= legal_high) {
870 if (sig_minimum) {
871 *sig_minimum = legal_low;
872 }
873 if (sig_count) {
874 *sig_count = cur->din_foreign_type_unit_count;
875 }
876 return DW_DLV_NO_ENTRY;
877 }
878
879 if (signature) {
880 Dwarf_Small *ptr = cur->din_foreign_tu_list +
881 sig_number *cur->din_offset_size;
882 Dwarf_Small *endptr = cur->din_hash_table;
883 if((ptr +sizeof(Dwarf_Sig8)) > endptr) {
884 _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG);
885 return DW_DLV_ERROR;
886 }
887 memcpy(signature,ptr,sizeof(Dwarf_Sig8));
888 }
889 if (sig_minimum) {
890 *sig_minimum = legal_low;
891 }
892 if (sig_count) {
893 *sig_count = cur->din_foreign_type_unit_count;
894 }
895 return DW_DLV_OK;
896 }
897
898 /* The hash table is composed of the buckets table
899 and the hashes table.
900 If there is no buckets table (bucket_count == 0)
901 the hashes part still exists. */
dwarf_debugnames_bucket(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned bucket_number,Dwarf_Unsigned * bucket_count,Dwarf_Unsigned * index_of_name_entry,Dwarf_Error * error)902 int dwarf_debugnames_bucket(Dwarf_Dnames_Head dn,
903 Dwarf_Unsigned index_number,
904 Dwarf_Unsigned bucket_number,
905 Dwarf_Unsigned * bucket_count,
906 Dwarf_Unsigned * index_of_name_entry,
907 Dwarf_Error * error)
908 {
909 struct Dwarf_Dnames_index_header_s *cur = 0;
910 Dwarf_Debug dbg = 0;
911 int res;
912
913 res = get_inhdr_cur(dn,index_number,&cur,error);
914 if (res != DW_DLV_OK) {
915 return res;
916 }
917 dbg = dn->dn_dbg;
918
919 if (bucket_number >= cur->din_bucket_count) {
920 if (bucket_count) {
921 *bucket_count = cur->din_bucket_count;
922 }
923 return DW_DLV_NO_ENTRY;
924 }
925
926 if (index_of_name_entry) {
927 Dwarf_Unsigned offsetval = 0;
928 Dwarf_Small *ptr = cur->din_buckets +
929 bucket_number * DWARF_32BIT_SIZE;
930 Dwarf_Small *endptr = cur->din_hash_table;
931
932 READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
933 ptr, DWARF_32BIT_SIZE,
934 error,endptr);
935 *index_of_name_entry = offsetval;
936 }
937 if (bucket_count) {
938 *bucket_count = cur->din_bucket_count;
939 }
940 return DW_DLV_OK;
941 }
942
943 /* Access to the .debug_names name table. */
944 int
dwarf_debugnames_name(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned name_entry,Dwarf_Unsigned * names_count,Dwarf_Sig8 * signature,Dwarf_Unsigned * offset_to_debug_str,Dwarf_Unsigned * offset_in_entrypool,Dwarf_Error * error)945 dwarf_debugnames_name(Dwarf_Dnames_Head dn,
946 Dwarf_Unsigned index_number,
947 Dwarf_Unsigned name_entry,
948 Dwarf_Unsigned * names_count,
949 Dwarf_Sig8 * signature,
950 Dwarf_Unsigned * offset_to_debug_str,
951 Dwarf_Unsigned * offset_in_entrypool,
952 Dwarf_Error * error)
953
954 {
955 struct Dwarf_Dnames_index_header_s *cur = 0;
956 Dwarf_Debug dbg = 0;
957 int res;
958
959 res = get_inhdr_cur(dn,index_number,&cur,error);
960 if (res != DW_DLV_OK) {
961 return res;
962 }
963 dbg = dn->dn_dbg;
964
965 if (name_entry >= cur->din_name_count) {
966 if (names_count) {
967 *names_count = cur->din_bucket_count;
968 }
969 return DW_DLV_NO_ENTRY;
970 }
971
972 if (signature) {
973 Dwarf_Small *ptr = cur->din_hash_table +
974 name_entry *sizeof(Dwarf_Sig8);
975 Dwarf_Small *endptr = cur->din_string_offsets;
976 if ((ptr + sizeof(Dwarf_Sig8)) > endptr) {
977 _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG);
978 return DW_DLV_ERROR;
979 }
980 memcpy(signature,ptr,sizeof(Dwarf_Sig8));
981 }
982
983 if (offset_to_debug_str) {
984 Dwarf_Unsigned offsetval = 0;
985 Dwarf_Small *ptr = cur->din_string_offsets +
986 name_entry * DWARF_32BIT_SIZE;
987 Dwarf_Small *endptr = cur->din_abbreviations;
988
989 READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
990 ptr, DWARF_32BIT_SIZE,
991 error,endptr);
992 *offset_to_debug_str = offsetval;
993 }
994 if (offset_in_entrypool) {
995 Dwarf_Unsigned offsetval = 0;
996 Dwarf_Small *ptr = cur->din_entry_offsets +
997 name_entry * DWARF_32BIT_SIZE;
998 Dwarf_Small *endptr = cur->din_abbreviations;
999
1000 READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
1001 ptr, DWARF_32BIT_SIZE,
1002 error,endptr);
1003 *offset_in_entrypool = offsetval;
1004 }
1005
1006 if (names_count) {
1007 *names_count = cur->din_name_count;
1008 }
1009 return DW_DLV_OK;
1010 }
1011
1012
1013
1014
1015
1016
1017 /* If abbrev_code returned is zero there is no tag returned
1018 and we are at the end of the entry pool set for this name
1019 entry.
1020 abbrev code, tag
1021 nameindexattr,form
1022 ...
1023 0,0
1024 ... repeat like the above
1025 0
1026 */
1027
1028 /* This provides a way to print the abbrev table by
1029 indexing from 0. */
1030 int
dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned abbrev_entry,Dwarf_Unsigned * abbrev_code,Dwarf_Unsigned * tag,Dwarf_Unsigned * number_of_abbrev,Dwarf_Unsigned * number_of_attr_form_entries,Dwarf_Error * error)1031 dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head dn,
1032 Dwarf_Unsigned index_number,
1033 Dwarf_Unsigned abbrev_entry,
1034 Dwarf_Unsigned * abbrev_code,
1035 Dwarf_Unsigned * tag,
1036
1037 /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1
1038 */
1039 Dwarf_Unsigned * number_of_abbrev,
1040
1041 /* The number of attr/form pairs, not counting the trailing
1042 0,0 pair. */
1043 Dwarf_Unsigned * number_of_attr_form_entries,
1044 Dwarf_Error *error)
1045 {
1046 struct Dwarf_Dnames_index_header_s *cur = 0;
1047 struct Dwarf_D_Abbrev_s * abbrev = 0;
1048 int res = 0;
1049
1050 res = get_inhdr_cur(dn,index_number,&cur,error);
1051 if (res != DW_DLV_OK) {
1052 return res;
1053 }
1054
1055 if (abbrev_entry >= cur->din_abbrev_list_count) {
1056 if (number_of_abbrev) {
1057 *number_of_abbrev = cur->din_abbrev_list_count;
1058 }
1059 return DW_DLV_NO_ENTRY;
1060 }
1061 abbrev = cur->din_abbrev_list + abbrev_entry;
1062 if(abbrev_code) {
1063 *abbrev_code = abbrev->da_abbrev_code;
1064 }
1065 if(tag) {
1066 *tag = abbrev->da_tag;
1067 }
1068 if(number_of_abbrev) {
1069 *number_of_abbrev = cur->din_abbrev_list_count;
1070 }
1071 if(number_of_attr_form_entries) {
1072 *number_of_attr_form_entries = abbrev->da_pairs_count;
1073 }
1074 return DW_DLV_OK;
1075 }
1076
1077 static int
_dwarf_internal_abbrev_by_code(struct Dwarf_Dnames_index_header_s * cur,Dwarf_Unsigned abbrev_code,Dwarf_Unsigned * tag,Dwarf_Unsigned * index_of_abbrev,Dwarf_Unsigned * number_of_attr_form_entries)1078 _dwarf_internal_abbrev_by_code(struct Dwarf_Dnames_index_header_s *cur,
1079 Dwarf_Unsigned abbrev_code,
1080 Dwarf_Unsigned * tag,
1081 Dwarf_Unsigned * index_of_abbrev,
1082 Dwarf_Unsigned * number_of_attr_form_entries)
1083 {
1084 unsigned n = 0;
1085 struct Dwarf_D_Abbrev_s * abbrev = 0;
1086
1087 abbrev = cur->din_abbrev_list;
1088 for(n = 0; n < cur->din_abbrev_list_count; ++n,++abbrev) {
1089 if (abbrev_code == abbrev->da_abbrev_code) {
1090 if (tag) {
1091 *tag = abbrev->da_tag;
1092 }
1093 if (index_of_abbrev) {
1094 *index_of_abbrev = n;
1095 }
1096 if (number_of_attr_form_entries) {
1097 *number_of_attr_form_entries = abbrev->da_pairs_count;
1098 }
1099 return DW_DLV_OK;
1100 }
1101 }
1102 /* Something is wrong, not found! */
1103 return DW_DLV_NO_ENTRY;
1104
1105 }
1106
1107 /* Access the abbrev by abbrev code (instead of index). */
1108 int
dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned abbrev_code,Dwarf_Unsigned * tag,Dwarf_Unsigned * index_of_abbrev,Dwarf_Unsigned * number_of_attr_form_entries,Dwarf_Error * error)1109 dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head dn,
1110 Dwarf_Unsigned index_number,
1111 Dwarf_Unsigned abbrev_code,
1112 Dwarf_Unsigned * tag,
1113
1114 /* The number of this code/tag as an array index. */
1115 Dwarf_Unsigned * index_of_abbrev,
1116
1117 /* The number of attr/form pairs, not counting the trailing
1118 0,0 pair. */
1119 Dwarf_Unsigned * number_of_attr_form_entries,
1120 Dwarf_Error * error)
1121 {
1122 struct Dwarf_Dnames_index_header_s *cur = 0;
1123 int res;
1124
1125 res = get_inhdr_cur(dn,index_number,&cur,error);
1126 if (res != DW_DLV_OK) {
1127 return res;
1128 }
1129 res = _dwarf_internal_abbrev_by_code(cur,
1130 abbrev_code,
1131 tag, index_of_abbrev,
1132 number_of_attr_form_entries);
1133 return res;
1134 }
1135
1136
1137 int
dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned abbrev_entry_index,Dwarf_Unsigned abbrev_form_index,Dwarf_Unsigned * name_index_attr,Dwarf_Unsigned * form,Dwarf_Unsigned * number_of_attr_form_entries,Dwarf_Error * error)1138 dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head dn,
1139 Dwarf_Unsigned index_number,
1140 Dwarf_Unsigned abbrev_entry_index,
1141 Dwarf_Unsigned abbrev_form_index,
1142 Dwarf_Unsigned * name_index_attr,
1143 Dwarf_Unsigned * form,
1144 Dwarf_Unsigned * number_of_attr_form_entries,
1145 Dwarf_Error * error)
1146 {
1147 struct Dwarf_Dnames_index_header_s *cur = 0;
1148 struct Dwarf_D_Abbrev_s * abbrev = 0;
1149 struct abbrev_pair_s *ap = 0;
1150 int res;
1151
1152 res = get_inhdr_cur(dn,index_number,&cur,error);
1153 if (res != DW_DLV_OK) {
1154 return res;
1155 }
1156
1157 if (abbrev_entry_index >= cur->din_abbrev_list_count) {
1158 if (number_of_attr_form_entries) {
1159 *number_of_attr_form_entries = cur->din_bucket_count;
1160 }
1161 return DW_DLV_NO_ENTRY;
1162 }
1163 abbrev = cur->din_abbrev_list + abbrev_entry_index;
1164 if (abbrev_form_index >= abbrev->da_pairs_count) {
1165 return DW_DLV_NO_ENTRY;
1166 }
1167 ap = abbrev->da_pairs + abbrev_entry_index;
1168 if(name_index_attr) {
1169 *name_index_attr = ap->ap_index;
1170 }
1171 if(form) {
1172 *form = ap->ap_form;
1173 }
1174 if(number_of_attr_form_entries) {
1175 *number_of_attr_form_entries = abbrev->da_pairs_count;
1176 }
1177 return DW_DLV_OK;
1178 }
1179
1180 /* This, combined with dwarf_debugnames_entrypool_values(),
1181 lets one examine as much or as little of an entrypool
1182 as one wants to by alternately calling these two
1183 functions. */
1184
dwarf_debugnames_entrypool(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned offset_in_entrypool,Dwarf_Unsigned * abbrev_code,Dwarf_Unsigned * tag,Dwarf_Unsigned * value_count,Dwarf_Unsigned * index_of_abbrev,Dwarf_Unsigned * offset_of_initial_value,Dwarf_Error * error)1185 int dwarf_debugnames_entrypool(Dwarf_Dnames_Head dn,
1186 Dwarf_Unsigned index_number,
1187 Dwarf_Unsigned offset_in_entrypool,
1188 Dwarf_Unsigned * abbrev_code,
1189 Dwarf_Unsigned * tag,
1190 Dwarf_Unsigned * value_count,
1191 Dwarf_Unsigned * index_of_abbrev,
1192 Dwarf_Unsigned * offset_of_initial_value,
1193 Dwarf_Error * error)
1194 {
1195 struct Dwarf_Dnames_index_header_s *cur = 0;
1196 Dwarf_Debug dbg = 0;
1197 int res = 0;
1198 Dwarf_Small *entrypool = 0;
1199 Dwarf_Small *endentrypool = 0;
1200 Dwarf_Unsigned abcode = 0;
1201 Dwarf_Unsigned leblen = 0;
1202
1203 res = get_inhdr_cur(dn,index_number,&cur,error);
1204 if (res != DW_DLV_OK) {
1205 return res;
1206 }
1207 dbg = dn->dn_dbg;
1208
1209 if (offset_in_entrypool >= cur->din_entry_pool_size) {
1210 _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET);
1211 return DW_DLV_ERROR;
1212 }
1213 endentrypool = cur->din_entry_pool +cur->din_entry_pool_size;
1214 entrypool = cur->din_entry_pool + offset_in_entrypool;
1215
1216 DECODE_LEB128_UWORD_LEN_CK(entrypool,abcode,leblen,
1217 dbg,error,endentrypool);
1218
1219 res = _dwarf_internal_abbrev_by_code(cur,
1220 abcode,
1221 tag, index_of_abbrev,
1222 value_count);
1223 if (res != DW_DLV_OK) {
1224 /* Never DW_DLV_ERROR (so far) */
1225 return res;
1226 }
1227 *offset_of_initial_value = offset_in_entrypool + leblen;
1228 *abbrev_code = abcode;
1229 return DW_DLV_OK;
1230 }
1231
1232
1233 /* Caller, knowing array size needed, passes in arrays
1234 it allocates of for idx, form, offset-size-values,
1235 and signature values. Caller must examine idx-number
1236 and form to decide, for each array element, whether
1237 the offset or the signature contains the value.
1238 So this returns all the values for the abbrev code.
1239 And points via offset_of_next to the next abbrev code.
1240
1241 While an array of structs would be easier for the caller
1242 to allocate than parallel arrays, public structs have
1243 turned out to be difficult to work with as interfaces
1244 (as formats change over time).
1245 */
dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head dn,Dwarf_Unsigned index_number,Dwarf_Unsigned index_of_abbrev,Dwarf_Unsigned offset_in_entrypool_of_values,Dwarf_Unsigned * array_dw_idx_number,Dwarf_Unsigned * array_form,Dwarf_Unsigned * array_of_offsets,Dwarf_Sig8 * array_of_signatures,Dwarf_Unsigned * offset_of_next_entrypool,Dwarf_Error * error)1246 int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head dn,
1247 Dwarf_Unsigned index_number,
1248 Dwarf_Unsigned index_of_abbrev,
1249 Dwarf_Unsigned offset_in_entrypool_of_values,
1250 Dwarf_Unsigned * array_dw_idx_number,
1251 Dwarf_Unsigned * array_form,
1252 Dwarf_Unsigned * array_of_offsets,
1253 Dwarf_Sig8 * array_of_signatures,
1254
1255 /* offset of the next entrypool entry. */
1256 Dwarf_Unsigned * offset_of_next_entrypool,
1257 Dwarf_Error * error)
1258 {
1259 struct Dwarf_Dnames_index_header_s *cur = 0;
1260 struct Dwarf_D_Abbrev_s * abbrev = 0;
1261 Dwarf_Debug dbg = 0;
1262 unsigned n = 0;
1263 int res = 0;
1264 Dwarf_Unsigned abcount = 0;
1265 Dwarf_Unsigned pooloffset = offset_in_entrypool_of_values;
1266 Dwarf_Small * endpool = 0;
1267 Dwarf_Small * poolptr = 0;
1268
1269 res = get_inhdr_cur(dn,index_number,&cur,error);
1270 if (res != DW_DLV_OK) {
1271 return res;
1272 }
1273 dbg = dn->dn_dbg;
1274 endpool = cur->din_entry_pool + cur->din_entry_pool_size;
1275
1276 if (index_of_abbrev >= cur->din_abbrev_list_count) {
1277 _dwarf_error(dbg,error,DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION);
1278 return DW_DLV_ERROR;
1279 }
1280 poolptr = cur->din_entry_pool + offset_in_entrypool_of_values;
1281 abbrev = cur->din_abbrev_list + index_of_abbrev;
1282 abcount = cur->din_abbrev_list_count;
1283 for(n = 0; n < abcount ; ++n) {
1284 struct abbrev_pair_s *abp = abbrev->da_pairs +n;
1285 unsigned idxtype = abp->ap_index;
1286 unsigned form = abp->ap_form;
1287 array_dw_idx_number[n] = idxtype;
1288 array_form[n] = form;
1289
1290 if(form == DW_FORM_data8 && idxtype == DW_IDX_type_hash) {
1291 if ((poolptr + sizeof(Dwarf_Sig8)) > endpool){
1292 _dwarf_error(dbg,error,
1293 DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET);
1294 return DW_DLV_ERROR;
1295 }
1296 memcpy(array_of_signatures+n,
1297 poolptr,sizeof(Dwarf_Sig8));
1298 poolptr += sizeof(Dwarf_Sig8);
1299 pooloffset += sizeof(Dwarf_Sig8);
1300 continue;
1301 } else if (_dwarf_allow_formudata(form)) {
1302 Dwarf_Unsigned val = 0;
1303 Dwarf_Unsigned bytesread = 0;
1304 res = _dwarf_formudata_internal(dbg,form,poolptr,
1305 endpool,&val,&bytesread,error);
1306 if(res != DW_DLV_OK) {
1307 return res;
1308 }
1309 poolptr += bytesread;
1310 pooloffset += bytesread;
1311 array_of_offsets[n] = val;
1312 continue;
1313 }
1314 /* There is some mistake/omission in our code here or in
1315 the data. */
1316 {
1317 dwarfstring m;
1318 const char *name = "<unknown form>";
1319
1320 dwarfstring_constructor(&m);
1321 dwarfstring_append_printf_u(&m,
1322 "DW_DLE_DEBUG_NAMES_UNHANDLED_FORM: Form 0x%x",
1323 form);
1324 dwarf_get_FORM_name(form,&name);
1325 dwarfstring_append_printf_s(&m,
1326 " %s is not currently supported in .debug_names ",
1327 (char *)name);
1328 _dwarf_error_string(dbg,error,
1329 DW_DLE_DEBUG_NAMES_UNHANDLED_FORM,
1330 dwarfstring_string(&m));
1331 dwarfstring_destructor(&m);
1332 }
1333 return DW_DLV_ERROR;
1334 }
1335 *offset_of_next_entrypool = pooloffset;
1336 return DW_DLV_OK;
1337 }
1338
1339
1340
1341
1342 /* Frees any Dwarf_Dnames_Head_s data that is directly
1343 mallocd. */
1344 void
_dwarf_debugnames_destructor(void * m)1345 _dwarf_debugnames_destructor(void *m)
1346 {
1347 struct Dwarf_Dnames_Head_s *h = (struct Dwarf_Dnames_Head_s *)m;
1348
1349 struct Dwarf_Dnames_index_header_s *cur = 0;
1350 unsigned n = 0;
1351
1352 cur = h->dn_inhdr_first;
1353 for( ;n < h->dn_inhdr_count ; ++n,++cur) {
1354 free_inhdr_content(cur);
1355 }
1356 free(h->dn_inhdr_first);
1357 h->dn_inhdr_first = 0;
1358 h->dn_inhdr_count = 0;
1359 }
1360