xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_dnames.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
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