1 /*
2
3 Copyright (C) 2014-2019 David Anderson. All Rights Reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2.1 of the GNU Lesser General Public License
7 as published by the Free Software Foundation.
8
9 This program is distributed in the hope that it would be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 Further, this software is distributed without any warranty that it is
14 free of the rightful claim of any third person regarding infringement
15 or the like. Any license provided herein, whether implied or
16 otherwise, applies only to this software file. Patent licenses, if
17 any, provided herein do not apply to combinations of this program with
18 other software, or any other product whatsoever.
19
20 You should have received a copy of the GNU Lesser General Public
21 License along with this program; if not, write the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23 USA.
24
25 */
26
27 #include "config.h"
28 #include <stdio.h>
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif /* HAVE_STDLIB_H */
32 #include "dwarf_incl.h"
33 #include "dwarf_alloc.h"
34 #include "dwarf_error.h"
35 #include "dwarf_util.h"
36 #include "memcpy_swap.h"
37 #include "dwarf_gdbindex.h"
38
39 #define TRUE 1
40 #define FALSE 0
41
42 /* The dwarf_util macro READ_UNALIGNED
43 cannot be directly used because
44 gdb defines the section contents of
45 .gdb_index as little-endian always.
46 */
47
48 #if WORDS_BIGENDIAN /* meaning on this host */
49 #define READ_GDBINDEX(dest,desttype, source, length) \
50 do { \
51 BIGGEST_UINT _ltmp = 0; \
52 _dwarf_memcpy_swap_bytes((((char *)(&_ltmp)) + sizeof(_ltmp) - length), \
53 source, length) ; \
54 dest = (desttype)_ltmp; \
55 } while (0)
56 #else /* little-endian on this host */
57 #define READ_GDBINDEX(dest,desttype, source, length) \
58 do { \
59 BIGGEST_UINT _ltmp = 0; \
60 memcpy(((char *)(&_ltmp)) , \
61 source, length) ; \
62 dest = (desttype)_ltmp; \
63 } while (0)
64
65 #endif
66
67
68 struct gi_fileheader_s {
69 char gfs [4][6];
70 };
71
72 struct dwarf_64bitpair {
73 gdbindex_64 offset;
74 gdbindex_64 length;
75 };
76
77 static int
set_base(Dwarf_Debug dbg,struct Dwarf_Gdbindex_array_instance_s * hdr,Dwarf_Small * start,Dwarf_Small * end,Dwarf_Unsigned entrylen,Dwarf_Unsigned fieldlen,enum gdbindex_type_e type,Dwarf_Error * err)78 set_base(Dwarf_Debug dbg,
79 struct Dwarf_Gdbindex_array_instance_s * hdr,
80 Dwarf_Small *start,
81 Dwarf_Small *end,
82 /* entrylen is the length of a single struct as seen in the object. */
83 Dwarf_Unsigned entrylen,
84 /* The size of each field in the struct in the object. */
85 Dwarf_Unsigned fieldlen,
86 enum gdbindex_type_e type,
87 Dwarf_Error * err)
88 {
89
90 if (type == git_std || type == git_cuvec) {
91 /* cuvec is sort of a fake as a simple
92 section, but a useful one. */
93 Dwarf_Unsigned count = 0;
94 if( end < start) {
95 _dwarf_error(dbg, err,DW_DLE_GDB_INDEX_COUNT_ERROR);
96 return DW_DLV_ERROR;
97 }
98 count = end - start;
99 count = count / entrylen;
100 hdr->dg_type = type;
101 hdr->dg_base = start;
102 hdr->dg_count = count;
103 hdr->dg_entry_length = entrylen;
104 hdr->dg_fieldlen = fieldlen;
105 } else {
106 /* address area. */
107 /* 64bit, 64bit, offset. Then 32bit pad. */
108 Dwarf_Unsigned count = 0;
109 hdr->dg_base = start;
110 if( end < start) {
111 _dwarf_error(dbg, err,DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR);
112 return DW_DLV_ERROR;
113 }
114 /* entry length includes pad. */
115 hdr->dg_entry_length = 2*sizeof(gdbindex_64) +
116 DWARF_32BIT_SIZE;
117 count = end - start;
118 count = count / hdr->dg_entry_length;
119 hdr->dg_count = count;
120 /* The dg_fieldlen is a fake, the fields are not
121 all the same length. */
122 hdr->dg_fieldlen = DWARF_32BIT_SIZE;
123 hdr->dg_type = type;
124 }
125 return DW_DLV_OK;
126 }
127
128 int
dwarf_gdbindex_header(Dwarf_Debug dbg,Dwarf_Gdbindex * gdbindexptr,Dwarf_Unsigned * version,Dwarf_Unsigned * cu_list_offset,Dwarf_Unsigned * types_cu_list_offset,Dwarf_Unsigned * address_area_offset,Dwarf_Unsigned * symbol_table_offset,Dwarf_Unsigned * constant_pool_offset,Dwarf_Unsigned * section_size,Dwarf_Unsigned * unused_reserved,const char ** section_name,Dwarf_Error * error)129 dwarf_gdbindex_header(Dwarf_Debug dbg,
130 Dwarf_Gdbindex * gdbindexptr,
131 Dwarf_Unsigned * version,
132 Dwarf_Unsigned * cu_list_offset,
133 Dwarf_Unsigned * types_cu_list_offset,
134 Dwarf_Unsigned * address_area_offset,
135 Dwarf_Unsigned * symbol_table_offset,
136 Dwarf_Unsigned * constant_pool_offset,
137 Dwarf_Unsigned * section_size,
138 Dwarf_Unsigned * unused_reserved,
139 const char ** section_name,
140 Dwarf_Error * error)
141 {
142
143 struct gi_fileheader_s header;
144 Dwarf_Gdbindex indexptr = 0;
145 int res = DW_DLV_ERROR;
146
147 if (!dbg->de_debug_gdbindex.dss_size) {
148 return DW_DLV_NO_ENTRY;
149 }
150 if (!dbg->de_debug_gdbindex.dss_data) {
151 res = _dwarf_load_section(dbg, &dbg->de_debug_gdbindex,error);
152 if (res != DW_DLV_OK) {
153 return res;
154 }
155 }
156
157 if (dbg->de_debug_gdbindex.dss_size <
158 sizeof(struct gi_fileheader_s) ) {
159 _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_GDB_INDEX_SECTION);
160 return (DW_DLV_ERROR);
161 }
162 memcpy(&header,dbg->de_debug_gdbindex.dss_data,
163 sizeof(struct gi_fileheader_s));
164 indexptr = (Dwarf_Gdbindex)_dwarf_get_alloc(dbg,DW_DLA_GDBINDEX,1);
165 if (indexptr == NULL) {
166 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
167 return (DW_DLV_ERROR);
168 }
169
170 indexptr->gi_dbg = dbg;
171 indexptr->gi_section_data = dbg->de_debug_gdbindex.dss_data;
172 indexptr->gi_section_length = dbg->de_debug_gdbindex.dss_size;
173 READ_GDBINDEX(indexptr->gi_version ,Dwarf_Unsigned,
174 dbg->de_debug_gdbindex.dss_data,
175 DWARF_32BIT_SIZE);
176 READ_GDBINDEX(indexptr->gi_cu_list_offset ,Dwarf_Unsigned,
177 dbg->de_debug_gdbindex.dss_data + DWARF_32BIT_SIZE,
178 DWARF_32BIT_SIZE);
179 READ_GDBINDEX(indexptr->gi_types_cu_list_offset ,Dwarf_Unsigned,
180 dbg->de_debug_gdbindex.dss_data + 2*DWARF_32BIT_SIZE,
181 DWARF_32BIT_SIZE);
182 READ_GDBINDEX(indexptr->gi_address_area_offset ,Dwarf_Unsigned,
183 dbg->de_debug_gdbindex.dss_data + 3*DWARF_32BIT_SIZE,
184 DWARF_32BIT_SIZE);
185 READ_GDBINDEX(indexptr->gi_symbol_table_offset ,Dwarf_Unsigned,
186 dbg->de_debug_gdbindex.dss_data + 4*DWARF_32BIT_SIZE,
187 DWARF_32BIT_SIZE);
188 READ_GDBINDEX(indexptr->gi_constant_pool_offset ,Dwarf_Unsigned,
189 dbg->de_debug_gdbindex.dss_data + 5*DWARF_32BIT_SIZE,
190 DWARF_32BIT_SIZE);
191
192 res = set_base(dbg,&indexptr->gi_culisthdr,
193 dbg->de_debug_gdbindex.dss_data + indexptr->gi_cu_list_offset,
194 dbg->de_debug_gdbindex.dss_data + indexptr->gi_types_cu_list_offset,
195 2*sizeof(gdbindex_64),
196 sizeof(gdbindex_64),
197 git_std,error);
198 if (res == DW_DLV_ERROR) {
199 return res;
200 }
201 res = set_base(dbg,&indexptr->gi_typesculisthdr,
202 dbg->de_debug_gdbindex.dss_data + indexptr->gi_types_cu_list_offset,
203 dbg->de_debug_gdbindex.dss_data + indexptr->gi_address_area_offset,
204 3*sizeof(gdbindex_64),
205 sizeof(gdbindex_64),
206 git_std,error);
207 if (res == DW_DLV_ERROR) {
208 return res;
209 }
210 res = set_base(dbg,&indexptr->gi_addressareahdr,
211 dbg->de_debug_gdbindex.dss_data + indexptr->gi_address_area_offset,
212 dbg->de_debug_gdbindex.dss_data + indexptr->gi_symbol_table_offset,
213 3*sizeof(gdbindex_64),
214 sizeof(gdbindex_64),
215 git_address,error);
216 if (res == DW_DLV_ERROR) {
217 return res;
218 }
219 res = set_base(dbg,&indexptr->gi_symboltablehdr,
220 dbg->de_debug_gdbindex.dss_data + indexptr->gi_symbol_table_offset,
221 dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset,
222 2*DWARF_32BIT_SIZE,
223 DWARF_32BIT_SIZE,
224 git_std,error);
225 if (res == DW_DLV_ERROR) {
226 return res;
227 }
228 res = set_base(dbg,&indexptr->gi_cuvectorhdr,
229 dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset,
230 /* There is no real single vector size.
231 but we'll use the entire rest as if there was. */
232 dbg->de_debug_gdbindex.dss_data + indexptr->gi_section_length,
233 DWARF_32BIT_SIZE,
234 DWARF_32BIT_SIZE,
235 git_cuvec,error);
236 if (res == DW_DLV_ERROR) {
237 return res;
238 }
239
240 /* Really just pointing to constant pool area. */
241 indexptr->gi_string_pool = dbg->de_debug_gdbindex.dss_data +
242 indexptr->gi_constant_pool_offset;
243 *gdbindexptr = indexptr;
244 *version = indexptr->gi_version;
245 *cu_list_offset = indexptr->gi_cu_list_offset;
246 *types_cu_list_offset = indexptr->gi_types_cu_list_offset;
247 *address_area_offset = indexptr->gi_address_area_offset;
248 *symbol_table_offset = indexptr->gi_symbol_table_offset;
249 *constant_pool_offset = indexptr->gi_constant_pool_offset;
250 *section_size = indexptr->gi_section_length;
251 *unused_reserved = 0;
252 *section_name = dbg->de_debug_gdbindex.dss_name;
253 return DW_DLV_OK;
254
255
256 }
257
258
259 int
dwarf_gdbindex_culist_array(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned * list_length,UNUSEDARG Dwarf_Error * error)260 dwarf_gdbindex_culist_array(Dwarf_Gdbindex gdbindexptr,
261 Dwarf_Unsigned * list_length,
262 UNUSEDARG Dwarf_Error * error)
263 {
264 *list_length = gdbindexptr->gi_culisthdr.dg_count;
265 return DW_DLV_OK;
266 }
267
268 /* entryindex: 0 to list_length-1 */
269 int
dwarf_gdbindex_culist_entry(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned entryindex,Dwarf_Unsigned * cu_offset,Dwarf_Unsigned * cu_length,Dwarf_Error * error)270 dwarf_gdbindex_culist_entry(Dwarf_Gdbindex gdbindexptr,
271 Dwarf_Unsigned entryindex,
272 Dwarf_Unsigned * cu_offset,
273 Dwarf_Unsigned * cu_length,
274 Dwarf_Error * error)
275 {
276 Dwarf_Unsigned max = gdbindexptr->gi_culisthdr.dg_count;
277 Dwarf_Small * base = 0;
278 Dwarf_Unsigned offset = 0;
279 Dwarf_Unsigned length = 0;
280 unsigned fieldlen = gdbindexptr->gi_culisthdr.dg_fieldlen;
281
282 if (entryindex >= max) {
283 _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR);
284 return DW_DLV_ERROR;
285 }
286 base = gdbindexptr->gi_culisthdr.dg_base;
287 base += entryindex*gdbindexptr->gi_culisthdr.dg_entry_length;
288
289 READ_GDBINDEX(offset ,Dwarf_Unsigned,
290 base,
291 fieldlen);
292 READ_GDBINDEX(length ,Dwarf_Unsigned,
293 base+ fieldlen,
294 fieldlen);
295 *cu_offset = offset;
296 *cu_length = length;
297 return DW_DLV_OK;
298 }
299
300 int
dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned * list_length,UNUSEDARG Dwarf_Error * error)301 dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex gdbindexptr,
302 Dwarf_Unsigned * list_length,
303 UNUSEDARG Dwarf_Error * error)
304 {
305 *list_length = gdbindexptr->gi_typesculisthdr.dg_count;
306 return DW_DLV_OK;
307 }
308
309 /* entryindex: 0 to list_length-1 */
310 int
dwarf_gdbindex_types_culist_entry(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned entryindex,Dwarf_Unsigned * t_offset,Dwarf_Unsigned * t_length,Dwarf_Unsigned * t_signature,Dwarf_Error * error)311 dwarf_gdbindex_types_culist_entry(Dwarf_Gdbindex gdbindexptr,
312 Dwarf_Unsigned entryindex,
313 Dwarf_Unsigned * t_offset,
314 Dwarf_Unsigned * t_length,
315 Dwarf_Unsigned * t_signature,
316 Dwarf_Error * error)
317 {
318 Dwarf_Unsigned max = gdbindexptr->gi_typesculisthdr.dg_count;
319 Dwarf_Small * base = 0;
320 Dwarf_Unsigned offset = 0;
321 Dwarf_Unsigned length = 0;
322 Dwarf_Unsigned signature = 0;
323 unsigned fieldlen = gdbindexptr->gi_typesculisthdr.dg_fieldlen;
324
325 if (entryindex >= max) {
326 _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR);
327 return DW_DLV_ERROR;
328 }
329 base = gdbindexptr->gi_typesculisthdr.dg_base;
330 base += entryindex*gdbindexptr->gi_typesculisthdr.dg_entry_length;
331
332 READ_GDBINDEX(offset ,Dwarf_Unsigned,
333 base,
334 fieldlen);
335 READ_GDBINDEX(length ,Dwarf_Unsigned,
336 base+ (1*fieldlen),
337 fieldlen);
338 READ_GDBINDEX(signature ,Dwarf_Unsigned,
339 base+ (2*fieldlen),
340 fieldlen);
341 *t_offset = offset;
342 *t_length = length;
343 *t_signature = signature;
344 return DW_DLV_OK;
345 }
346
347 int
dwarf_gdbindex_addressarea(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned * list_length,UNUSEDARG Dwarf_Error * error)348 dwarf_gdbindex_addressarea(Dwarf_Gdbindex gdbindexptr,
349 Dwarf_Unsigned * list_length,
350 UNUSEDARG Dwarf_Error * error)
351 {
352 *list_length = gdbindexptr->gi_addressareahdr.dg_count;
353 return DW_DLV_OK;
354 }
355
356 /* entryindex: 0 to addressarea_list_length-1 */
357 int
dwarf_gdbindex_addressarea_entry(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned entryindex,Dwarf_Unsigned * low_address,Dwarf_Unsigned * high_address,Dwarf_Unsigned * cu_index,Dwarf_Error * error)358 dwarf_gdbindex_addressarea_entry(
359 Dwarf_Gdbindex gdbindexptr,
360 Dwarf_Unsigned entryindex,
361 Dwarf_Unsigned * low_address,
362 Dwarf_Unsigned * high_address,
363 Dwarf_Unsigned * cu_index,
364 Dwarf_Error * error)
365 {
366 Dwarf_Unsigned max = gdbindexptr->gi_addressareahdr.dg_count;
367 Dwarf_Small * base = 0;
368 Dwarf_Unsigned lowaddr = 0;
369 Dwarf_Unsigned highaddr = 0;
370 Dwarf_Unsigned cuindex = 0;
371
372 if (entryindex >= max) {
373 _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR);
374 return DW_DLV_ERROR;
375 }
376 base = gdbindexptr->gi_addressareahdr.dg_base;
377 base += entryindex*gdbindexptr->gi_addressareahdr.dg_entry_length;
378
379 READ_GDBINDEX(lowaddr ,Dwarf_Unsigned,
380 base,
381 sizeof(gdbindex_64));
382 READ_GDBINDEX(highaddr ,Dwarf_Unsigned,
383 base+ (1*sizeof(gdbindex_64)),
384 sizeof(gdbindex_64));
385 READ_GDBINDEX(cuindex ,Dwarf_Unsigned,
386 base+ (2*sizeof(gdbindex_64)),
387 DWARF_32BIT_SIZE);
388 *low_address = lowaddr;
389 *high_address = highaddr;
390 *cu_index = cuindex;
391 return DW_DLV_OK;
392 }
393
394 int
dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned * list_length,UNUSEDARG Dwarf_Error * error)395 dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex gdbindexptr,
396 Dwarf_Unsigned * list_length,
397 UNUSEDARG Dwarf_Error * error)
398 {
399 *list_length = gdbindexptr->gi_symboltablehdr.dg_count;
400 return DW_DLV_OK;
401 }
402
403 /* entryindex: 0 to symtab_list_length-1 */
404 int
dwarf_gdbindex_symboltable_entry(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned entryindex,Dwarf_Unsigned * string_offset,Dwarf_Unsigned * cu_vector_offset,Dwarf_Error * error)405 dwarf_gdbindex_symboltable_entry(
406 Dwarf_Gdbindex gdbindexptr,
407 Dwarf_Unsigned entryindex,
408 Dwarf_Unsigned * string_offset,
409 Dwarf_Unsigned * cu_vector_offset,
410 Dwarf_Error * error)
411 {
412 Dwarf_Unsigned max = gdbindexptr->gi_symboltablehdr.dg_count;
413 Dwarf_Small * base = 0;
414 Dwarf_Unsigned symoffset = 0;
415 Dwarf_Unsigned cuoffset = 0;
416 unsigned fieldlen = gdbindexptr->gi_symboltablehdr.dg_fieldlen;
417
418 if (entryindex >= max) {
419 _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR);
420 return DW_DLV_ERROR;
421 }
422 base = gdbindexptr->gi_symboltablehdr.dg_base;
423 base += entryindex*gdbindexptr->gi_symboltablehdr.dg_entry_length;
424
425 READ_GDBINDEX(symoffset ,Dwarf_Unsigned,
426 base,
427 fieldlen);
428 READ_GDBINDEX(cuoffset ,Dwarf_Unsigned,
429 base + fieldlen,
430 fieldlen);
431 *string_offset = symoffset;
432 *cu_vector_offset = cuoffset;
433 return DW_DLV_OK;
434 }
435
436 int
dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex gdbindex,Dwarf_Unsigned cuvector_offset,Dwarf_Unsigned * innercount,Dwarf_Error * error)437 dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex gdbindex,
438 Dwarf_Unsigned cuvector_offset,
439 Dwarf_Unsigned * innercount,
440 Dwarf_Error * error)
441 {
442 Dwarf_Small *base = gdbindex->gi_cuvectorhdr.dg_base;
443 Dwarf_Small *end = gdbindex->gi_section_data + gdbindex->gi_section_length;
444 Dwarf_Unsigned val = 0;
445 unsigned fieldlen = gdbindex->gi_cuvectorhdr.dg_entry_length;
446
447 base += cuvector_offset;
448 if ((base + fieldlen) >= end) {
449 _dwarf_error(gdbindex->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR);
450 return DW_DLV_ERROR;
451 }
452
453 READ_GDBINDEX(val,Dwarf_Unsigned,
454 base,
455 fieldlen);
456 *innercount = val;
457 return DW_DLV_OK;
458 }
459
460 int
dwarf_gdbindex_cuvector_inner_attributes(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned cuvector_offset,Dwarf_Unsigned innerindex,Dwarf_Unsigned * attributes,Dwarf_Error * error)461 dwarf_gdbindex_cuvector_inner_attributes(Dwarf_Gdbindex gdbindexptr,
462 Dwarf_Unsigned cuvector_offset,
463 Dwarf_Unsigned innerindex,
464 /* The attr_value is a field of bits. For expanded version
465 use dwarf_gdbindex_instance_expand_value() */
466 Dwarf_Unsigned * attributes,
467 Dwarf_Error * error)
468 {
469 Dwarf_Small *base = gdbindexptr->gi_cuvectorhdr.dg_base;
470 Dwarf_Small *end = gdbindexptr->gi_section_data +
471 gdbindexptr->gi_section_length;
472 Dwarf_Unsigned val = 0;
473 unsigned fieldlen = gdbindexptr->gi_cuvectorhdr.dg_entry_length;
474
475 base += cuvector_offset;
476 if ((base+fieldlen) >= end) {
477 _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR);
478 return DW_DLV_ERROR;
479 }
480 base += fieldlen;
481 base += innerindex*fieldlen;
482
483 READ_GDBINDEX(val ,Dwarf_Unsigned,
484 base,
485 fieldlen);
486 *attributes = val;
487 return DW_DLV_OK;
488 }
489
490
491 int
dwarf_gdbindex_cuvector_instance_expand_value(UNUSEDARG Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned value,Dwarf_Unsigned * cu_index,Dwarf_Unsigned * reserved1,Dwarf_Unsigned * symbol_kind,Dwarf_Unsigned * is_static,UNUSEDARG Dwarf_Error * error)492 dwarf_gdbindex_cuvector_instance_expand_value(
493 UNUSEDARG Dwarf_Gdbindex gdbindexptr,
494 Dwarf_Unsigned value,
495 Dwarf_Unsigned * cu_index,
496 Dwarf_Unsigned * reserved1,
497 Dwarf_Unsigned * symbol_kind,
498 Dwarf_Unsigned * is_static,
499 UNUSEDARG Dwarf_Error * error)
500 {
501 *cu_index = value & 0xffffff;
502 *reserved1 = (value >> 24) & 0xf;
503 *symbol_kind = (value >> 28) & 0x7;
504 *is_static = (value >> 31) & 1;
505 return DW_DLV_OK;
506 }
507
508
509 /* The strings in the pool follow (in memory) the cu index
510 set and are NUL terminated. */
511 int
dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex gdbindexptr,Dwarf_Unsigned stringoffsetinpool,const char ** string_ptr,UNUSEDARG Dwarf_Error * error)512 dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex gdbindexptr,
513 Dwarf_Unsigned stringoffsetinpool,
514 const char ** string_ptr,
515 UNUSEDARG Dwarf_Error * error)
516 {
517 Dwarf_Small *pooldata = 0;
518 Dwarf_Small *section_end = 0;
519 Dwarf_Small *stringitself = 0;
520
521 /* If gdbindexptr NULL or gdbindexptr->gi_dbg is NULL
522 this is not going to go very well. Ugh. FIXME */
523 pooldata = gdbindexptr->gi_section_data +
524 gdbindexptr->gi_constant_pool_offset;
525 section_end = gdbindexptr->gi_section_data +
526 gdbindexptr->gi_section_length;
527 stringitself = pooldata + stringoffsetinpool;
528 if (stringitself > section_end) {
529 _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR);
530 return DW_DLV_ERROR;
531 }
532 *string_ptr = (const char *)stringitself;
533 return DW_DLV_OK;
534 }
535
536
537
538
539 void
dwarf_gdbindex_free(Dwarf_Gdbindex indexptr)540 dwarf_gdbindex_free(Dwarf_Gdbindex indexptr)
541 {
542 if(indexptr) {
543 Dwarf_Debug dbg = indexptr->gi_dbg;
544 dwarf_dealloc(dbg,indexptr,DW_DLA_GDBINDEX);
545 }
546 }
547