dbghelp: Dwarf & new scheme.
[wine/multimedia.git] / dlls / dbghelp / dwarf.c
blob5ccc3660f537c806d5cbfc553cff80de8e352fc7
1 /*
2 * File dwarf.c - read dwarf2 information from the ELF modules
4 * Copyright (C) 2005, Raphael Junqueira
5 * Copyright (C) 2006, Eric Pouech
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include <sys/types.h>
25 #include <fcntl.h>
26 #ifdef HAVE_SYS_STAT_H
27 # include <sys/stat.h>
28 #endif
29 #ifdef HAVE_SYS_MMAN_H
30 #include <sys/mman.h>
31 #endif
32 #include <limits.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #ifdef HAVE_UNISTD_H
36 # include <unistd.h>
37 #endif
38 #include <stdio.h>
39 #ifndef PATH_MAX
40 #define PATH_MAX MAX_PATH
41 #endif
42 #include <assert.h>
43 #include <stdarg.h>
45 #include "windef.h"
46 #include "winbase.h"
47 #include "winreg.h"
48 #include "winnls.h"
50 #include "dbghelp_private.h"
52 #include "wine/debug.h"
54 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_dwarf);
56 #if 0
57 static void dump(const void* ptr, unsigned len)
59 int i, j;
60 BYTE msg[128];
61 static const char hexof[] = "0123456789abcdef";
62 const BYTE* x = (const BYTE*)ptr;
64 for (i = 0; i < len; i += 16)
66 sprintf(msg, "%08x: ", i);
67 memset(msg + 10, ' ', 3 * 16 + 1 + 16);
68 for (j = 0; j < min(16, len - i); j++)
70 msg[10 + 3 * j + 0] = hexof[x[i + j] >> 4];
71 msg[10 + 3 * j + 1] = hexof[x[i + j] & 15];
72 msg[10 + 3 * j + 2] = ' ';
73 msg[10 + 3 * 16 + 1 + j] = (x[i + j] >= 0x20 && x[i + j] < 0x7f) ?
74 x[i + j] : '.';
76 msg[10 + 3 * 16] = ' ';
77 msg[10 + 3 * 16 + 1 + 16] = '\0';
78 TRACE("%s\n", msg);
81 #endif
83 /**
85 * Main Specs:
86 * http://www.eagercon.com/dwarf/dwarf3std.htm
87 * http://www.eagercon.com/dwarf/dwarf-2.0.0.pdf
89 * dwarf2.h: http://www.hakpetzna.com/b/binutils/dwarf2_8h-source.html
91 * example of projects who do dwarf2 parsing:
92 * http://www.x86-64.org/cgi-bin/cvsweb.cgi/binutils.dead/binutils/readelf.c?rev=1.1.1.2
93 * http://elis.ugent.be/diota/log/ltrace_elf.c
95 #include "dwarf.h"
97 /**
98 * Parsers
101 typedef struct dwarf2_abbrev_entry_attr_s {
102 unsigned long attribute;
103 unsigned long form;
104 struct dwarf2_abbrev_entry_attr_s* next;
105 } dwarf2_abbrev_entry_attr_t;
107 typedef struct dwarf2_abbrev_entry_s
109 unsigned long entry_code;
110 unsigned long tag;
111 unsigned char have_child;
112 unsigned num_attr;
113 dwarf2_abbrev_entry_attr_t* attrs;
114 } dwarf2_abbrev_entry_t;
116 union attribute
118 unsigned long uvalue;
119 long svalue;
120 const char* string;
123 typedef struct dwarf2_debug_info_s
125 unsigned long offset;
126 const dwarf2_abbrev_entry_t*abbrev;
127 struct symt* symt;
128 union attribute* attributes;
129 struct vector children;
130 } dwarf2_debug_info_t;
132 typedef struct dwarf2_parse_context_s {
133 struct pool pool;
134 struct module* module;
135 struct sparse_array abbrev_table;
136 struct sparse_array debug_info_table;
137 const unsigned char* data_stream;
138 const unsigned char* data;
139 const unsigned char* start_data;
140 const unsigned char* end_data;
141 const unsigned char* str_section;
142 unsigned long offset;
143 unsigned char word_size;
144 } dwarf2_parse_context_t;
146 /* forward declarations */
147 static struct symt_enum* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry);
149 static unsigned char dwarf2_parse_byte(dwarf2_parse_context_t* ctx)
151 unsigned char uvalue = *(const unsigned char*) ctx->data;
152 ctx->data += 1;
153 return uvalue;
156 static unsigned short dwarf2_parse_u2(dwarf2_parse_context_t* ctx)
158 unsigned short uvalue = *(const unsigned short*) ctx->data;
159 ctx->data += 2;
160 return uvalue;
163 static unsigned long dwarf2_parse_u4(dwarf2_parse_context_t* ctx)
165 unsigned long uvalue = *(const unsigned int*) ctx->data;
166 ctx->data += 4;
167 return uvalue;
170 static unsigned long dwarf2_leb128_as_unsigned(dwarf2_parse_context_t* ctx)
172 unsigned long ret = 0;
173 unsigned char byte;
174 unsigned shift = 0;
176 assert( NULL != ctx );
178 while (1) {
179 byte = dwarf2_parse_byte(ctx);
180 ret |= (byte & 0x7f) << shift;
181 shift += 7;
182 if (0 == (byte & 0x80)) { break ; }
185 return ret;
188 static long dwarf2_leb128_as_signed(dwarf2_parse_context_t* ctx)
190 long ret = 0;
191 unsigned char byte;
192 unsigned shift = 0;
193 const unsigned size = sizeof(int) * 8;
195 assert( NULL != ctx );
197 while (1) {
198 byte = dwarf2_parse_byte(ctx);
199 ret |= (byte & 0x7f) << shift;
200 shift += 7;
201 if (0 == (byte & 0x80)) { break ; }
203 /* as spec: sign bit of byte is 2nd high order bit (80x40)
204 * -> 0x80 is used as flag.
206 if ((shift < size) && (byte & 0x40)) {
207 ret |= - (1 << shift);
209 return ret;
212 static unsigned long dwarf2_parse_addr(dwarf2_parse_context_t* ctx)
214 unsigned long ret;
216 switch (ctx->word_size)
218 case 4:
219 ret = dwarf2_parse_u4(ctx);
220 break;
221 default:
222 FIXME("Unsupported Word Size %u\n", ctx->word_size);
223 ret = 0;
225 return ret;
228 static const char* dwarf2_debug_ctx(dwarf2_parse_context_t* ctx)
230 /*return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->start_data, ctx->level); */
231 return wine_dbg_sprintf("ctx(0x%x)", ctx->data - ctx->data_stream);
233 static const char* dwarf2_debug_attr(dwarf2_abbrev_entry_attr_t* attr)
235 return wine_dbg_sprintf("attr(attr:0x%lx,form:0x%lx)", attr->attribute, attr->form);
238 static void dwarf2_check_sibling(dwarf2_parse_context_t* ctx, unsigned long next_sibling)
240 if (0 < next_sibling && ctx->data != ctx->data_stream + next_sibling) {
241 if ((ctx->data + 1) != ctx->data_stream + next_sibling) {
242 /** padding check */
243 WARN("cursor error for %s should be sibling<0x%lx>\n", dwarf2_debug_ctx(ctx), next_sibling);
245 ctx->data = ctx->data_stream + next_sibling;
250 static dwarf2_abbrev_entry_t*
251 dwarf2_abbrev_table_find_entry(struct sparse_array* abbrev_table,
252 unsigned long entry_code)
254 assert( NULL != abbrev_table );
255 return sparse_array_find(abbrev_table, entry_code);
258 static void dwarf2_parse_abbrev_set(dwarf2_parse_context_t* abbrev_ctx,
259 struct sparse_array* abbrev_table,
260 struct pool* pool)
262 unsigned long entry_code;
263 dwarf2_abbrev_entry_t* abbrev_entry;
264 dwarf2_abbrev_entry_attr_t* new = NULL;
265 dwarf2_abbrev_entry_attr_t* last = NULL;
266 unsigned long attribute;
267 unsigned long form;
269 TRACE("%s, end at %p\n", dwarf2_debug_ctx(abbrev_ctx), abbrev_ctx->end_data);
271 assert( NULL != abbrev_ctx );
273 sparse_array_init(abbrev_table, sizeof(dwarf2_abbrev_entry_t), 32);
274 while (abbrev_ctx->data < abbrev_ctx->end_data)
276 TRACE("now at %s\n", dwarf2_debug_ctx(abbrev_ctx));
277 entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx);
278 TRACE("found entry_code %lu\n", entry_code);
279 if (!entry_code)
281 TRACE("NULL entry code at %s\n", dwarf2_debug_ctx(abbrev_ctx));
282 break;
284 abbrev_entry = sparse_array_add(abbrev_table, entry_code, pool);
285 assert( NULL != abbrev_entry );
287 abbrev_entry->entry_code = entry_code;
288 abbrev_entry->tag = dwarf2_leb128_as_unsigned(abbrev_ctx);
289 abbrev_entry->have_child = dwarf2_parse_byte(abbrev_ctx);
290 abbrev_entry->attrs = NULL;
291 abbrev_entry->num_attr = 0;
293 TRACE("table:(%p,#%u) entry_code(%lu) tag(0x%lx) have_child(%u) -> %p\n",
294 abbrev_table, sparse_array_length(abbrev_table),
295 entry_code, abbrev_entry->tag, abbrev_entry->have_child, abbrev_entry);
297 last = NULL;
298 while (1)
300 attribute = dwarf2_leb128_as_unsigned(abbrev_ctx);
301 form = dwarf2_leb128_as_unsigned(abbrev_ctx);
302 if (!attribute) break;
304 new = pool_alloc(pool, sizeof(dwarf2_abbrev_entry_attr_t));
305 assert(new);
307 new->attribute = attribute;
308 new->form = form;
309 new->next = NULL;
310 if (abbrev_entry->attrs) last->next = new;
311 else abbrev_entry->attrs = new;
312 last = new;
313 abbrev_entry->num_attr++;
316 TRACE("found %u entries\n", sparse_array_length(abbrev_table));
319 static const char* dwarf2_parse_attr_as_string(dwarf2_abbrev_entry_attr_t* attr,
320 dwarf2_parse_context_t* ctx)
322 const char* ret = NULL;
323 switch (attr->form) {
324 case DW_FORM_string:
325 ret = (const char*) ctx->data;
326 ctx->data += strlen(ret) + 1;
327 break;
328 case DW_FORM_strp:
330 unsigned long offset = dwarf2_parse_u4(ctx);
331 ret = (const char*) ctx->str_section + offset;
332 /*FIXME("Unsupported indirect string format offset 0x%lx (in .debug_str)\n", offset);*/
334 break;
335 default:
336 ERR("Unsupported string format 0x%lx for attr 0x%lx\n", attr->form, attr->attribute);
338 return ret;
341 static unsigned long dwarf2_parse_attr_as_addr(dwarf2_abbrev_entry_attr_t* attr,
342 dwarf2_parse_context_t* ctx)
344 unsigned long offset = 0;
345 switch (ctx->word_size) {
346 case 4:
347 offset = *(const unsigned int*) ctx->data;
348 break;
349 case 8:
350 default:
351 FIXME("Unsupported Word Size %u\n", ctx->word_size);
353 ctx->data += ctx->word_size;
354 return offset;
357 static unsigned long dwarf2_parse_attr_as_ref(dwarf2_abbrev_entry_attr_t* attr,
358 dwarf2_parse_context_t* ctx)
360 unsigned long uvalue = 0;
361 switch (attr->form) {
362 case DW_FORM_ref1:
363 uvalue = ctx->offset + dwarf2_parse_byte(ctx);
364 TRACE("ref1<0x%lx>\n", uvalue);
365 break;
367 case DW_FORM_ref2:
368 uvalue = ctx->offset + dwarf2_parse_u2(ctx);
369 TRACE("ref2<0x%lx>\n", uvalue);
370 break;
372 case DW_FORM_ref4:
373 uvalue = ctx->offset + dwarf2_parse_u4(ctx);
374 TRACE("ref4<0x%lx>\n", uvalue);
375 break;
377 case DW_FORM_ref8:
378 /* FIXME: 64bits support */
380 uvalue = ctx->offset + dwarf2_parse_u8(ctx);
381 TRACE("ref8<0x%lx>\n", uvalue);
383 ctx->data += 8;
384 break;
386 return uvalue;
390 static unsigned long dwarf2_parse_attr_as_data(dwarf2_abbrev_entry_attr_t* attr,
391 dwarf2_parse_context_t* ctx)
393 unsigned long uvalue = 0;
394 switch (attr->form) {
395 case DW_FORM_data1:
396 uvalue = dwarf2_parse_byte(ctx);
397 TRACE("data1<%lu>\n", uvalue);
398 break;
400 case DW_FORM_data2:
401 uvalue = dwarf2_parse_u2(ctx);
402 TRACE("data2<%lu>\n", uvalue);
403 break;
405 case DW_FORM_data4:
406 uvalue = dwarf2_parse_u4(ctx);
407 TRACE("data4<%lu>\n", uvalue);
408 break;
410 case DW_FORM_data8:
411 FIXME("Unsupported 64bits support\n");
412 ctx->data += 8;
413 break;
415 return uvalue;
418 static void dwarf2_parse_attr(dwarf2_abbrev_entry_attr_t* attr,
419 dwarf2_parse_context_t* ctx)
421 const unsigned long attribute = attr->attribute;
422 const unsigned long form = attr->form;
423 unsigned long uvalue = 0;
424 long svalue = 0;
425 const char* str = NULL;
427 TRACE("(attr:0x%lx,form:0x%lx)\n", attribute, form);
429 switch (form) {
430 case DW_FORM_ref_addr:
431 case DW_FORM_addr:
432 uvalue = dwarf2_parse_attr_as_addr(attr, ctx);
433 break;
435 case DW_FORM_flag:
436 uvalue = dwarf2_parse_byte(ctx);
437 TRACE("flag<0x%lx>\n", uvalue);
438 break;
440 case DW_FORM_data1:
441 uvalue = dwarf2_parse_byte(ctx);
442 TRACE("data1<%lu>\n", uvalue);
443 break;
445 case DW_FORM_data2:
446 uvalue = dwarf2_parse_u2(ctx);
447 TRACE("data2<%lu>\n", uvalue);
448 break;
450 case DW_FORM_data4:
451 uvalue = dwarf2_parse_u4(ctx);
452 TRACE("data4<%lu>\n", uvalue);
453 break;
455 case DW_FORM_ref1:
456 case DW_FORM_ref2:
457 case DW_FORM_ref4:
458 case DW_FORM_ref8:
459 uvalue = dwarf2_parse_attr_as_ref(attr, ctx);
460 /*TRACE("ref<0x%lx>\n", ctx->offset + uvalue);*/
461 break;
463 case DW_FORM_data8:
464 FIXME("Unsupported 64bits support\n");
465 ctx->data += 8;
466 break;
468 case DW_FORM_sdata:
469 svalue = dwarf2_leb128_as_signed(ctx);
470 break;
472 case DW_FORM_ref_udata:
473 case DW_FORM_udata:
474 uvalue = dwarf2_leb128_as_unsigned(ctx);
475 break;
477 case DW_FORM_string:
478 case DW_FORM_strp:
479 str = dwarf2_parse_attr_as_string(attr, ctx);
480 TRACE("string<%s>\n", str);
481 break;
483 case DW_FORM_block:
484 uvalue = dwarf2_leb128_as_unsigned(ctx);
485 ctx->data += uvalue;
486 break;
488 case DW_FORM_block1:
489 uvalue = dwarf2_parse_byte(ctx);
490 ctx->data += uvalue;
491 break;
493 case DW_FORM_block2:
494 uvalue = dwarf2_parse_u2(ctx);
495 ctx->data += uvalue;
496 break;
498 case DW_FORM_block4:
499 uvalue = dwarf2_parse_u4(ctx);
500 ctx->data += uvalue;
501 break;
503 default:
504 break;
508 static void dwarf2_parse_attr_into_di(dwarf2_parse_context_t* ctx,
509 const dwarf2_abbrev_entry_attr_t* abbrev_attr,
510 union attribute* attr)
513 TRACE("(attr:0x%lx,form:0x%lx)\n", abbrev_attr->attribute, abbrev_attr->form);
515 switch (abbrev_attr->form) {
516 case DW_FORM_ref_addr:
517 case DW_FORM_addr:
518 attr->uvalue = dwarf2_parse_addr(ctx);
519 TRACE("addr<0x%lx>\n", attr->uvalue);
520 break;
522 case DW_FORM_flag:
523 attr->uvalue = dwarf2_parse_byte(ctx);
524 TRACE("flag<0x%lx>\n", attr->uvalue);
525 break;
527 case DW_FORM_data1:
528 attr->uvalue = dwarf2_parse_byte(ctx);
529 TRACE("data1<%lu>\n", attr->uvalue);
530 break;
532 case DW_FORM_data2:
533 attr->uvalue = dwarf2_parse_u2(ctx);
534 TRACE("data2<%lu>\n", attr->uvalue);
535 break;
537 case DW_FORM_data4:
538 attr->uvalue = dwarf2_parse_u4(ctx);
539 TRACE("data4<%lu>\n", attr->uvalue);
540 break;
542 case DW_FORM_data8:
543 FIXME("Unhandled 64bits support\n");
544 ctx->data += 8;
545 break;
547 case DW_FORM_ref1:
548 attr->uvalue = ctx->offset + dwarf2_parse_byte(ctx);
549 TRACE("ref1<0x%lx>\n", attr->uvalue);
550 break;
552 case DW_FORM_ref2:
553 attr->uvalue = ctx->offset + dwarf2_parse_u2(ctx);
554 TRACE("ref2<0x%lx>\n", attr->uvalue);
555 break;
557 case DW_FORM_ref4:
558 attr->uvalue = ctx->offset + dwarf2_parse_u4(ctx);
559 TRACE("ref4<0x%lx>\n", attr->uvalue);
560 break;
562 case DW_FORM_ref8:
563 FIXME("Unhandled 64 bit support\n");
564 ctx->data += 8;
565 break;
567 case DW_FORM_sdata:
568 attr->svalue = dwarf2_leb128_as_signed(ctx);
569 break;
571 case DW_FORM_ref_udata:
572 attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
573 break;
575 case DW_FORM_udata:
576 attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
577 break;
579 case DW_FORM_string:
580 attr->string = (const char*)ctx->data;
581 ctx->data += strlen(attr->string) + 1;
582 TRACE("string<%s>\n", attr->string);
583 break;
585 case DW_FORM_strp:
587 unsigned long offset = dwarf2_parse_u4(ctx);
588 attr->string = (const char*)ctx->str_section + offset;
590 TRACE("strp<%s>\n", attr->string);
591 break;
592 case DW_FORM_block:
593 attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
594 ctx->data += attr->uvalue;
595 break;
597 case DW_FORM_block1:
598 attr->uvalue = dwarf2_parse_byte(ctx);
599 ctx->data += attr->uvalue;
600 break;
602 case DW_FORM_block2:
603 attr->uvalue = dwarf2_parse_u2(ctx);
604 ctx->data += attr->uvalue;
605 break;
607 case DW_FORM_block4:
608 attr->uvalue = dwarf2_parse_u4(ctx);
609 ctx->data += attr->uvalue;
610 break;
612 default:
613 FIXME("Unhandled attribute form %lx\n", abbrev_attr->form);
614 break;
618 static BOOL dwarf2_find_attribute(const dwarf2_debug_info_t* di,
619 unsigned at, union attribute* attr)
621 unsigned i;
622 dwarf2_abbrev_entry_attr_t* abbrev_attr;
624 for (i = 0, abbrev_attr = di->abbrev->attrs; abbrev_attr; i++, abbrev_attr = abbrev_attr->next)
626 if (abbrev_attr->attribute == at)
628 *attr = di->attributes[i];
629 return TRUE;
632 return FALSE;
635 static void dwarf2_find_name(dwarf2_parse_context_t* ctx,
636 const dwarf2_debug_info_t* di,
637 union attribute* attr, const char* pfx)
640 static int index;
642 if (!dwarf2_find_attribute(di, DW_AT_name, attr))
644 char* tmp = pool_alloc(&ctx->pool, strlen(pfx) + 16);
645 if (tmp) sprintf(tmp, "%s_%d", pfx, index++);
646 attr->string = tmp;
650 static struct symt* dwarf2_find_symt_by_ref(struct module* module, unsigned long ref)
652 WARN("want ref<0x%lx>\n", ref);
653 return NULL;
656 /******************************************************************
657 * dwarf2_read_one_debug_info
659 * Loads into memory one debug info entry, and recursively its children (if any)
661 static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx,
662 dwarf2_debug_info_t** pdi)
664 const dwarf2_abbrev_entry_t*abbrev;
665 unsigned long entry_code;
666 unsigned long offset;
667 dwarf2_debug_info_t* di;
668 dwarf2_debug_info_t* child;
669 dwarf2_debug_info_t** where;
670 dwarf2_abbrev_entry_attr_t* attr;
671 unsigned i;
673 offset = ctx->data - ctx->data_stream;
674 entry_code = dwarf2_leb128_as_unsigned(ctx);
675 TRACE("found entry_code %lu at 0x%lx\n", entry_code, offset);
676 if (!entry_code)
678 *pdi = NULL;
679 return TRUE;
681 abbrev = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
682 if (!abbrev)
684 WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, offset);
685 return FALSE;
687 di = sparse_array_add(&ctx->debug_info_table, offset, &ctx->pool);
688 if (!di) return FALSE;
689 di->offset = offset;
690 di->abbrev = abbrev;
691 di->symt = NULL;
693 if (abbrev->num_attr)
695 di->attributes = pool_alloc(&ctx->pool,
696 abbrev->num_attr * sizeof(union attribute));
697 for (i = 0, attr = abbrev->attrs; attr; i++, attr = attr->next)
699 dwarf2_parse_attr_into_di(ctx, attr, &di->attributes[i]);
702 else di->attributes = NULL;
703 if (abbrev->have_child)
705 vector_init(&di->children, sizeof(dwarf2_debug_info_t*), 16);
706 while (ctx->data < ctx->end_data)
708 if (!dwarf2_read_one_debug_info(ctx, &child)) return FALSE;
709 if (!child) break;
710 where = vector_add(&di->children, &ctx->pool);
711 if (!where) return FALSE;
712 *where = child;
715 *pdi = di;
716 return TRUE;
719 static struct symt_basic* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
721 struct symt_basic* symt = NULL;
722 const char* name = NULL;
723 unsigned size = 0;
724 unsigned encoding = 0;
725 enum BasicType bt;
726 dwarf2_abbrev_entry_attr_t* attr = NULL;
728 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
730 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
731 switch (attr->attribute) {
732 case DW_AT_name:
733 name = dwarf2_parse_attr_as_string(attr, ctx);
734 TRACE("found name %s\n", name);
735 break;
736 case DW_AT_byte_size:
737 size = dwarf2_parse_attr_as_data(attr, ctx);
738 break;
739 case DW_AT_encoding:
740 encoding = dwarf2_parse_byte(ctx);
741 break;
742 default:
743 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
744 dwarf2_parse_attr(attr, ctx);
747 switch (encoding) {
748 case DW_ATE_void: bt = btVoid; break;
749 case DW_ATE_address: bt = btULong; break;
750 case DW_ATE_boolean: bt = btBool; break;
751 case DW_ATE_complex_float: bt = btComplex; break;
752 case DW_ATE_float: bt = btFloat; break;
753 case DW_ATE_signed: bt = btInt; break;
754 case DW_ATE_unsigned: bt = btUInt; break;
755 case DW_ATE_signed_char: bt = btChar; break;
756 case DW_ATE_unsigned_char: bt = btChar; break;
757 default:
758 bt = btNoType;
760 /*TRACE("symt_new_basic(%p, %u, %s, %u)", module, bt, name, size);*/
761 symt = symt_new_basic(ctx->module, bt, name, size);
763 if (entry->have_child) {
764 FIXME("Unsupported children\n");
766 return symt;
769 static struct symt_typedef* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
771 struct symt_typedef* symt = NULL;
772 struct symt* ref_type = NULL;
773 const char* name = NULL;
774 dwarf2_abbrev_entry_attr_t* attr = NULL;
776 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
778 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
779 switch (attr->attribute) {
780 case DW_AT_name:
781 name = dwarf2_parse_attr_as_string(attr, ctx);
782 TRACE("found name %s\n", name);
783 break;
784 case DW_AT_type:
786 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
787 ref_type = dwarf2_find_symt_by_ref(ctx->module, ref);
789 break;
790 case DW_AT_decl_file:
791 case DW_AT_decl_line:
792 dwarf2_parse_attr(attr, ctx);
793 break;
794 default:
795 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
796 dwarf2_parse_attr(attr, ctx);
799 if (NULL != name) {
800 symt = symt_new_typedef(ctx->module, ref_type, name);
803 if (entry->have_child) {
804 FIXME("Unsupported children\n");
806 return symt;
809 static struct symt_pointer* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
811 struct symt_pointer* symt = NULL;
812 struct symt* ref_type = NULL;
813 unsigned size = 0;
814 dwarf2_abbrev_entry_attr_t* attr = NULL;
816 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
818 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
819 switch (attr->attribute) {
820 case DW_AT_byte_size:
821 size = dwarf2_parse_attr_as_data(attr, ctx);
822 break;
823 case DW_AT_type:
825 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
826 ref_type = dwarf2_find_symt_by_ref(ctx->module, ref);
828 break;
829 default:
830 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
831 dwarf2_parse_attr(attr, ctx);
834 symt = symt_new_pointer(ctx->module, ref_type);
836 if (entry->have_child) {
837 FIXME("Unsupported children\n");
839 return symt;
842 static void dwarf2_parse_array_subrange_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_array* parent)
844 unsigned min = 0;
845 unsigned max = 0;
846 struct symt* idx_type = NULL;
847 dwarf2_abbrev_entry_attr_t* attr = NULL;
849 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
851 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
852 switch (attr->attribute) {
853 case DW_AT_type:
855 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
856 idx_type = dwarf2_find_symt_by_ref(ctx->module, ref);
857 /** check if idx_type is a basic_type integer */
859 break;
860 case DW_AT_lower_bound:
861 TRACE("%s %s, lower_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
862 min = dwarf2_parse_attr_as_data(attr, ctx);
863 break;
864 case DW_AT_upper_bound:
865 TRACE("%s %s, upper_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
866 max = dwarf2_parse_attr_as_data(attr, ctx);
867 break;
868 case DW_AT_count:
869 TRACE("%s %s, count min:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), min);
870 max = min + dwarf2_parse_attr_as_data(attr, ctx);
871 break;
872 default:
873 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
874 dwarf2_parse_attr(attr, ctx);
877 parent->start = min;
878 parent->end = max;
879 parent->index_type = idx_type;
881 TRACE("found min:%u max:%u\n", min, max);
883 if (entry->have_child) {
884 FIXME("Unsupported children\n");
889 static struct symt_array* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
891 struct symt_array* symt = NULL;
892 struct symt* ref_type = NULL;
893 unsigned min = 0;
894 unsigned max = 0;
895 dwarf2_abbrev_entry_attr_t* attr = NULL;
896 unsigned long next_sibling = 0;
898 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
900 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
901 switch (attr->attribute) {
902 case DW_AT_sibling:
903 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
904 break;
905 case DW_AT_type:
907 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
908 ref_type = dwarf2_find_symt_by_ref(ctx->module, ref);
910 break;
911 default:
912 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
913 dwarf2_parse_attr(attr, ctx);
917 /* FIXME: ugly as hell */
918 symt = symt_new_array(ctx->module, min, max, ref_type, NULL);
920 if (entry->have_child) { /** any interest to not have child ? */
921 while (ctx->data < ctx->end_data) {
922 dwarf2_abbrev_entry_t* entry = NULL;
923 unsigned long entry_code;
924 unsigned long entry_ref = 0;
926 entry_ref = ctx->data - ctx->data_stream;
928 entry_code = dwarf2_leb128_as_unsigned(ctx);
929 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
930 if (0 == entry_code) {
931 break ;
934 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
935 assert( NULL != entry );
937 switch (entry->tag) {
938 case DW_TAG_subrange_type:
939 dwarf2_parse_array_subrange_type(ctx, entry, symt);
940 break;
941 default:
943 dwarf2_abbrev_entry_attr_t* attr;
944 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
945 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
946 dwarf2_parse_attr(attr, ctx);
949 break;
954 /** set correct data cursor */
955 dwarf2_check_sibling(ctx, next_sibling);
957 return symt;
960 static struct symt* dwarf2_parse_const_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
962 struct symt* ref_type = NULL;
963 dwarf2_abbrev_entry_attr_t* attr = NULL;
964 unsigned long next_sibling = 0;
966 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
968 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
969 switch (attr->attribute) {
970 case DW_AT_type:
972 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
973 ref_type = dwarf2_find_symt_by_ref(ctx->module, ref);
975 break;
976 default:
977 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
978 dwarf2_parse_attr(attr, ctx);
982 if (entry->have_child) {
983 FIXME("Unsupported children\n");
986 /** set correct data cursor */
987 dwarf2_check_sibling(ctx, next_sibling);
989 return ref_type;
992 static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
994 struct symt* symt = NULL;
995 struct symt* ref_type = NULL;
996 dwarf2_abbrev_entry_attr_t* attr = NULL;
997 unsigned long next_sibling = 0;
999 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1001 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1002 switch (attr->attribute) {
1003 case DW_AT_sibling:
1004 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1005 break;
1006 case DW_AT_type:
1008 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1009 ref_type = dwarf2_find_symt_by_ref(ctx->module, ref);
1011 break;
1012 default:
1013 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1014 dwarf2_parse_attr(attr, ctx);
1017 /* FIXME: for now, we hard-wire C++ references to pointers */
1018 symt = &symt_new_pointer(ctx->module, ref_type)->symt;
1020 if (entry->have_child) {
1021 FIXME("Unsupported children\n");
1024 /** set correct data cursor */
1025 dwarf2_check_sibling(ctx, next_sibling);
1027 return symt;
1030 static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_udt* parent)
1032 struct symt* elt_type = NULL;
1033 const char* name = NULL;
1034 unsigned long offset = 0;
1035 unsigned size = 0;
1036 dwarf2_abbrev_entry_attr_t* attr = NULL;
1037 unsigned long next_sibling = 0;
1039 assert( NULL != parent );
1041 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1043 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1044 switch (attr->attribute) {
1045 case DW_AT_sibling:
1046 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1047 break;
1048 case DW_AT_name:
1049 name = dwarf2_parse_attr_as_string(attr, ctx);
1050 TRACE("found name %s\n", name);
1051 break;
1052 case DW_AT_type:
1054 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1055 elt_type = dwarf2_find_symt_by_ref(ctx->module, ref);
1057 break;
1058 case DW_AT_data_member_location:
1060 unsigned long uvalue = 0;
1061 TRACE("found member_location at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1062 /*offset = dwarf2_parse_attr_as_data(attr, ctx);*/
1063 switch (attr->form) {
1064 case DW_FORM_block:
1065 uvalue = dwarf2_leb128_as_unsigned(ctx);
1066 break;
1067 case DW_FORM_block1:
1068 uvalue = dwarf2_parse_byte(ctx);
1069 break;
1070 case DW_FORM_block2:
1071 uvalue = dwarf2_parse_u2(ctx);
1072 break;
1073 case DW_FORM_block4:
1074 uvalue = dwarf2_parse_u4(ctx);
1075 break;
1076 default:
1077 WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1078 dwarf2_parse_attr(attr, ctx);
1080 if (uvalue) {
1081 unsigned char op = dwarf2_parse_byte(ctx);
1082 --uvalue;
1083 switch (op) {
1084 case DW_OP_plus_uconst:
1085 offset = dwarf2_leb128_as_unsigned(ctx);
1086 break;
1087 default:
1088 WARN("Unhandled attr op at %s, for %s, op:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), op);
1089 ctx->data += uvalue;
1091 TRACE("found offset:%lu\n", offset);
1094 break;
1095 case DW_AT_decl_file:
1096 case DW_AT_decl_line:
1097 dwarf2_parse_attr(attr, ctx);
1098 break;
1099 default:
1100 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1101 dwarf2_parse_attr(attr, ctx);
1104 symt_add_udt_element(ctx->module, parent, name, elt_type, offset, size);
1106 if (entry->have_child) {
1107 FIXME("Unsupported children\n");
1110 /** set correct data cursor */
1111 dwarf2_check_sibling(ctx, next_sibling);
1114 static void dwarf2_parse_udt_members(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_udt* symt)
1116 if (entry->have_child) { /** any interest to not have child ? */
1117 while (ctx->data < ctx->end_data) {
1118 dwarf2_abbrev_entry_t* entry = NULL;
1119 unsigned long entry_code;
1120 unsigned long entry_ref = 0;
1122 entry_ref = ctx->data - ctx->data_stream;
1124 entry_code = dwarf2_leb128_as_unsigned(ctx);
1125 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1126 if (0 == entry_code) {
1127 break ;
1130 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1131 assert( NULL != entry );
1133 switch (entry->tag) {
1134 case DW_TAG_member:
1135 dwarf2_parse_udt_member(ctx, entry, symt);
1136 break;
1137 case DW_TAG_enumeration_type:
1138 dwarf2_parse_enumeration_type(ctx, entry);
1139 break;
1140 default:
1142 dwarf2_abbrev_entry_attr_t* attr;
1143 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1144 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1145 dwarf2_parse_attr(attr, ctx);
1148 break;
1154 static struct symt_udt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, enum UdtKind udt)
1156 struct symt_udt* symt = NULL;
1157 const char* name = NULL;
1158 unsigned size = 0;
1159 dwarf2_abbrev_entry_attr_t* attr = NULL;
1160 unsigned long next_sibling = 0;
1162 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1164 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1165 switch (attr->attribute) {
1166 case DW_AT_sibling:
1167 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1168 break;
1169 case DW_AT_name:
1170 name = dwarf2_parse_attr_as_string(attr, ctx);
1171 TRACE("found name %s\n", name);
1172 break;
1173 case DW_AT_byte_size:
1174 size = dwarf2_parse_attr_as_data(attr, ctx);
1175 break;
1176 case DW_AT_decl_file:
1177 case DW_AT_decl_line:
1178 dwarf2_parse_attr(attr, ctx);
1179 break;
1180 default:
1181 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1182 dwarf2_parse_attr(attr, ctx);
1185 symt = symt_new_udt(ctx->module, name, size, udt);
1186 dwarf2_parse_udt_members(ctx, entry, symt);
1188 /** set correct data cursor */
1189 dwarf2_check_sibling(ctx, next_sibling);
1191 return symt;
1194 static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_enum* parent)
1196 const char* name = NULL;
1197 long value = 0;
1198 dwarf2_abbrev_entry_attr_t* attr = NULL;
1200 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1202 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1203 switch (attr->attribute) {
1204 case DW_AT_name:
1205 name = dwarf2_parse_attr_as_string(attr, ctx);
1206 TRACE("found name %s\n", name);
1207 break;
1208 case DW_AT_const_value:
1209 switch (attr->form) {
1210 case DW_FORM_sdata:
1211 value = dwarf2_leb128_as_signed(ctx);
1212 TRACE("found value %ld\n", value);
1213 break;
1214 case DW_FORM_udata:
1215 value = dwarf2_leb128_as_unsigned(ctx);
1216 TRACE("found value %ld\n", value);
1217 break;
1218 default:
1219 WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1220 dwarf2_parse_attr(attr, ctx);
1222 break;
1223 default:
1224 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1225 dwarf2_parse_attr(attr, ctx);
1228 symt_add_enum_element(ctx->module, parent, name, value);
1230 if (entry->have_child) {
1231 FIXME("Unsupported children\n");
1235 static struct symt_enum* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
1237 struct symt_enum* symt = NULL;
1238 const char* name = NULL;
1239 unsigned long size = 0;
1240 dwarf2_abbrev_entry_attr_t* attr = NULL;
1241 unsigned long next_sibling = 0;
1243 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1245 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1246 switch (attr->attribute) {
1247 case DW_AT_sibling:
1248 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1249 break;
1250 case DW_AT_name:
1251 name = dwarf2_parse_attr_as_string(attr, ctx);
1252 TRACE("found name %s\n", name);
1253 break;
1254 case DW_AT_byte_size:
1255 size = dwarf2_parse_attr_as_data(attr, ctx);
1256 break;
1257 case DW_AT_decl_file:
1258 case DW_AT_decl_line:
1259 dwarf2_parse_attr(attr, ctx);
1260 break;
1261 default:
1262 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1263 dwarf2_parse_attr(attr, ctx);
1266 symt = symt_new_enum(ctx->module, name);
1268 if (entry->have_child) { /** any interest to not have child ? */
1269 while (ctx->data < ctx->end_data) {
1270 dwarf2_abbrev_entry_t* entry = NULL;
1271 unsigned long entry_code;
1272 unsigned long entry_ref = 0;
1274 entry_ref = ctx->data - ctx->data_stream;
1276 entry_code = dwarf2_leb128_as_unsigned(ctx);
1277 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1278 if (0 == entry_code) {
1279 break ;
1282 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1283 assert( NULL != entry );
1285 switch (entry->tag) {
1286 case DW_TAG_enumerator:
1287 dwarf2_parse_enumerator(ctx, entry, symt);
1288 break;
1289 default:
1291 dwarf2_abbrev_entry_attr_t* attr;
1292 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1293 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1294 dwarf2_parse_attr(attr, ctx);
1297 break;
1302 /** set correct data cursor */
1303 dwarf2_check_sibling(ctx, next_sibling);
1305 return symt;
1308 static void dwarf2_parse_variable(dwarf2_parse_context_t* ctx,
1309 dwarf2_abbrev_entry_t* entry)
1311 struct symt* var_type = NULL;
1312 dwarf2_abbrev_entry_attr_t* attr = NULL;
1313 const char* name = NULL;
1314 unsigned long next_sibling = 0;
1316 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1318 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1319 switch (attr->attribute) {
1320 case DW_AT_sibling:
1321 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1322 break;
1323 case DW_AT_type:
1325 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1326 var_type = dwarf2_find_symt_by_ref(ctx->module, ref);
1328 break;
1329 case DW_AT_name:
1330 name = dwarf2_parse_attr_as_string(attr, ctx);
1331 TRACE("found name %s\n", name);
1332 break;
1333 case DW_AT_decl_file:
1334 case DW_AT_decl_line:
1335 dwarf2_parse_attr(attr, ctx);
1336 break;
1337 default:
1338 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1339 dwarf2_parse_attr(attr, ctx);
1343 if (entry->have_child) {
1344 FIXME("Unsupported children\n");
1347 /** set correct data cursor */
1348 dwarf2_check_sibling(ctx, next_sibling);
1351 static void dwarf2_parse_subprogram_parameter(dwarf2_parse_context_t* ctx,
1352 dwarf2_abbrev_entry_t* entry,
1353 struct symt_function_signature* sig_type,
1354 struct symt_function* func_type)
1356 struct symt* param_type = NULL;
1357 const char* name = NULL;
1358 dwarf2_abbrev_entry_attr_t* attr = NULL;
1359 unsigned long next_sibling = 0;
1361 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1363 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1364 switch (attr->attribute) {
1365 case DW_AT_sibling:
1366 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1367 break;
1368 case DW_AT_type:
1370 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1371 param_type = dwarf2_find_symt_by_ref(ctx->module, ref);
1373 break;
1374 case DW_AT_name:
1375 name = dwarf2_parse_attr_as_string(attr, ctx);
1376 TRACE("found name %s\n", name);
1377 break;
1378 case DW_AT_decl_file:
1379 case DW_AT_decl_line:
1380 dwarf2_parse_attr(attr, ctx);
1381 break;
1382 case DW_AT_location:
1383 dwarf2_parse_attr(attr, ctx);
1384 break;
1385 default:
1386 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1387 dwarf2_parse_attr(attr, ctx);
1390 if (NULL != sig_type) {
1391 symt_add_function_signature_parameter(ctx->module, sig_type, param_type);
1394 if (entry->have_child) {
1395 FIXME("Unsupported children\n");
1398 /** set correct data cursor */
1399 dwarf2_check_sibling(ctx, next_sibling);
1402 static void dwarf2_parse_inlined_subroutine(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
1404 const char* name = NULL;
1405 unsigned long addr = 0;
1406 unsigned long low_pc = 0;
1407 unsigned long high_pc = 0;
1408 unsigned size = 0;
1409 dwarf2_abbrev_entry_attr_t* attr = NULL;
1410 unsigned long next_sibling = 0;
1412 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1414 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1415 switch (attr->attribute) {
1416 case DW_AT_sibling:
1417 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1418 break;
1419 case DW_AT_low_pc:
1420 low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1421 addr = ctx->module->module.BaseOfImage + low_pc;
1422 break;
1423 case DW_AT_high_pc:
1424 high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1425 size = high_pc - low_pc;
1426 break;
1427 case DW_AT_name:
1428 name = dwarf2_parse_attr_as_string(attr, ctx);
1429 TRACE("found name %s\n", name);
1430 break;
1431 case DW_AT_decl_file:
1432 case DW_AT_decl_line:
1433 dwarf2_parse_attr(attr, ctx);
1434 break;
1435 default:
1436 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1437 dwarf2_parse_attr(attr, ctx);
1441 if (entry->have_child) { /** any interest to not have child ? */
1442 while (ctx->data < ctx->end_data) {
1443 dwarf2_abbrev_entry_t* entry = NULL;
1444 unsigned long entry_code;
1445 unsigned long entry_ref = 0;
1447 entry_ref = ctx->data - ctx->data_stream;
1449 entry_code = dwarf2_leb128_as_unsigned(ctx);
1450 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1451 if (0 == entry_code) {
1452 break ;
1455 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1456 assert( NULL != entry );
1458 switch (entry->tag) {
1459 case DW_TAG_formal_parameter:
1460 dwarf2_parse_subprogram_parameter(ctx, entry, NULL, NULL);
1461 break;
1462 case DW_TAG_variable:
1463 dwarf2_parse_variable(ctx, entry);
1464 break;
1465 case DW_TAG_label:
1466 default:
1468 dwarf2_abbrev_entry_attr_t* attr;
1469 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1470 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1471 dwarf2_parse_attr(attr, ctx);
1474 break;
1479 /** set correct data cursor */
1480 dwarf2_check_sibling(ctx, next_sibling);
1484 static void dwarf2_parse_subprogram_block(dwarf2_parse_context_t* ctx,
1485 dwarf2_abbrev_entry_t* entry,
1486 struct symt_function_signature* sig_type,
1487 struct symt_function* func_type)
1489 dwarf2_abbrev_entry_attr_t* attr = NULL;
1490 const char* name = NULL;
1491 unsigned long next_sibling = 0;
1493 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1495 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1496 switch (attr->attribute) {
1497 case DW_AT_sibling:
1498 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1499 break;
1500 case DW_AT_name:
1501 name = dwarf2_parse_attr_as_string(attr, ctx);
1502 TRACE("found name %s\n", name);
1503 break;
1504 case DW_AT_decl_file:
1505 case DW_AT_decl_line:
1506 dwarf2_parse_attr(attr, ctx);
1507 break;
1508 case DW_AT_ranges: /** what to do ? */
1509 dwarf2_parse_attr(attr, ctx);
1510 break;
1511 default:
1512 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1513 dwarf2_parse_attr(attr, ctx);
1517 if (entry->have_child) { /** any interest to not have child ? */
1518 while (ctx->data < ctx->end_data) {
1519 dwarf2_abbrev_entry_t* entry = NULL;
1520 unsigned long entry_code;
1521 unsigned long entry_ref = 0;
1523 entry_ref = ctx->data - ctx->data_stream;
1525 entry_code = dwarf2_leb128_as_unsigned(ctx);
1526 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1527 if (0 == entry_code) {
1528 break ;
1531 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1532 assert( NULL != entry );
1534 switch (entry->tag) {
1535 case DW_TAG_inlined_subroutine:
1536 dwarf2_parse_inlined_subroutine(ctx, entry);
1537 break;
1538 case DW_TAG_variable:
1539 dwarf2_parse_variable(ctx, entry);
1540 break;
1541 case DW_TAG_label:
1542 default:
1544 dwarf2_abbrev_entry_attr_t* attr;
1545 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1546 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1547 dwarf2_parse_attr(attr, ctx);
1550 break;
1555 /** set correct data cursor */
1556 dwarf2_check_sibling(ctx, next_sibling);
1559 static void dwarf2_parse_subprogram_content(dwarf2_parse_context_t* ctx,
1560 dwarf2_abbrev_entry_t* entry,
1561 struct symt_function_signature* sig_type,
1562 struct symt_function* func_type)
1564 if (entry->have_child) { /** any interest to not have child ? */
1565 while (ctx->data < ctx->end_data) {
1566 dwarf2_abbrev_entry_t* entry = NULL;
1567 unsigned long entry_code;
1568 unsigned long entry_ref = 0;
1570 entry_ref = ctx->data - ctx->data_stream;
1572 entry_code = dwarf2_leb128_as_unsigned(ctx);
1573 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1574 if (0 == entry_code) {
1575 break ;
1578 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1579 assert( NULL != entry );
1581 switch (entry->tag) {
1582 case DW_TAG_formal_parameter:
1583 dwarf2_parse_subprogram_parameter(ctx, entry, sig_type, func_type);
1584 break;
1585 case DW_TAG_lexical_block:
1586 dwarf2_parse_subprogram_block(ctx, entry, sig_type, func_type);
1587 break;
1588 case DW_TAG_variable:
1589 dwarf2_parse_variable(ctx, entry);
1590 break;
1591 case DW_TAG_label:
1592 default:
1594 dwarf2_abbrev_entry_attr_t* attr;
1595 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1596 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1597 dwarf2_parse_attr(attr, ctx);
1600 break;
1606 static struct symt_function* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_compiland* compiland)
1608 struct symt_function* func_type = NULL;
1609 const char* name = NULL;
1610 struct symt* ret_type = NULL;
1611 struct symt_function_signature* sig_type = NULL;
1612 unsigned long addr = 0;
1613 unsigned long low_pc = 0;
1614 unsigned long high_pc = 0;
1615 unsigned size = 0;
1616 unsigned char is_decl = 0;
1617 unsigned char inl_flags = 0;
1618 unsigned char decl_file = 0;
1619 unsigned char decl_line = 0;
1620 dwarf2_abbrev_entry_attr_t* attr = NULL;
1621 unsigned long next_sibling = 0;
1622 enum CV_call_e call_conv = CV_CALL_FAR_C; /* FIXME: assuming C source code */
1623 unsigned cc;
1625 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1627 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1628 switch (attr->attribute) {
1629 case DW_AT_sibling:
1630 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1631 break;
1632 case DW_AT_low_pc:
1633 low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1634 addr = ctx->module->module.BaseOfImage + low_pc;
1635 break;
1636 case DW_AT_high_pc:
1637 high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1638 size = high_pc - low_pc;
1639 break;
1640 case DW_AT_name:
1641 name = dwarf2_parse_attr_as_string(attr, ctx);
1642 TRACE("found name %s\n", name);
1643 break;
1644 case DW_AT_type:
1646 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1647 ret_type = dwarf2_find_symt_by_ref(ctx->module, ref);
1649 break;
1650 case DW_AT_declaration:
1651 is_decl = dwarf2_parse_byte(ctx);
1652 break;
1653 case DW_AT_inline:
1654 inl_flags = dwarf2_parse_byte(ctx);
1655 break;
1656 case DW_AT_calling_convention:
1657 switch (cc = dwarf2_parse_byte(ctx))
1659 case DW_CC_normal: break;
1660 case DW_CC_nocall: call_conv = -1;
1661 default: FIXME("Unsupported calling convention %d\n", cc);
1663 break;
1664 /* not work yet, need parsing .debug_line and using Compil Unit stmt_list
1665 case DW_AT_decl_file:
1666 decl_file = dwarf2_parse_byte(ctx);
1667 break;
1668 case DW_AT_decl_line:
1669 decl_line = dwarf2_parse_byte(ctx);
1670 break;
1672 default:
1673 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1674 dwarf2_parse_attr(attr, ctx);
1677 sig_type = symt_new_function_signature(ctx->module, ret_type, call_conv);
1678 if (!is_decl) {
1679 func_type = symt_new_function(ctx->module, compiland, name, addr, size, &sig_type->symt);
1680 if (low_pc && high_pc) {
1681 symt_add_function_point(ctx->module, func_type, SymTagFuncDebugStart, low_pc, NULL);
1682 symt_add_function_point(ctx->module, func_type, SymTagFuncDebugEnd, high_pc, NULL);
1684 if (decl_file && decl_line) {
1685 symt_add_func_line(ctx->module, func_type, decl_file, decl_line, low_pc);
1688 dwarf2_parse_subprogram_content(ctx, entry, sig_type, func_type);
1689 symt_normalize_function(ctx->module, func_type);
1691 /** set correct data cursor */
1692 dwarf2_check_sibling(ctx, next_sibling);
1694 return func_type;
1697 static void dwarf2_parse_compiland_content(dwarf2_parse_context_t* ctx, const dwarf2_abbrev_entry_t* entry, struct symt_compiland* compiland)
1699 if (entry->have_child) { /** any interest to not have child ? */
1700 while (ctx->data < ctx->end_data) {
1701 dwarf2_abbrev_entry_t* entry = NULL;
1702 unsigned long entry_code;
1703 unsigned long entry_ref = 0;
1705 entry_ref = ctx->data - ctx->data_stream;
1707 entry_code = dwarf2_leb128_as_unsigned(ctx);
1708 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1709 if (0 == entry_code) {
1710 break ;
1713 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1714 assert( NULL != entry );
1716 switch (entry->tag) {
1717 case DW_TAG_typedef:
1718 dwarf2_parse_typedef(ctx, entry);
1719 break;
1720 case DW_TAG_base_type:
1721 dwarf2_parse_base_type(ctx, entry);
1722 break;
1723 case DW_TAG_pointer_type:
1724 dwarf2_parse_pointer_type(ctx, entry);
1725 break;
1726 case DW_TAG_class_type:
1727 dwarf2_parse_udt_type(ctx, entry, UdtClass);
1728 break;
1729 case DW_TAG_structure_type:
1730 dwarf2_parse_udt_type(ctx, entry, UdtStruct);
1731 break;
1732 case DW_TAG_union_type:
1733 dwarf2_parse_udt_type(ctx, entry, UdtUnion);
1734 break;
1735 case DW_TAG_array_type:
1736 dwarf2_parse_array_type(ctx, entry);
1737 break;
1738 case DW_TAG_const_type:
1739 dwarf2_parse_const_type(ctx, entry);
1740 break;
1741 case DW_TAG_reference_type:
1742 dwarf2_parse_reference_type(ctx, entry);
1743 break;
1744 case DW_TAG_enumeration_type:
1745 dwarf2_parse_enumeration_type(ctx, entry);
1746 break;
1747 case DW_TAG_subprogram:
1748 dwarf2_parse_subprogram(ctx, entry, compiland);
1749 break;
1751 default:
1753 dwarf2_abbrev_entry_attr_t* attr;
1754 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1755 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1756 dwarf2_parse_attr(attr, ctx);
1759 break;
1765 static struct symt_compiland* dwarf2_parse_compiland(dwarf2_parse_context_t* ctx, const dwarf2_abbrev_entry_t* entry)
1767 struct symt_compiland* compiland = NULL;
1768 const char* name = NULL;
1769 unsigned long next_sibling = 0;
1770 dwarf2_abbrev_entry_attr_t* attr = NULL;
1772 TRACE("beginning at Ox%x, for %lu\n", ctx->data - ctx->start_data, entry->entry_code);
1774 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1775 switch (attr->attribute) {
1776 case DW_AT_sibling:
1777 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1778 break;
1779 case DW_AT_name:
1780 name = dwarf2_parse_attr_as_string(attr, ctx);
1781 TRACE("found name %s\n", name);
1782 break;
1783 default:
1784 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1785 dwarf2_parse_attr(attr, ctx);
1788 compiland = symt_new_compiland(ctx->module, name);
1789 dwarf2_parse_compiland_content(ctx, entry, compiland);
1791 dwarf2_check_sibling(ctx, next_sibling);
1793 return compiland;
1796 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
1797 const unsigned char* debug, unsigned int debug_size,
1798 const unsigned char* abbrev, unsigned int abbrev_size,
1799 const unsigned char* str, unsigned int str_sz)
1801 const unsigned char* comp_unit_cursor = debug;
1802 const unsigned char* end_debug = debug + debug_size;
1804 while (comp_unit_cursor < end_debug) {
1805 const dwarf2_comp_unit_stream_t* comp_unit_stream;
1806 dwarf2_comp_unit_t comp_unit;
1807 dwarf2_parse_context_t ctx;
1808 dwarf2_parse_context_t abbrev_ctx;
1809 struct symt_compiland* compiland = NULL;
1810 dwarf2_debug_info_t* di;
1812 comp_unit_stream = (const dwarf2_comp_unit_stream_t*) comp_unit_cursor;
1814 comp_unit.length = *(unsigned long*) comp_unit_stream->length;
1815 comp_unit.version = *(unsigned short*) comp_unit_stream->version;
1816 comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset;
1817 comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size;
1819 TRACE("Compilation Unit Herder found at 0x%x:\n", comp_unit_cursor - debug);
1820 TRACE("- length: %lu\n", comp_unit.length);
1821 TRACE("- version: %u\n", comp_unit.version);
1822 TRACE("- abbrev_offset: %lu\n", comp_unit.abbrev_offset);
1823 TRACE("- word_size: %u\n", comp_unit.word_size);
1825 pool_init(&ctx.pool, 65536);
1826 ctx.module = module;
1827 ctx.data_stream = debug;
1828 ctx.data = ctx.start_data = comp_unit_cursor + sizeof(dwarf2_comp_unit_stream_t);
1829 ctx.offset = comp_unit_cursor - debug;
1830 ctx.word_size = comp_unit.word_size;
1831 ctx.str_section = str;
1833 comp_unit_cursor += comp_unit.length + sizeof(unsigned);
1834 ctx.end_data = comp_unit_cursor;
1836 if (2 != comp_unit.version) {
1837 WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", comp_unit.version);
1838 continue ;
1841 abbrev_ctx.data_stream = abbrev;
1842 abbrev_ctx.data = abbrev_ctx.start_data = abbrev + comp_unit.abbrev_offset;
1843 abbrev_ctx.end_data = abbrev + abbrev_size;
1844 abbrev_ctx.offset = comp_unit.abbrev_offset;
1845 abbrev_ctx.str_section = str;
1846 dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
1848 sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128);
1849 dwarf2_read_one_debug_info(&ctx, &di);
1850 ctx.data = ctx.start_data; /* FIXME */
1852 while (ctx.data < ctx.end_data) {
1853 const dwarf2_abbrev_entry_t* entry = NULL;
1854 unsigned long entry_code;
1855 unsigned long entry_ref = 0;
1857 entry_ref = ctx.data - ctx.data_stream;
1859 entry_code = dwarf2_leb128_as_unsigned(&ctx);
1860 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1861 if (0 == entry_code) {
1862 continue ;
1864 entry = dwarf2_abbrev_table_find_entry(&ctx.abbrev_table, entry_code);
1865 if (NULL == entry) {
1866 WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, entry_ref);
1867 pool_destroy(&ctx.pool);
1868 return FALSE;
1871 switch (entry->tag) {
1872 case DW_TAG_compile_unit:
1873 compiland = dwarf2_parse_compiland(&ctx, entry);
1874 break;
1875 default:
1877 dwarf2_abbrev_entry_attr_t* attr;
1878 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(&ctx), entry->entry_code);
1879 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1880 dwarf2_parse_attr(attr, &ctx);
1883 break;
1886 pool_destroy(&ctx.pool);
1889 module->module.SymType = SymDia;
1890 return TRUE;