dbghelp: Dwarf merge parsing of UDT.
[wine/multimedia.git] / dlls / dbghelp / dwarf.c
blob9dc0b7ee8475a2a633954adecc1fda584986cce8
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 sparse_array abbrev_table;
135 struct sparse_array debug_info_table;
136 const unsigned char* data_stream;
137 const unsigned char* data;
138 const unsigned char* start_data;
139 const unsigned char* end_data;
140 const unsigned char* str_section;
141 unsigned long offset;
142 unsigned char word_size;
143 } dwarf2_parse_context_t;
145 /* forward declarations */
146 static struct symt_enum* dwarf2_parse_enumeration_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx);
148 static unsigned char dwarf2_parse_byte(dwarf2_parse_context_t* ctx)
150 unsigned char uvalue = *(const unsigned char*) ctx->data;
151 ctx->data += 1;
152 return uvalue;
155 static unsigned short dwarf2_parse_u2(dwarf2_parse_context_t* ctx)
157 unsigned short uvalue = *(const unsigned short*) ctx->data;
158 ctx->data += 2;
159 return uvalue;
162 static unsigned long dwarf2_parse_u4(dwarf2_parse_context_t* ctx)
164 unsigned long uvalue = *(const unsigned int*) ctx->data;
165 ctx->data += 4;
166 return uvalue;
169 static unsigned long dwarf2_leb128_as_unsigned(dwarf2_parse_context_t* ctx)
171 unsigned long ret = 0;
172 unsigned char byte;
173 unsigned shift = 0;
175 assert( NULL != ctx );
177 while (1) {
178 byte = dwarf2_parse_byte(ctx);
179 ret |= (byte & 0x7f) << shift;
180 shift += 7;
181 if (0 == (byte & 0x80)) { break ; }
184 return ret;
187 static long dwarf2_leb128_as_signed(dwarf2_parse_context_t* ctx)
189 long ret = 0;
190 unsigned char byte;
191 unsigned shift = 0;
192 const unsigned size = sizeof(int) * 8;
194 assert( NULL != ctx );
196 while (1) {
197 byte = dwarf2_parse_byte(ctx);
198 ret |= (byte & 0x7f) << shift;
199 shift += 7;
200 if (0 == (byte & 0x80)) { break ; }
202 /* as spec: sign bit of byte is 2nd high order bit (80x40)
203 * -> 0x80 is used as flag.
205 if ((shift < size) && (byte & 0x40)) {
206 ret |= - (1 << shift);
208 return ret;
211 static unsigned long dwarf2_parse_addr(dwarf2_parse_context_t* ctx)
213 unsigned long ret;
215 switch (ctx->word_size)
217 case 4:
218 ret = dwarf2_parse_u4(ctx);
219 break;
220 default:
221 FIXME("Unsupported Word Size %u\n", ctx->word_size);
222 ret = 0;
224 return ret;
227 static const char* dwarf2_debug_ctx(dwarf2_parse_context_t* ctx)
229 /*return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->start_data, ctx->level); */
230 return wine_dbg_sprintf("ctx(0x%x)", ctx->data - ctx->data_stream);
232 static const char* dwarf2_debug_attr(dwarf2_abbrev_entry_attr_t* attr)
234 return wine_dbg_sprintf("attr(attr:0x%lx,form:0x%lx)", attr->attribute, attr->form);
237 static void dwarf2_check_sibling(dwarf2_parse_context_t* ctx, unsigned long next_sibling)
239 if (0 < next_sibling && ctx->data != ctx->data_stream + next_sibling) {
240 if ((ctx->data + 1) != ctx->data_stream + next_sibling) {
241 /** padding check */
242 WARN("cursor error for %s should be sibling<0x%lx>\n", dwarf2_debug_ctx(ctx), next_sibling);
244 ctx->data = ctx->data_stream + next_sibling;
249 static dwarf2_abbrev_entry_t*
250 dwarf2_abbrev_table_find_entry(struct sparse_array* abbrev_table,
251 unsigned long entry_code)
253 assert( NULL != abbrev_table );
254 return sparse_array_find(abbrev_table, entry_code);
257 static void dwarf2_parse_abbrev_set(dwarf2_parse_context_t* abbrev_ctx,
258 struct sparse_array* abbrev_table,
259 struct pool* pool)
261 unsigned long entry_code;
262 dwarf2_abbrev_entry_t* abbrev_entry;
263 dwarf2_abbrev_entry_attr_t* new = NULL;
264 dwarf2_abbrev_entry_attr_t* last = NULL;
265 unsigned long attribute;
266 unsigned long form;
268 TRACE("%s, end at %p\n", dwarf2_debug_ctx(abbrev_ctx), abbrev_ctx->end_data);
270 assert( NULL != abbrev_ctx );
272 sparse_array_init(abbrev_table, sizeof(dwarf2_abbrev_entry_t), 32);
273 while (abbrev_ctx->data < abbrev_ctx->end_data)
275 TRACE("now at %s\n", dwarf2_debug_ctx(abbrev_ctx));
276 entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx);
277 TRACE("found entry_code %lu\n", entry_code);
278 if (!entry_code)
280 TRACE("NULL entry code at %s\n", dwarf2_debug_ctx(abbrev_ctx));
281 break;
283 abbrev_entry = sparse_array_add(abbrev_table, entry_code, pool);
284 assert( NULL != abbrev_entry );
286 abbrev_entry->entry_code = entry_code;
287 abbrev_entry->tag = dwarf2_leb128_as_unsigned(abbrev_ctx);
288 abbrev_entry->have_child = dwarf2_parse_byte(abbrev_ctx);
289 abbrev_entry->attrs = NULL;
290 abbrev_entry->num_attr = 0;
292 TRACE("table:(%p,#%u) entry_code(%lu) tag(0x%lx) have_child(%u) -> %p\n",
293 abbrev_table, sparse_array_length(abbrev_table),
294 entry_code, abbrev_entry->tag, abbrev_entry->have_child, abbrev_entry);
296 last = NULL;
297 while (1)
299 attribute = dwarf2_leb128_as_unsigned(abbrev_ctx);
300 form = dwarf2_leb128_as_unsigned(abbrev_ctx);
301 if (!attribute) break;
303 new = pool_alloc(pool, sizeof(dwarf2_abbrev_entry_attr_t));
304 assert(new);
306 new->attribute = attribute;
307 new->form = form;
308 new->next = NULL;
309 if (abbrev_entry->attrs) last->next = new;
310 else abbrev_entry->attrs = new;
311 last = new;
312 abbrev_entry->num_attr++;
315 TRACE("found %u entries\n", sparse_array_length(abbrev_table));
318 static const char* dwarf2_parse_attr_as_string(dwarf2_abbrev_entry_attr_t* attr,
319 dwarf2_parse_context_t* ctx)
321 const char* ret = NULL;
322 switch (attr->form) {
323 case DW_FORM_string:
324 ret = (const char*) ctx->data;
325 ctx->data += strlen(ret) + 1;
326 break;
327 case DW_FORM_strp:
329 unsigned long offset = dwarf2_parse_u4(ctx);
330 ret = (const char*) ctx->str_section + offset;
331 /*FIXME("Unsupported indirect string format offset 0x%lx (in .debug_str)\n", offset);*/
333 break;
334 default:
335 ERR("Unsupported string format 0x%lx for attr 0x%lx\n", attr->form, attr->attribute);
337 return ret;
340 static unsigned long dwarf2_parse_attr_as_addr(dwarf2_abbrev_entry_attr_t* attr,
341 dwarf2_parse_context_t* ctx)
343 unsigned long offset = 0;
344 switch (ctx->word_size) {
345 case 4:
346 offset = *(const unsigned int*) ctx->data;
347 break;
348 case 8:
349 default:
350 FIXME("Unsupported Word Size %u\n", ctx->word_size);
352 ctx->data += ctx->word_size;
353 return offset;
356 static unsigned long dwarf2_parse_attr_as_ref(dwarf2_abbrev_entry_attr_t* attr,
357 dwarf2_parse_context_t* ctx)
359 unsigned long uvalue = 0;
360 switch (attr->form) {
361 case DW_FORM_ref1:
362 uvalue = ctx->offset + dwarf2_parse_byte(ctx);
363 TRACE("ref1<0x%lx>\n", uvalue);
364 break;
366 case DW_FORM_ref2:
367 uvalue = ctx->offset + dwarf2_parse_u2(ctx);
368 TRACE("ref2<0x%lx>\n", uvalue);
369 break;
371 case DW_FORM_ref4:
372 uvalue = ctx->offset + dwarf2_parse_u4(ctx);
373 TRACE("ref4<0x%lx>\n", uvalue);
374 break;
376 case DW_FORM_ref8:
377 /* FIXME: 64bits support */
379 uvalue = ctx->offset + dwarf2_parse_u8(ctx);
380 TRACE("ref8<0x%lx>\n", uvalue);
382 ctx->data += 8;
383 break;
385 return uvalue;
389 static unsigned long dwarf2_parse_attr_as_data(dwarf2_abbrev_entry_attr_t* attr,
390 dwarf2_parse_context_t* ctx)
392 unsigned long uvalue = 0;
393 switch (attr->form) {
394 case DW_FORM_data1:
395 uvalue = dwarf2_parse_byte(ctx);
396 TRACE("data1<%lu>\n", uvalue);
397 break;
399 case DW_FORM_data2:
400 uvalue = dwarf2_parse_u2(ctx);
401 TRACE("data2<%lu>\n", uvalue);
402 break;
404 case DW_FORM_data4:
405 uvalue = dwarf2_parse_u4(ctx);
406 TRACE("data4<%lu>\n", uvalue);
407 break;
409 case DW_FORM_data8:
410 FIXME("Unsupported 64bits support\n");
411 ctx->data += 8;
412 break;
414 return uvalue;
417 static void dwarf2_parse_attr(dwarf2_abbrev_entry_attr_t* attr,
418 dwarf2_parse_context_t* ctx)
420 const unsigned long attribute = attr->attribute;
421 const unsigned long form = attr->form;
422 unsigned long uvalue = 0;
423 long svalue = 0;
424 const char* str = NULL;
426 TRACE("(attr:0x%lx,form:0x%lx)\n", attribute, form);
428 switch (form) {
429 case DW_FORM_ref_addr:
430 case DW_FORM_addr:
431 uvalue = dwarf2_parse_attr_as_addr(attr, ctx);
432 break;
434 case DW_FORM_flag:
435 uvalue = dwarf2_parse_byte(ctx);
436 TRACE("flag<0x%lx>\n", uvalue);
437 break;
439 case DW_FORM_data1:
440 uvalue = dwarf2_parse_byte(ctx);
441 TRACE("data1<%lu>\n", uvalue);
442 break;
444 case DW_FORM_data2:
445 uvalue = dwarf2_parse_u2(ctx);
446 TRACE("data2<%lu>\n", uvalue);
447 break;
449 case DW_FORM_data4:
450 uvalue = dwarf2_parse_u4(ctx);
451 TRACE("data4<%lu>\n", uvalue);
452 break;
454 case DW_FORM_ref1:
455 case DW_FORM_ref2:
456 case DW_FORM_ref4:
457 case DW_FORM_ref8:
458 uvalue = dwarf2_parse_attr_as_ref(attr, ctx);
459 /*TRACE("ref<0x%lx>\n", ctx->offset + uvalue);*/
460 break;
462 case DW_FORM_data8:
463 FIXME("Unsupported 64bits support\n");
464 ctx->data += 8;
465 break;
467 case DW_FORM_sdata:
468 svalue = dwarf2_leb128_as_signed(ctx);
469 break;
471 case DW_FORM_ref_udata:
472 case DW_FORM_udata:
473 uvalue = dwarf2_leb128_as_unsigned(ctx);
474 break;
476 case DW_FORM_string:
477 case DW_FORM_strp:
478 str = dwarf2_parse_attr_as_string(attr, ctx);
479 TRACE("string<%s>\n", str);
480 break;
482 case DW_FORM_block:
483 uvalue = dwarf2_leb128_as_unsigned(ctx);
484 ctx->data += uvalue;
485 break;
487 case DW_FORM_block1:
488 uvalue = dwarf2_parse_byte(ctx);
489 ctx->data += uvalue;
490 break;
492 case DW_FORM_block2:
493 uvalue = dwarf2_parse_u2(ctx);
494 ctx->data += uvalue;
495 break;
497 case DW_FORM_block4:
498 uvalue = dwarf2_parse_u4(ctx);
499 ctx->data += uvalue;
500 break;
502 default:
503 break;
507 static void dwarf2_parse_attr_into_di(dwarf2_parse_context_t* ctx,
508 const dwarf2_abbrev_entry_attr_t* abbrev_attr,
509 union attribute* attr)
512 TRACE("(attr:0x%lx,form:0x%lx)\n", abbrev_attr->attribute, abbrev_attr->form);
514 switch (abbrev_attr->form) {
515 case DW_FORM_ref_addr:
516 case DW_FORM_addr:
517 attr->uvalue = dwarf2_parse_addr(ctx);
518 TRACE("addr<0x%lx>\n", attr->uvalue);
519 break;
521 case DW_FORM_flag:
522 attr->uvalue = dwarf2_parse_byte(ctx);
523 TRACE("flag<0x%lx>\n", attr->uvalue);
524 break;
526 case DW_FORM_data1:
527 attr->uvalue = dwarf2_parse_byte(ctx);
528 TRACE("data1<%lu>\n", attr->uvalue);
529 break;
531 case DW_FORM_data2:
532 attr->uvalue = dwarf2_parse_u2(ctx);
533 TRACE("data2<%lu>\n", attr->uvalue);
534 break;
536 case DW_FORM_data4:
537 attr->uvalue = dwarf2_parse_u4(ctx);
538 TRACE("data4<%lu>\n", attr->uvalue);
539 break;
541 case DW_FORM_data8:
542 FIXME("Unhandled 64bits support\n");
543 ctx->data += 8;
544 break;
546 case DW_FORM_ref1:
547 attr->uvalue = ctx->offset + dwarf2_parse_byte(ctx);
548 TRACE("ref1<0x%lx>\n", attr->uvalue);
549 break;
551 case DW_FORM_ref2:
552 attr->uvalue = ctx->offset + dwarf2_parse_u2(ctx);
553 TRACE("ref2<0x%lx>\n", attr->uvalue);
554 break;
556 case DW_FORM_ref4:
557 attr->uvalue = ctx->offset + dwarf2_parse_u4(ctx);
558 TRACE("ref4<0x%lx>\n", attr->uvalue);
559 break;
561 case DW_FORM_ref8:
562 FIXME("Unhandled 64 bit support\n");
563 ctx->data += 8;
564 break;
566 case DW_FORM_sdata:
567 attr->svalue = dwarf2_leb128_as_signed(ctx);
568 break;
570 case DW_FORM_ref_udata:
571 attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
572 break;
574 case DW_FORM_udata:
575 attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
576 break;
578 case DW_FORM_string:
579 attr->string = (const char*)ctx->data;
580 ctx->data += strlen(attr->string) + 1;
581 TRACE("string<%s>\n", attr->string);
582 break;
584 case DW_FORM_strp:
586 unsigned long offset = dwarf2_parse_u4(ctx);
587 attr->string = (const char*)ctx->str_section + offset;
589 TRACE("strp<%s>\n", attr->string);
590 break;
591 case DW_FORM_block:
592 attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
593 ctx->data += attr->uvalue;
594 break;
596 case DW_FORM_block1:
597 attr->uvalue = dwarf2_parse_byte(ctx);
598 ctx->data += attr->uvalue;
599 break;
601 case DW_FORM_block2:
602 attr->uvalue = dwarf2_parse_u2(ctx);
603 ctx->data += attr->uvalue;
604 break;
606 case DW_FORM_block4:
607 attr->uvalue = dwarf2_parse_u4(ctx);
608 ctx->data += attr->uvalue;
609 break;
611 default:
612 FIXME("Unhandled attribute form %lx\n", abbrev_attr->form);
613 break;
617 static struct symt* dwarf2_find_symt_by_ref(struct module* module, unsigned long ref)
619 WARN("want ref<0x%lx>\n", ref);
620 return NULL;
623 static struct symt* dwarf2_add_symt_ref(struct module* module, unsigned long ref, struct symt* symt)
625 if (NULL != symt) return NULL;
626 return NULL;
629 /******************************************************************
630 * dwarf2_read_one_debug_info
632 * Loads into memory one debug info entry, and recursively its children (if any)
634 static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx,
635 dwarf2_debug_info_t** pdi)
637 const dwarf2_abbrev_entry_t*abbrev;
638 unsigned long entry_code;
639 unsigned long offset;
640 dwarf2_debug_info_t* di;
641 dwarf2_debug_info_t* child;
642 dwarf2_debug_info_t** where;
643 dwarf2_abbrev_entry_attr_t* attr;
644 unsigned i;
646 offset = ctx->data - ctx->data_stream;
647 entry_code = dwarf2_leb128_as_unsigned(ctx);
648 TRACE("found entry_code %lu at 0x%lx\n", entry_code, offset);
649 if (!entry_code)
651 *pdi = NULL;
652 return TRUE;
654 abbrev = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
655 if (!abbrev)
657 WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, offset);
658 return FALSE;
660 di = sparse_array_add(&ctx->debug_info_table, offset, &ctx->pool);
661 if (!di) return FALSE;
662 di->offset = offset;
663 di->abbrev = abbrev;
664 di->symt = NULL;
666 if (abbrev->num_attr)
668 di->attributes = pool_alloc(&ctx->pool,
669 abbrev->num_attr * sizeof(union attribute));
670 for (i = 0, attr = abbrev->attrs; attr; i++, attr = attr->next)
672 dwarf2_parse_attr_into_di(ctx, attr, &di->attributes[i]);
675 else di->attributes = NULL;
676 if (abbrev->have_child)
678 vector_init(&di->children, sizeof(dwarf2_debug_info_t*), 16);
679 while (ctx->data < ctx->end_data)
681 if (!dwarf2_read_one_debug_info(ctx, &child)) return FALSE;
682 if (!child) break;
683 where = vector_add(&di->children, &ctx->pool);
684 if (!where) return FALSE;
685 *where = child;
688 *pdi = di;
689 return TRUE;
692 static struct symt_basic* dwarf2_parse_base_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
694 struct symt_basic* symt = NULL;
695 const char* name = NULL;
696 unsigned size = 0;
697 unsigned encoding = 0;
698 enum BasicType bt;
699 dwarf2_abbrev_entry_attr_t* attr = NULL;
701 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
703 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
704 switch (attr->attribute) {
705 case DW_AT_name:
706 name = dwarf2_parse_attr_as_string(attr, ctx);
707 TRACE("found name %s\n", name);
708 break;
709 case DW_AT_byte_size:
710 size = dwarf2_parse_attr_as_data(attr, ctx);
711 break;
712 case DW_AT_encoding:
713 encoding = dwarf2_parse_byte(ctx);
714 break;
715 default:
716 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
717 dwarf2_parse_attr(attr, ctx);
720 switch (encoding) {
721 case DW_ATE_void: bt = btVoid; break;
722 case DW_ATE_address: bt = btULong; break;
723 case DW_ATE_boolean: bt = btBool; break;
724 case DW_ATE_complex_float: bt = btComplex; break;
725 case DW_ATE_float: bt = btFloat; break;
726 case DW_ATE_signed: bt = btInt; break;
727 case DW_ATE_unsigned: bt = btUInt; break;
728 case DW_ATE_signed_char: bt = btChar; break;
729 case DW_ATE_unsigned_char: bt = btChar; break;
730 default:
731 bt = btNoType;
733 /*TRACE("symt_new_basic(%p, %u, %s, %u)", module, bt, name, size);*/
734 symt = symt_new_basic(module, bt, name, size);
736 if (entry->have_child) {
737 FIXME("Unsupported children\n");
739 return symt;
742 static struct symt_typedef* dwarf2_parse_typedef(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
744 struct symt_typedef* symt = NULL;
745 struct symt* ref_type = NULL;
746 const char* name = NULL;
747 dwarf2_abbrev_entry_attr_t* attr = NULL;
749 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
751 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
752 switch (attr->attribute) {
753 case DW_AT_name:
754 name = dwarf2_parse_attr_as_string(attr, ctx);
755 TRACE("found name %s\n", name);
756 break;
757 case DW_AT_type:
759 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
760 ref_type = dwarf2_find_symt_by_ref(module, ref);
762 break;
763 case DW_AT_decl_file:
764 case DW_AT_decl_line:
765 dwarf2_parse_attr(attr, ctx);
766 break;
767 default:
768 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
769 dwarf2_parse_attr(attr, ctx);
772 if (NULL != name) {
773 symt = symt_new_typedef(module, ref_type, name);
776 if (entry->have_child) {
777 FIXME("Unsupported children\n");
779 return symt;
782 static struct symt_pointer* dwarf2_parse_pointer_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
784 struct symt_pointer* symt = NULL;
785 struct symt* ref_type = NULL;
786 unsigned size = 0;
787 dwarf2_abbrev_entry_attr_t* attr = NULL;
789 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
791 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
792 switch (attr->attribute) {
793 case DW_AT_byte_size:
794 size = dwarf2_parse_attr_as_data(attr, ctx);
795 break;
796 case DW_AT_type:
798 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
799 ref_type = dwarf2_find_symt_by_ref(module, ref);
801 break;
802 default:
803 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
804 dwarf2_parse_attr(attr, ctx);
807 symt = symt_new_pointer(module, ref_type);
809 if (entry->have_child) {
810 FIXME("Unsupported children\n");
812 return symt;
815 static void dwarf2_parse_array_subrange_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_array* parent)
817 unsigned min = 0;
818 unsigned max = 0;
819 struct symt* idx_type = NULL;
820 dwarf2_abbrev_entry_attr_t* attr = NULL;
822 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
824 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
825 switch (attr->attribute) {
826 case DW_AT_type:
828 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
829 idx_type = dwarf2_find_symt_by_ref(module, ref);
830 /** check if idx_type is a basic_type integer */
832 break;
833 case DW_AT_lower_bound:
834 TRACE("%s %s, lower_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
835 min = dwarf2_parse_attr_as_data(attr, ctx);
836 break;
837 case DW_AT_upper_bound:
838 TRACE("%s %s, upper_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
839 max = dwarf2_parse_attr_as_data(attr, ctx);
840 break;
841 case DW_AT_count:
842 TRACE("%s %s, count min:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), min);
843 max = min + dwarf2_parse_attr_as_data(attr, ctx);
844 break;
845 default:
846 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
847 dwarf2_parse_attr(attr, ctx);
850 parent->start = min;
851 parent->end = max;
852 parent->index_type = idx_type;
854 TRACE("found min:%u max:%u\n", min, max);
856 if (entry->have_child) {
857 FIXME("Unsupported children\n");
862 static struct symt_array* dwarf2_parse_array_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
864 struct symt_array* symt = NULL;
865 struct symt* ref_type = NULL;
866 unsigned min = 0;
867 unsigned max = 0;
868 dwarf2_abbrev_entry_attr_t* attr = NULL;
869 unsigned long next_sibling = 0;
871 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
873 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
874 switch (attr->attribute) {
875 case DW_AT_sibling:
876 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
877 break;
878 case DW_AT_type:
880 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
881 ref_type = dwarf2_find_symt_by_ref(module, ref);
883 break;
884 default:
885 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
886 dwarf2_parse_attr(attr, ctx);
890 /* FIXME: ugly as hell */
891 symt = symt_new_array(module, min, max, ref_type, NULL);
893 if (entry->have_child) { /** any interest to not have child ? */
894 while (ctx->data < ctx->end_data) {
895 dwarf2_abbrev_entry_t* entry = NULL;
896 unsigned long entry_code;
897 unsigned long entry_ref = 0;
899 entry_ref = ctx->data - ctx->data_stream;
901 entry_code = dwarf2_leb128_as_unsigned(ctx);
902 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
903 if (0 == entry_code) {
904 break ;
907 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
908 assert( NULL != entry );
910 switch (entry->tag) {
911 case DW_TAG_subrange_type:
912 dwarf2_parse_array_subrange_type(module, entry, ctx, symt);
913 break;
914 default:
916 dwarf2_abbrev_entry_attr_t* attr;
917 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
918 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
919 dwarf2_parse_attr(attr, ctx);
922 break;
927 /** set correct data cursor */
928 dwarf2_check_sibling(ctx, next_sibling);
930 return symt;
933 static struct symt* dwarf2_parse_const_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
935 struct symt* ref_type = NULL;
936 dwarf2_abbrev_entry_attr_t* attr = NULL;
937 unsigned long next_sibling = 0;
939 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
941 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
942 switch (attr->attribute) {
943 case DW_AT_type:
945 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
946 ref_type = dwarf2_find_symt_by_ref(module, ref);
948 break;
949 default:
950 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
951 dwarf2_parse_attr(attr, ctx);
955 if (entry->have_child) {
956 FIXME("Unsupported children\n");
959 /** set correct data cursor */
960 dwarf2_check_sibling(ctx, next_sibling);
962 return ref_type;
965 static struct symt* dwarf2_parse_reference_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
967 struct symt* symt = NULL;
968 struct symt* ref_type = NULL;
969 dwarf2_abbrev_entry_attr_t* attr = NULL;
970 unsigned long next_sibling = 0;
972 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
974 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
975 switch (attr->attribute) {
976 case DW_AT_sibling:
977 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
978 break;
979 case DW_AT_type:
981 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
982 ref_type = dwarf2_find_symt_by_ref(module, ref);
984 break;
985 default:
986 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
987 dwarf2_parse_attr(attr, ctx);
990 /* FIXME: for now, we hard-wire C++ references to pointers */
991 symt = &symt_new_pointer(module, ref_type)->symt;
993 if (entry->have_child) {
994 FIXME("Unsupported children\n");
997 /** set correct data cursor */
998 dwarf2_check_sibling(ctx, next_sibling);
1000 return symt;
1003 static void dwarf2_parse_udt_member(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* parent)
1005 struct symt* elt_type = NULL;
1006 const char* name = NULL;
1007 unsigned long offset = 0;
1008 unsigned size = 0;
1009 dwarf2_abbrev_entry_attr_t* attr = NULL;
1010 unsigned long next_sibling = 0;
1012 assert( NULL != parent );
1014 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1016 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1017 switch (attr->attribute) {
1018 case DW_AT_sibling:
1019 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1020 break;
1021 case DW_AT_name:
1022 name = dwarf2_parse_attr_as_string(attr, ctx);
1023 TRACE("found name %s\n", name);
1024 break;
1025 case DW_AT_type:
1027 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1028 elt_type = dwarf2_find_symt_by_ref(module, ref);
1030 break;
1031 case DW_AT_data_member_location:
1033 unsigned long uvalue = 0;
1034 TRACE("found member_location at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1035 /*offset = dwarf2_parse_attr_as_data(attr, ctx);*/
1036 switch (attr->form) {
1037 case DW_FORM_block:
1038 uvalue = dwarf2_leb128_as_unsigned(ctx);
1039 break;
1040 case DW_FORM_block1:
1041 uvalue = dwarf2_parse_byte(ctx);
1042 break;
1043 case DW_FORM_block2:
1044 uvalue = dwarf2_parse_u2(ctx);
1045 break;
1046 case DW_FORM_block4:
1047 uvalue = dwarf2_parse_u4(ctx);
1048 break;
1049 default:
1050 WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1051 dwarf2_parse_attr(attr, ctx);
1053 if (uvalue) {
1054 unsigned char op = dwarf2_parse_byte(ctx);
1055 --uvalue;
1056 switch (op) {
1057 case DW_OP_plus_uconst:
1058 offset = dwarf2_leb128_as_unsigned(ctx);
1059 break;
1060 default:
1061 WARN("Unhandled attr op at %s, for %s, op:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), op);
1062 ctx->data += uvalue;
1064 TRACE("found offset:%lu\n", offset);
1067 break;
1068 case DW_AT_decl_file:
1069 case DW_AT_decl_line:
1070 dwarf2_parse_attr(attr, ctx);
1071 break;
1072 default:
1073 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1074 dwarf2_parse_attr(attr, ctx);
1077 symt_add_udt_element(module, parent, name, elt_type, offset, size);
1079 if (entry->have_child) {
1080 FIXME("Unsupported children\n");
1083 /** set correct data cursor */
1084 dwarf2_check_sibling(ctx, next_sibling);
1087 static void dwarf2_parse_udt_members(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* symt)
1089 if (entry->have_child) { /** any interest to not have child ? */
1090 while (ctx->data < ctx->end_data) {
1091 dwarf2_abbrev_entry_t* entry = NULL;
1092 unsigned long entry_code;
1093 unsigned long entry_ref = 0;
1095 entry_ref = ctx->data - ctx->data_stream;
1097 entry_code = dwarf2_leb128_as_unsigned(ctx);
1098 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1099 if (0 == entry_code) {
1100 break ;
1103 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1104 assert( NULL != entry );
1106 switch (entry->tag) {
1107 case DW_TAG_member:
1108 dwarf2_parse_udt_member(module, entry, ctx, symt);
1109 break;
1110 case DW_TAG_enumeration_type:
1112 struct symt_enum* symt = dwarf2_parse_enumeration_type(module, entry, ctx);
1113 dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1115 break;
1116 default:
1118 dwarf2_abbrev_entry_attr_t* attr;
1119 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1120 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1121 dwarf2_parse_attr(attr, ctx);
1124 break;
1130 static struct symt_udt* dwarf2_parse_udt_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, enum UdtKind udt)
1132 struct symt_udt* symt = NULL;
1133 const char* name = NULL;
1134 unsigned size = 0;
1135 dwarf2_abbrev_entry_attr_t* attr = NULL;
1136 unsigned long next_sibling = 0;
1138 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1140 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1141 switch (attr->attribute) {
1142 case DW_AT_sibling:
1143 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1144 break;
1145 case DW_AT_name:
1146 name = dwarf2_parse_attr_as_string(attr, ctx);
1147 TRACE("found name %s\n", name);
1148 break;
1149 case DW_AT_byte_size:
1150 size = dwarf2_parse_attr_as_data(attr, ctx);
1151 break;
1152 case DW_AT_decl_file:
1153 case DW_AT_decl_line:
1154 dwarf2_parse_attr(attr, ctx);
1155 break;
1156 default:
1157 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1158 dwarf2_parse_attr(attr, ctx);
1161 symt = symt_new_udt(module, name, size, udt);
1162 dwarf2_parse_udt_members(module, entry, ctx, symt);
1164 /** set correct data cursor */
1165 dwarf2_check_sibling(ctx, next_sibling);
1167 return symt;
1170 static void dwarf2_parse_enumerator(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_enum* parent)
1172 const char* name = NULL;
1173 long value = 0;
1174 dwarf2_abbrev_entry_attr_t* attr = NULL;
1176 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1178 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1179 switch (attr->attribute) {
1180 case DW_AT_name:
1181 name = dwarf2_parse_attr_as_string(attr, ctx);
1182 TRACE("found name %s\n", name);
1183 break;
1184 case DW_AT_const_value:
1185 switch (attr->form) {
1186 case DW_FORM_sdata:
1187 value = dwarf2_leb128_as_signed(ctx);
1188 TRACE("found value %ld\n", value);
1189 break;
1190 case DW_FORM_udata:
1191 value = dwarf2_leb128_as_unsigned(ctx);
1192 TRACE("found value %ld\n", value);
1193 break;
1194 default:
1195 WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1196 dwarf2_parse_attr(attr, ctx);
1198 break;
1199 default:
1200 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1201 dwarf2_parse_attr(attr, ctx);
1204 symt_add_enum_element(module, parent, name, value);
1206 if (entry->have_child) {
1207 FIXME("Unsupported children\n");
1211 static struct symt_enum* dwarf2_parse_enumeration_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1213 struct symt_enum* symt = NULL;
1214 const char* name = NULL;
1215 unsigned long size = 0;
1216 dwarf2_abbrev_entry_attr_t* attr = NULL;
1217 unsigned long next_sibling = 0;
1219 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1221 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1222 switch (attr->attribute) {
1223 case DW_AT_sibling:
1224 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1225 break;
1226 case DW_AT_name:
1227 name = dwarf2_parse_attr_as_string(attr, ctx);
1228 TRACE("found name %s\n", name);
1229 break;
1230 case DW_AT_byte_size:
1231 size = dwarf2_parse_attr_as_data(attr, ctx);
1232 break;
1233 case DW_AT_decl_file:
1234 case DW_AT_decl_line:
1235 dwarf2_parse_attr(attr, ctx);
1236 break;
1237 default:
1238 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1239 dwarf2_parse_attr(attr, ctx);
1242 symt = symt_new_enum(module, name);
1244 if (entry->have_child) { /** any interest to not have child ? */
1245 while (ctx->data < ctx->end_data) {
1246 dwarf2_abbrev_entry_t* entry = NULL;
1247 unsigned long entry_code;
1248 unsigned long entry_ref = 0;
1250 entry_ref = ctx->data - ctx->data_stream;
1252 entry_code = dwarf2_leb128_as_unsigned(ctx);
1253 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1254 if (0 == entry_code) {
1255 break ;
1258 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1259 assert( NULL != entry );
1261 switch (entry->tag) {
1262 case DW_TAG_enumerator:
1263 dwarf2_parse_enumerator(module, entry, ctx, symt);
1264 break;
1265 default:
1267 dwarf2_abbrev_entry_attr_t* attr;
1268 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1269 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1270 dwarf2_parse_attr(attr, ctx);
1273 break;
1278 /** set correct data cursor */
1279 dwarf2_check_sibling(ctx, next_sibling);
1281 return symt;
1284 static void dwarf2_parse_variable(struct module* module,
1285 dwarf2_abbrev_entry_t* entry,
1286 dwarf2_parse_context_t* ctx)
1288 struct symt* var_type = NULL;
1289 dwarf2_abbrev_entry_attr_t* attr = NULL;
1290 const char* name = NULL;
1291 unsigned long next_sibling = 0;
1293 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1295 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1296 switch (attr->attribute) {
1297 case DW_AT_sibling:
1298 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1299 break;
1300 case DW_AT_type:
1302 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1303 var_type = dwarf2_find_symt_by_ref(module, ref);
1305 break;
1306 case DW_AT_name:
1307 name = dwarf2_parse_attr_as_string(attr, ctx);
1308 TRACE("found name %s\n", name);
1309 break;
1310 case DW_AT_decl_file:
1311 case DW_AT_decl_line:
1312 dwarf2_parse_attr(attr, ctx);
1313 break;
1314 default:
1315 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1316 dwarf2_parse_attr(attr, ctx);
1320 if (entry->have_child) {
1321 FIXME("Unsupported children\n");
1324 /** set correct data cursor */
1325 dwarf2_check_sibling(ctx, next_sibling);
1328 static void dwarf2_parse_subprogram_parameter(struct module* module,
1329 dwarf2_abbrev_entry_t* entry,
1330 dwarf2_parse_context_t* ctx,
1331 struct symt_function_signature* sig_type,
1332 struct symt_function* func_type)
1334 struct symt* param_type = NULL;
1335 const char* name = NULL;
1336 dwarf2_abbrev_entry_attr_t* attr = NULL;
1337 unsigned long next_sibling = 0;
1339 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1341 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1342 switch (attr->attribute) {
1343 case DW_AT_sibling:
1344 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1345 break;
1346 case DW_AT_type:
1348 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1349 param_type = dwarf2_find_symt_by_ref(module, ref);
1351 break;
1352 case DW_AT_name:
1353 name = dwarf2_parse_attr_as_string(attr, ctx);
1354 TRACE("found name %s\n", name);
1355 break;
1356 case DW_AT_decl_file:
1357 case DW_AT_decl_line:
1358 dwarf2_parse_attr(attr, ctx);
1359 break;
1360 case DW_AT_location:
1361 dwarf2_parse_attr(attr, ctx);
1362 break;
1363 default:
1364 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1365 dwarf2_parse_attr(attr, ctx);
1368 if (NULL != sig_type) {
1369 symt_add_function_signature_parameter(module, sig_type, param_type);
1372 if (entry->have_child) {
1373 FIXME("Unsupported children\n");
1376 /** set correct data cursor */
1377 dwarf2_check_sibling(ctx, next_sibling);
1380 static void dwarf2_parse_inlined_subroutine(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1382 const char* name = NULL;
1383 unsigned long addr = 0;
1384 unsigned long low_pc = 0;
1385 unsigned long high_pc = 0;
1386 unsigned size = 0;
1387 dwarf2_abbrev_entry_attr_t* attr = NULL;
1388 unsigned long next_sibling = 0;
1390 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1392 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1393 switch (attr->attribute) {
1394 case DW_AT_sibling:
1395 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1396 break;
1397 case DW_AT_low_pc:
1398 low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1399 addr = module->module.BaseOfImage + low_pc;
1400 break;
1401 case DW_AT_high_pc:
1402 high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1403 size = high_pc - low_pc;
1404 break;
1405 case DW_AT_name:
1406 name = dwarf2_parse_attr_as_string(attr, ctx);
1407 TRACE("found name %s\n", name);
1408 break;
1409 case DW_AT_decl_file:
1410 case DW_AT_decl_line:
1411 dwarf2_parse_attr(attr, ctx);
1412 break;
1413 default:
1414 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1415 dwarf2_parse_attr(attr, ctx);
1419 if (entry->have_child) { /** any interest to not have child ? */
1420 while (ctx->data < ctx->end_data) {
1421 dwarf2_abbrev_entry_t* entry = NULL;
1422 unsigned long entry_code;
1423 unsigned long entry_ref = 0;
1425 entry_ref = ctx->data - ctx->data_stream;
1427 entry_code = dwarf2_leb128_as_unsigned(ctx);
1428 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1429 if (0 == entry_code) {
1430 break ;
1433 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1434 assert( NULL != entry );
1436 switch (entry->tag) {
1437 case DW_TAG_formal_parameter:
1438 dwarf2_parse_subprogram_parameter(module, entry, ctx, NULL, NULL);
1439 break;
1440 case DW_TAG_variable:
1441 dwarf2_parse_variable(module, entry, ctx);
1442 break;
1443 case DW_TAG_label:
1444 default:
1446 dwarf2_abbrev_entry_attr_t* attr;
1447 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1448 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1449 dwarf2_parse_attr(attr, ctx);
1452 break;
1457 /** set correct data cursor */
1458 dwarf2_check_sibling(ctx, next_sibling);
1462 static void dwarf2_parse_subprogram_block(struct module* module,
1463 dwarf2_abbrev_entry_t* entry,
1464 dwarf2_parse_context_t* ctx,
1465 struct symt_function_signature* sig_type,
1466 struct symt_function* func_type)
1468 dwarf2_abbrev_entry_attr_t* attr = NULL;
1469 const char* name = NULL;
1470 unsigned long next_sibling = 0;
1472 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1474 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1475 switch (attr->attribute) {
1476 case DW_AT_sibling:
1477 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1478 break;
1479 case DW_AT_name:
1480 name = dwarf2_parse_attr_as_string(attr, ctx);
1481 TRACE("found name %s\n", name);
1482 break;
1483 case DW_AT_decl_file:
1484 case DW_AT_decl_line:
1485 dwarf2_parse_attr(attr, ctx);
1486 break;
1487 case DW_AT_ranges: /** what to do ? */
1488 dwarf2_parse_attr(attr, ctx);
1489 break;
1490 default:
1491 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1492 dwarf2_parse_attr(attr, ctx);
1496 if (entry->have_child) { /** any interest to not have child ? */
1497 while (ctx->data < ctx->end_data) {
1498 dwarf2_abbrev_entry_t* entry = NULL;
1499 unsigned long entry_code;
1500 unsigned long entry_ref = 0;
1502 entry_ref = ctx->data - ctx->data_stream;
1504 entry_code = dwarf2_leb128_as_unsigned(ctx);
1505 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1506 if (0 == entry_code) {
1507 break ;
1510 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1511 assert( NULL != entry );
1513 switch (entry->tag) {
1514 case DW_TAG_inlined_subroutine:
1515 dwarf2_parse_inlined_subroutine(module, entry, ctx);
1516 break;
1517 case DW_TAG_variable:
1518 dwarf2_parse_variable(module, entry, ctx);
1519 break;
1520 case DW_TAG_label:
1521 default:
1523 dwarf2_abbrev_entry_attr_t* attr;
1524 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1525 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1526 dwarf2_parse_attr(attr, ctx);
1529 break;
1534 /** set correct data cursor */
1535 dwarf2_check_sibling(ctx, next_sibling);
1538 static void dwarf2_parse_subprogram_content(struct module* module,
1539 dwarf2_abbrev_entry_t* entry,
1540 dwarf2_parse_context_t* ctx,
1541 struct symt_function_signature* sig_type,
1542 struct symt_function* func_type)
1544 if (entry->have_child) { /** any interest to not have child ? */
1545 while (ctx->data < ctx->end_data) {
1546 dwarf2_abbrev_entry_t* entry = NULL;
1547 unsigned long entry_code;
1548 unsigned long entry_ref = 0;
1550 entry_ref = ctx->data - ctx->data_stream;
1552 entry_code = dwarf2_leb128_as_unsigned(ctx);
1553 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1554 if (0 == entry_code) {
1555 break ;
1558 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1559 assert( NULL != entry );
1561 switch (entry->tag) {
1562 case DW_TAG_formal_parameter:
1563 dwarf2_parse_subprogram_parameter(module, entry, ctx, sig_type, func_type);
1564 break;
1565 case DW_TAG_lexical_block:
1566 dwarf2_parse_subprogram_block(module, entry, ctx, sig_type, func_type);
1567 break;
1568 case DW_TAG_variable:
1569 dwarf2_parse_variable(module, entry, ctx);
1570 break;
1571 case DW_TAG_label:
1572 default:
1574 dwarf2_abbrev_entry_attr_t* attr;
1575 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1576 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1577 dwarf2_parse_attr(attr, ctx);
1580 break;
1586 static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1588 struct symt_function* func_type = NULL;
1589 const char* name = NULL;
1590 struct symt* ret_type = NULL;
1591 struct symt_function_signature* sig_type = NULL;
1592 unsigned long addr = 0;
1593 unsigned long low_pc = 0;
1594 unsigned long high_pc = 0;
1595 unsigned size = 0;
1596 unsigned char is_decl = 0;
1597 unsigned char inl_flags = 0;
1598 unsigned char decl_file = 0;
1599 unsigned char decl_line = 0;
1600 dwarf2_abbrev_entry_attr_t* attr = NULL;
1601 unsigned long next_sibling = 0;
1602 enum CV_call_e call_conv = CV_CALL_FAR_C; /* FIXME: assuming C source code */
1603 unsigned cc;
1605 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1607 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1608 switch (attr->attribute) {
1609 case DW_AT_sibling:
1610 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1611 break;
1612 case DW_AT_low_pc:
1613 low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1614 addr = module->module.BaseOfImage + low_pc;
1615 break;
1616 case DW_AT_high_pc:
1617 high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1618 size = high_pc - low_pc;
1619 break;
1620 case DW_AT_name:
1621 name = dwarf2_parse_attr_as_string(attr, ctx);
1622 TRACE("found name %s\n", name);
1623 break;
1624 case DW_AT_type:
1626 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1627 ret_type = dwarf2_find_symt_by_ref(module, ref);
1629 break;
1630 case DW_AT_declaration:
1631 is_decl = dwarf2_parse_byte(ctx);
1632 break;
1633 case DW_AT_inline:
1634 inl_flags = dwarf2_parse_byte(ctx);
1635 break;
1636 case DW_AT_calling_convention:
1637 switch (cc = dwarf2_parse_byte(ctx))
1639 case DW_CC_normal: break;
1640 case DW_CC_nocall: call_conv = -1;
1641 default: FIXME("Unsupported calling convention %d\n", cc);
1643 break;
1644 /* not work yet, need parsing .debug_line and using Compil Unit stmt_list
1645 case DW_AT_decl_file:
1646 decl_file = dwarf2_parse_byte(ctx);
1647 break;
1648 case DW_AT_decl_line:
1649 decl_line = dwarf2_parse_byte(ctx);
1650 break;
1652 default:
1653 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1654 dwarf2_parse_attr(attr, ctx);
1657 sig_type = symt_new_function_signature(module, ret_type, call_conv);
1658 if (!is_decl) {
1659 func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt);
1660 if (low_pc && high_pc) {
1661 symt_add_function_point(module, func_type, SymTagFuncDebugStart, low_pc, NULL);
1662 symt_add_function_point(module, func_type, SymTagFuncDebugEnd, high_pc, NULL);
1664 if (decl_file && decl_line) {
1665 symt_add_func_line(module, func_type, decl_file, decl_line, low_pc);
1668 dwarf2_parse_subprogram_content(module, entry, ctx, sig_type, func_type);
1669 symt_normalize_function(module, func_type);
1671 /** set correct data cursor */
1672 dwarf2_check_sibling(ctx, next_sibling);
1674 return func_type;
1677 static void dwarf2_parse_compiland_content(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1679 if (entry->have_child) { /** any interest to not have child ? */
1680 while (ctx->data < ctx->end_data) {
1681 dwarf2_abbrev_entry_t* entry = NULL;
1682 unsigned long entry_code;
1683 unsigned long entry_ref = 0;
1685 entry_ref = ctx->data - ctx->data_stream;
1687 entry_code = dwarf2_leb128_as_unsigned(ctx);
1688 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1689 if (0 == entry_code) {
1690 break ;
1693 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1694 assert( NULL != entry );
1696 switch (entry->tag) {
1697 case DW_TAG_typedef:
1699 struct symt_typedef* symt = dwarf2_parse_typedef(module, entry, ctx);
1700 dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1702 break;
1703 case DW_TAG_base_type:
1705 struct symt_basic* symt = dwarf2_parse_base_type(module, entry, ctx);
1706 dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1708 break;
1709 case DW_TAG_pointer_type:
1711 struct symt_pointer* symt = dwarf2_parse_pointer_type(module, entry, ctx);
1712 dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1714 break;
1715 case DW_TAG_class_type:
1717 struct symt_udt* symt = dwarf2_parse_udt_type(module, entry, ctx, UdtClass);
1718 if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1720 break;
1721 case DW_TAG_structure_type:
1723 struct symt_udt* symt = dwarf2_parse_udt_type(module, entry, ctx, UdtStruct);
1724 if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1726 break;
1727 case DW_TAG_union_type:
1729 struct symt_udt* symt = dwarf2_parse_udt_type(module, entry, ctx, UdtUnion);
1730 if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1732 break;
1733 case DW_TAG_array_type:
1735 struct symt_array* symt = dwarf2_parse_array_type(module, entry, ctx);
1736 dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1738 break;
1739 case DW_TAG_const_type:
1741 struct symt* symt = dwarf2_parse_const_type(module, entry, ctx);
1742 dwarf2_add_symt_ref(module, entry_ref, symt);
1744 break;
1745 case DW_TAG_reference_type:
1747 struct symt* symt = dwarf2_parse_reference_type(module, entry, ctx);
1748 dwarf2_add_symt_ref(module, entry_ref, symt);
1750 break;
1751 case DW_TAG_enumeration_type:
1753 struct symt_enum* symt = dwarf2_parse_enumeration_type(module, entry, ctx);
1754 dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1756 break;
1757 case DW_TAG_subprogram:
1759 struct symt_function* symt = dwarf2_parse_subprogram(module, entry, ctx, compiland);
1760 if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1762 break;
1764 default:
1766 dwarf2_abbrev_entry_attr_t* attr;
1767 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1768 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1769 dwarf2_parse_attr(attr, ctx);
1772 break;
1778 static struct symt_compiland* dwarf2_parse_compiland(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1780 struct symt_compiland* compiland = NULL;
1781 const char* name = NULL;
1782 unsigned long next_sibling = 0;
1783 dwarf2_abbrev_entry_attr_t* attr = NULL;
1785 TRACE("beginning at Ox%x, for %lu\n", ctx->data - ctx->start_data, entry->entry_code);
1787 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1788 switch (attr->attribute) {
1789 case DW_AT_sibling:
1790 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1791 break;
1792 case DW_AT_name:
1793 name = dwarf2_parse_attr_as_string(attr, ctx);
1794 TRACE("found name %s\n", name);
1795 break;
1796 default:
1797 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1798 dwarf2_parse_attr(attr, ctx);
1801 compiland = symt_new_compiland(module, name);
1802 dwarf2_parse_compiland_content(module, entry, ctx, compiland);
1804 dwarf2_check_sibling(ctx, next_sibling);
1806 return compiland;
1809 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
1810 const unsigned char* debug, unsigned int debug_size,
1811 const unsigned char* abbrev, unsigned int abbrev_size,
1812 const unsigned char* str, unsigned int str_sz)
1814 const unsigned char* comp_unit_cursor = debug;
1815 const unsigned char* end_debug = debug + debug_size;
1817 while (comp_unit_cursor < end_debug) {
1818 const dwarf2_comp_unit_stream_t* comp_unit_stream;
1819 dwarf2_comp_unit_t comp_unit;
1820 dwarf2_parse_context_t ctx;
1821 dwarf2_parse_context_t abbrev_ctx;
1822 struct symt_compiland* compiland = NULL;
1823 dwarf2_debug_info_t* di;
1825 comp_unit_stream = (const dwarf2_comp_unit_stream_t*) comp_unit_cursor;
1827 comp_unit.length = *(unsigned long*) comp_unit_stream->length;
1828 comp_unit.version = *(unsigned short*) comp_unit_stream->version;
1829 comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset;
1830 comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size;
1832 TRACE("Compilation Unit Herder found at 0x%x:\n", comp_unit_cursor - debug);
1833 TRACE("- length: %lu\n", comp_unit.length);
1834 TRACE("- version: %u\n", comp_unit.version);
1835 TRACE("- abbrev_offset: %lu\n", comp_unit.abbrev_offset);
1836 TRACE("- word_size: %u\n", comp_unit.word_size);
1838 pool_init(&ctx.pool, 65536);
1839 ctx.data_stream = debug;
1840 ctx.data = ctx.start_data = comp_unit_cursor + sizeof(dwarf2_comp_unit_stream_t);
1841 ctx.offset = comp_unit_cursor - debug;
1842 ctx.word_size = comp_unit.word_size;
1843 ctx.str_section = str;
1845 comp_unit_cursor += comp_unit.length + sizeof(unsigned);
1846 ctx.end_data = comp_unit_cursor;
1848 if (2 != comp_unit.version) {
1849 WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", comp_unit.version);
1850 continue ;
1853 abbrev_ctx.data_stream = abbrev;
1854 abbrev_ctx.data = abbrev_ctx.start_data = abbrev + comp_unit.abbrev_offset;
1855 abbrev_ctx.end_data = abbrev + abbrev_size;
1856 abbrev_ctx.offset = comp_unit.abbrev_offset;
1857 abbrev_ctx.str_section = str;
1858 dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
1860 sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128);
1861 dwarf2_read_one_debug_info(&ctx, &di);
1862 ctx.data = ctx.start_data; /* FIXME */
1864 while (ctx.data < ctx.end_data) {
1865 const dwarf2_abbrev_entry_t* entry = NULL;
1866 unsigned long entry_code;
1867 unsigned long entry_ref = 0;
1869 entry_ref = ctx.data - ctx.data_stream;
1871 entry_code = dwarf2_leb128_as_unsigned(&ctx);
1872 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1873 if (0 == entry_code) {
1874 continue ;
1876 entry = dwarf2_abbrev_table_find_entry(&ctx.abbrev_table, entry_code);
1877 if (NULL == entry) {
1878 WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, entry_ref);
1879 pool_destroy(&ctx.pool);
1880 return FALSE;
1883 switch (entry->tag) {
1884 case DW_TAG_compile_unit:
1886 struct symt_compiland* symt = dwarf2_parse_compiland(module, entry, &ctx);
1887 dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1888 compiland = symt;
1890 break;
1891 default:
1893 dwarf2_abbrev_entry_attr_t* attr;
1894 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(&ctx), entry->entry_code);
1895 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1896 dwarf2_parse_attr(attr, &ctx);
1899 break;
1902 pool_destroy(&ctx.pool);
1905 module->module.SymType = SymDia;
1906 return TRUE;