dbghelp: Dwarf & type references.
[wine/multimedia.git] / dlls / dbghelp / dwarf.c
blob34d5aac15b31dcf6bf03217dfb6207beceba8abb
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 /******************************************************************
624 * dwarf2_read_one_debug_info
626 * Loads into memory one debug info entry, and recursively its children (if any)
628 static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx,
629 dwarf2_debug_info_t** pdi)
631 const dwarf2_abbrev_entry_t*abbrev;
632 unsigned long entry_code;
633 unsigned long offset;
634 dwarf2_debug_info_t* di;
635 dwarf2_debug_info_t* child;
636 dwarf2_debug_info_t** where;
637 dwarf2_abbrev_entry_attr_t* attr;
638 unsigned i;
640 offset = ctx->data - ctx->data_stream;
641 entry_code = dwarf2_leb128_as_unsigned(ctx);
642 TRACE("found entry_code %lu at 0x%lx\n", entry_code, offset);
643 if (!entry_code)
645 *pdi = NULL;
646 return TRUE;
648 abbrev = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
649 if (!abbrev)
651 WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, offset);
652 return FALSE;
654 di = sparse_array_add(&ctx->debug_info_table, offset, &ctx->pool);
655 if (!di) return FALSE;
656 di->offset = offset;
657 di->abbrev = abbrev;
658 di->symt = NULL;
660 if (abbrev->num_attr)
662 di->attributes = pool_alloc(&ctx->pool,
663 abbrev->num_attr * sizeof(union attribute));
664 for (i = 0, attr = abbrev->attrs; attr; i++, attr = attr->next)
666 dwarf2_parse_attr_into_di(ctx, attr, &di->attributes[i]);
669 else di->attributes = NULL;
670 if (abbrev->have_child)
672 vector_init(&di->children, sizeof(dwarf2_debug_info_t*), 16);
673 while (ctx->data < ctx->end_data)
675 if (!dwarf2_read_one_debug_info(ctx, &child)) return FALSE;
676 if (!child) break;
677 where = vector_add(&di->children, &ctx->pool);
678 if (!where) return FALSE;
679 *where = child;
682 *pdi = di;
683 return TRUE;
686 static struct symt_basic* dwarf2_parse_base_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
688 struct symt_basic* symt = NULL;
689 const char* name = NULL;
690 unsigned size = 0;
691 unsigned encoding = 0;
692 enum BasicType bt;
693 dwarf2_abbrev_entry_attr_t* attr = NULL;
695 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
697 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
698 switch (attr->attribute) {
699 case DW_AT_name:
700 name = dwarf2_parse_attr_as_string(attr, ctx);
701 TRACE("found name %s\n", name);
702 break;
703 case DW_AT_byte_size:
704 size = dwarf2_parse_attr_as_data(attr, ctx);
705 break;
706 case DW_AT_encoding:
707 encoding = dwarf2_parse_byte(ctx);
708 break;
709 default:
710 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
711 dwarf2_parse_attr(attr, ctx);
714 switch (encoding) {
715 case DW_ATE_void: bt = btVoid; break;
716 case DW_ATE_address: bt = btULong; break;
717 case DW_ATE_boolean: bt = btBool; break;
718 case DW_ATE_complex_float: bt = btComplex; break;
719 case DW_ATE_float: bt = btFloat; break;
720 case DW_ATE_signed: bt = btInt; break;
721 case DW_ATE_unsigned: bt = btUInt; break;
722 case DW_ATE_signed_char: bt = btChar; break;
723 case DW_ATE_unsigned_char: bt = btChar; break;
724 default:
725 bt = btNoType;
727 /*TRACE("symt_new_basic(%p, %u, %s, %u)", module, bt, name, size);*/
728 symt = symt_new_basic(module, bt, name, size);
730 if (entry->have_child) {
731 FIXME("Unsupported children\n");
733 return symt;
736 static struct symt_typedef* dwarf2_parse_typedef(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
738 struct symt_typedef* symt = NULL;
739 struct symt* ref_type = NULL;
740 const char* name = NULL;
741 dwarf2_abbrev_entry_attr_t* attr = NULL;
743 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
745 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
746 switch (attr->attribute) {
747 case DW_AT_name:
748 name = dwarf2_parse_attr_as_string(attr, ctx);
749 TRACE("found name %s\n", name);
750 break;
751 case DW_AT_type:
753 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
754 ref_type = dwarf2_find_symt_by_ref(module, ref);
756 break;
757 case DW_AT_decl_file:
758 case DW_AT_decl_line:
759 dwarf2_parse_attr(attr, ctx);
760 break;
761 default:
762 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
763 dwarf2_parse_attr(attr, ctx);
766 if (NULL != name) {
767 symt = symt_new_typedef(module, ref_type, name);
770 if (entry->have_child) {
771 FIXME("Unsupported children\n");
773 return symt;
776 static struct symt_pointer* dwarf2_parse_pointer_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
778 struct symt_pointer* symt = NULL;
779 struct symt* ref_type = NULL;
780 unsigned size = 0;
781 dwarf2_abbrev_entry_attr_t* attr = NULL;
783 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
785 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
786 switch (attr->attribute) {
787 case DW_AT_byte_size:
788 size = dwarf2_parse_attr_as_data(attr, ctx);
789 break;
790 case DW_AT_type:
792 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
793 ref_type = dwarf2_find_symt_by_ref(module, ref);
795 break;
796 default:
797 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
798 dwarf2_parse_attr(attr, ctx);
801 symt = symt_new_pointer(module, ref_type);
803 if (entry->have_child) {
804 FIXME("Unsupported children\n");
806 return symt;
809 static void dwarf2_parse_array_subrange_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_array* parent)
811 unsigned min = 0;
812 unsigned max = 0;
813 struct symt* idx_type = NULL;
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_type:
822 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
823 idx_type = dwarf2_find_symt_by_ref(module, ref);
824 /** check if idx_type is a basic_type integer */
826 break;
827 case DW_AT_lower_bound:
828 TRACE("%s %s, lower_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
829 min = dwarf2_parse_attr_as_data(attr, ctx);
830 break;
831 case DW_AT_upper_bound:
832 TRACE("%s %s, upper_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
833 max = dwarf2_parse_attr_as_data(attr, ctx);
834 break;
835 case DW_AT_count:
836 TRACE("%s %s, count min:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), min);
837 max = min + dwarf2_parse_attr_as_data(attr, ctx);
838 break;
839 default:
840 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
841 dwarf2_parse_attr(attr, ctx);
844 parent->start = min;
845 parent->end = max;
846 parent->index_type = idx_type;
848 TRACE("found min:%u max:%u\n", min, max);
850 if (entry->have_child) {
851 FIXME("Unsupported children\n");
856 static struct symt_array* dwarf2_parse_array_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
858 struct symt_array* symt = NULL;
859 struct symt* ref_type = NULL;
860 unsigned min = 0;
861 unsigned max = 0;
862 dwarf2_abbrev_entry_attr_t* attr = NULL;
863 unsigned long next_sibling = 0;
865 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
867 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
868 switch (attr->attribute) {
869 case DW_AT_sibling:
870 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
871 break;
872 case DW_AT_type:
874 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
875 ref_type = dwarf2_find_symt_by_ref(module, ref);
877 break;
878 default:
879 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
880 dwarf2_parse_attr(attr, ctx);
884 /* FIXME: ugly as hell */
885 symt = symt_new_array(module, min, max, ref_type, NULL);
887 if (entry->have_child) { /** any interest to not have child ? */
888 while (ctx->data < ctx->end_data) {
889 dwarf2_abbrev_entry_t* entry = NULL;
890 unsigned long entry_code;
891 unsigned long entry_ref = 0;
893 entry_ref = ctx->data - ctx->data_stream;
895 entry_code = dwarf2_leb128_as_unsigned(ctx);
896 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
897 if (0 == entry_code) {
898 break ;
901 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
902 assert( NULL != entry );
904 switch (entry->tag) {
905 case DW_TAG_subrange_type:
906 dwarf2_parse_array_subrange_type(module, entry, ctx, symt);
907 break;
908 default:
910 dwarf2_abbrev_entry_attr_t* attr;
911 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
912 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
913 dwarf2_parse_attr(attr, ctx);
916 break;
921 /** set correct data cursor */
922 dwarf2_check_sibling(ctx, next_sibling);
924 return symt;
927 static struct symt* dwarf2_parse_const_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
929 struct symt* ref_type = NULL;
930 dwarf2_abbrev_entry_attr_t* attr = NULL;
931 unsigned long next_sibling = 0;
933 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
935 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
936 switch (attr->attribute) {
937 case DW_AT_type:
939 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
940 ref_type = dwarf2_find_symt_by_ref(module, ref);
942 break;
943 default:
944 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
945 dwarf2_parse_attr(attr, ctx);
949 if (entry->have_child) {
950 FIXME("Unsupported children\n");
953 /** set correct data cursor */
954 dwarf2_check_sibling(ctx, next_sibling);
956 return ref_type;
959 static struct symt* dwarf2_parse_reference_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
961 struct symt* symt = NULL;
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_sibling:
971 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
972 break;
973 case DW_AT_type:
975 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
976 ref_type = dwarf2_find_symt_by_ref(module, ref);
978 break;
979 default:
980 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
981 dwarf2_parse_attr(attr, ctx);
984 /* FIXME: for now, we hard-wire C++ references to pointers */
985 symt = &symt_new_pointer(module, ref_type)->symt;
987 if (entry->have_child) {
988 FIXME("Unsupported children\n");
991 /** set correct data cursor */
992 dwarf2_check_sibling(ctx, next_sibling);
994 return symt;
997 static void dwarf2_parse_udt_member(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* parent)
999 struct symt* elt_type = NULL;
1000 const char* name = NULL;
1001 unsigned long offset = 0;
1002 unsigned size = 0;
1003 dwarf2_abbrev_entry_attr_t* attr = NULL;
1004 unsigned long next_sibling = 0;
1006 assert( NULL != parent );
1008 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1010 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1011 switch (attr->attribute) {
1012 case DW_AT_sibling:
1013 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1014 break;
1015 case DW_AT_name:
1016 name = dwarf2_parse_attr_as_string(attr, ctx);
1017 TRACE("found name %s\n", name);
1018 break;
1019 case DW_AT_type:
1021 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1022 elt_type = dwarf2_find_symt_by_ref(module, ref);
1024 break;
1025 case DW_AT_data_member_location:
1027 unsigned long uvalue = 0;
1028 TRACE("found member_location at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1029 /*offset = dwarf2_parse_attr_as_data(attr, ctx);*/
1030 switch (attr->form) {
1031 case DW_FORM_block:
1032 uvalue = dwarf2_leb128_as_unsigned(ctx);
1033 break;
1034 case DW_FORM_block1:
1035 uvalue = dwarf2_parse_byte(ctx);
1036 break;
1037 case DW_FORM_block2:
1038 uvalue = dwarf2_parse_u2(ctx);
1039 break;
1040 case DW_FORM_block4:
1041 uvalue = dwarf2_parse_u4(ctx);
1042 break;
1043 default:
1044 WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1045 dwarf2_parse_attr(attr, ctx);
1047 if (uvalue) {
1048 unsigned char op = dwarf2_parse_byte(ctx);
1049 --uvalue;
1050 switch (op) {
1051 case DW_OP_plus_uconst:
1052 offset = dwarf2_leb128_as_unsigned(ctx);
1053 break;
1054 default:
1055 WARN("Unhandled attr op at %s, for %s, op:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), op);
1056 ctx->data += uvalue;
1058 TRACE("found offset:%lu\n", offset);
1061 break;
1062 case DW_AT_decl_file:
1063 case DW_AT_decl_line:
1064 dwarf2_parse_attr(attr, ctx);
1065 break;
1066 default:
1067 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1068 dwarf2_parse_attr(attr, ctx);
1071 symt_add_udt_element(module, parent, name, elt_type, offset, size);
1073 if (entry->have_child) {
1074 FIXME("Unsupported children\n");
1077 /** set correct data cursor */
1078 dwarf2_check_sibling(ctx, next_sibling);
1081 static void dwarf2_parse_udt_members(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* symt)
1083 if (entry->have_child) { /** any interest to not have child ? */
1084 while (ctx->data < ctx->end_data) {
1085 dwarf2_abbrev_entry_t* entry = NULL;
1086 unsigned long entry_code;
1087 unsigned long entry_ref = 0;
1089 entry_ref = ctx->data - ctx->data_stream;
1091 entry_code = dwarf2_leb128_as_unsigned(ctx);
1092 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1093 if (0 == entry_code) {
1094 break ;
1097 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1098 assert( NULL != entry );
1100 switch (entry->tag) {
1101 case DW_TAG_member:
1102 dwarf2_parse_udt_member(module, entry, ctx, symt);
1103 break;
1104 case DW_TAG_enumeration_type:
1105 dwarf2_parse_enumeration_type(module, entry, ctx);
1106 break;
1107 default:
1109 dwarf2_abbrev_entry_attr_t* attr;
1110 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1111 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1112 dwarf2_parse_attr(attr, ctx);
1115 break;
1121 static struct symt_udt* dwarf2_parse_udt_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, enum UdtKind udt)
1123 struct symt_udt* symt = NULL;
1124 const char* name = NULL;
1125 unsigned size = 0;
1126 dwarf2_abbrev_entry_attr_t* attr = NULL;
1127 unsigned long next_sibling = 0;
1129 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1131 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1132 switch (attr->attribute) {
1133 case DW_AT_sibling:
1134 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1135 break;
1136 case DW_AT_name:
1137 name = dwarf2_parse_attr_as_string(attr, ctx);
1138 TRACE("found name %s\n", name);
1139 break;
1140 case DW_AT_byte_size:
1141 size = dwarf2_parse_attr_as_data(attr, ctx);
1142 break;
1143 case DW_AT_decl_file:
1144 case DW_AT_decl_line:
1145 dwarf2_parse_attr(attr, ctx);
1146 break;
1147 default:
1148 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1149 dwarf2_parse_attr(attr, ctx);
1152 symt = symt_new_udt(module, name, size, udt);
1153 dwarf2_parse_udt_members(module, entry, ctx, symt);
1155 /** set correct data cursor */
1156 dwarf2_check_sibling(ctx, next_sibling);
1158 return symt;
1161 static void dwarf2_parse_enumerator(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_enum* parent)
1163 const char* name = NULL;
1164 long value = 0;
1165 dwarf2_abbrev_entry_attr_t* attr = NULL;
1167 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1169 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1170 switch (attr->attribute) {
1171 case DW_AT_name:
1172 name = dwarf2_parse_attr_as_string(attr, ctx);
1173 TRACE("found name %s\n", name);
1174 break;
1175 case DW_AT_const_value:
1176 switch (attr->form) {
1177 case DW_FORM_sdata:
1178 value = dwarf2_leb128_as_signed(ctx);
1179 TRACE("found value %ld\n", value);
1180 break;
1181 case DW_FORM_udata:
1182 value = dwarf2_leb128_as_unsigned(ctx);
1183 TRACE("found value %ld\n", value);
1184 break;
1185 default:
1186 WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1187 dwarf2_parse_attr(attr, ctx);
1189 break;
1190 default:
1191 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1192 dwarf2_parse_attr(attr, ctx);
1195 symt_add_enum_element(module, parent, name, value);
1197 if (entry->have_child) {
1198 FIXME("Unsupported children\n");
1202 static struct symt_enum* dwarf2_parse_enumeration_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1204 struct symt_enum* symt = NULL;
1205 const char* name = NULL;
1206 unsigned long size = 0;
1207 dwarf2_abbrev_entry_attr_t* attr = NULL;
1208 unsigned long next_sibling = 0;
1210 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1212 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1213 switch (attr->attribute) {
1214 case DW_AT_sibling:
1215 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1216 break;
1217 case DW_AT_name:
1218 name = dwarf2_parse_attr_as_string(attr, ctx);
1219 TRACE("found name %s\n", name);
1220 break;
1221 case DW_AT_byte_size:
1222 size = dwarf2_parse_attr_as_data(attr, ctx);
1223 break;
1224 case DW_AT_decl_file:
1225 case DW_AT_decl_line:
1226 dwarf2_parse_attr(attr, ctx);
1227 break;
1228 default:
1229 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1230 dwarf2_parse_attr(attr, ctx);
1233 symt = symt_new_enum(module, name);
1235 if (entry->have_child) { /** any interest to not have child ? */
1236 while (ctx->data < ctx->end_data) {
1237 dwarf2_abbrev_entry_t* entry = NULL;
1238 unsigned long entry_code;
1239 unsigned long entry_ref = 0;
1241 entry_ref = ctx->data - ctx->data_stream;
1243 entry_code = dwarf2_leb128_as_unsigned(ctx);
1244 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1245 if (0 == entry_code) {
1246 break ;
1249 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1250 assert( NULL != entry );
1252 switch (entry->tag) {
1253 case DW_TAG_enumerator:
1254 dwarf2_parse_enumerator(module, entry, ctx, symt);
1255 break;
1256 default:
1258 dwarf2_abbrev_entry_attr_t* attr;
1259 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1260 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1261 dwarf2_parse_attr(attr, ctx);
1264 break;
1269 /** set correct data cursor */
1270 dwarf2_check_sibling(ctx, next_sibling);
1272 return symt;
1275 static void dwarf2_parse_variable(struct module* module,
1276 dwarf2_abbrev_entry_t* entry,
1277 dwarf2_parse_context_t* ctx)
1279 struct symt* var_type = NULL;
1280 dwarf2_abbrev_entry_attr_t* attr = NULL;
1281 const char* name = NULL;
1282 unsigned long next_sibling = 0;
1284 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1286 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1287 switch (attr->attribute) {
1288 case DW_AT_sibling:
1289 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1290 break;
1291 case DW_AT_type:
1293 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1294 var_type = dwarf2_find_symt_by_ref(module, ref);
1296 break;
1297 case DW_AT_name:
1298 name = dwarf2_parse_attr_as_string(attr, ctx);
1299 TRACE("found name %s\n", name);
1300 break;
1301 case DW_AT_decl_file:
1302 case DW_AT_decl_line:
1303 dwarf2_parse_attr(attr, ctx);
1304 break;
1305 default:
1306 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1307 dwarf2_parse_attr(attr, ctx);
1311 if (entry->have_child) {
1312 FIXME("Unsupported children\n");
1315 /** set correct data cursor */
1316 dwarf2_check_sibling(ctx, next_sibling);
1319 static void dwarf2_parse_subprogram_parameter(struct module* module,
1320 dwarf2_abbrev_entry_t* entry,
1321 dwarf2_parse_context_t* ctx,
1322 struct symt_function_signature* sig_type,
1323 struct symt_function* func_type)
1325 struct symt* param_type = NULL;
1326 const char* name = NULL;
1327 dwarf2_abbrev_entry_attr_t* attr = NULL;
1328 unsigned long next_sibling = 0;
1330 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1332 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1333 switch (attr->attribute) {
1334 case DW_AT_sibling:
1335 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1336 break;
1337 case DW_AT_type:
1339 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1340 param_type = dwarf2_find_symt_by_ref(module, ref);
1342 break;
1343 case DW_AT_name:
1344 name = dwarf2_parse_attr_as_string(attr, ctx);
1345 TRACE("found name %s\n", name);
1346 break;
1347 case DW_AT_decl_file:
1348 case DW_AT_decl_line:
1349 dwarf2_parse_attr(attr, ctx);
1350 break;
1351 case DW_AT_location:
1352 dwarf2_parse_attr(attr, ctx);
1353 break;
1354 default:
1355 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1356 dwarf2_parse_attr(attr, ctx);
1359 if (NULL != sig_type) {
1360 symt_add_function_signature_parameter(module, sig_type, param_type);
1363 if (entry->have_child) {
1364 FIXME("Unsupported children\n");
1367 /** set correct data cursor */
1368 dwarf2_check_sibling(ctx, next_sibling);
1371 static void dwarf2_parse_inlined_subroutine(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1373 const char* name = NULL;
1374 unsigned long addr = 0;
1375 unsigned long low_pc = 0;
1376 unsigned long high_pc = 0;
1377 unsigned size = 0;
1378 dwarf2_abbrev_entry_attr_t* attr = NULL;
1379 unsigned long next_sibling = 0;
1381 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1383 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1384 switch (attr->attribute) {
1385 case DW_AT_sibling:
1386 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1387 break;
1388 case DW_AT_low_pc:
1389 low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1390 addr = module->module.BaseOfImage + low_pc;
1391 break;
1392 case DW_AT_high_pc:
1393 high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1394 size = high_pc - low_pc;
1395 break;
1396 case DW_AT_name:
1397 name = dwarf2_parse_attr_as_string(attr, ctx);
1398 TRACE("found name %s\n", name);
1399 break;
1400 case DW_AT_decl_file:
1401 case DW_AT_decl_line:
1402 dwarf2_parse_attr(attr, ctx);
1403 break;
1404 default:
1405 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1406 dwarf2_parse_attr(attr, ctx);
1410 if (entry->have_child) { /** any interest to not have child ? */
1411 while (ctx->data < ctx->end_data) {
1412 dwarf2_abbrev_entry_t* entry = NULL;
1413 unsigned long entry_code;
1414 unsigned long entry_ref = 0;
1416 entry_ref = ctx->data - ctx->data_stream;
1418 entry_code = dwarf2_leb128_as_unsigned(ctx);
1419 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1420 if (0 == entry_code) {
1421 break ;
1424 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1425 assert( NULL != entry );
1427 switch (entry->tag) {
1428 case DW_TAG_formal_parameter:
1429 dwarf2_parse_subprogram_parameter(module, entry, ctx, NULL, NULL);
1430 break;
1431 case DW_TAG_variable:
1432 dwarf2_parse_variable(module, entry, ctx);
1433 break;
1434 case DW_TAG_label:
1435 default:
1437 dwarf2_abbrev_entry_attr_t* attr;
1438 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1439 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1440 dwarf2_parse_attr(attr, ctx);
1443 break;
1448 /** set correct data cursor */
1449 dwarf2_check_sibling(ctx, next_sibling);
1453 static void dwarf2_parse_subprogram_block(struct module* module,
1454 dwarf2_abbrev_entry_t* entry,
1455 dwarf2_parse_context_t* ctx,
1456 struct symt_function_signature* sig_type,
1457 struct symt_function* func_type)
1459 dwarf2_abbrev_entry_attr_t* attr = NULL;
1460 const char* name = NULL;
1461 unsigned long next_sibling = 0;
1463 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1465 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1466 switch (attr->attribute) {
1467 case DW_AT_sibling:
1468 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1469 break;
1470 case DW_AT_name:
1471 name = dwarf2_parse_attr_as_string(attr, ctx);
1472 TRACE("found name %s\n", name);
1473 break;
1474 case DW_AT_decl_file:
1475 case DW_AT_decl_line:
1476 dwarf2_parse_attr(attr, ctx);
1477 break;
1478 case DW_AT_ranges: /** what to do ? */
1479 dwarf2_parse_attr(attr, ctx);
1480 break;
1481 default:
1482 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1483 dwarf2_parse_attr(attr, ctx);
1487 if (entry->have_child) { /** any interest to not have child ? */
1488 while (ctx->data < ctx->end_data) {
1489 dwarf2_abbrev_entry_t* entry = NULL;
1490 unsigned long entry_code;
1491 unsigned long entry_ref = 0;
1493 entry_ref = ctx->data - ctx->data_stream;
1495 entry_code = dwarf2_leb128_as_unsigned(ctx);
1496 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1497 if (0 == entry_code) {
1498 break ;
1501 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1502 assert( NULL != entry );
1504 switch (entry->tag) {
1505 case DW_TAG_inlined_subroutine:
1506 dwarf2_parse_inlined_subroutine(module, entry, ctx);
1507 break;
1508 case DW_TAG_variable:
1509 dwarf2_parse_variable(module, entry, ctx);
1510 break;
1511 case DW_TAG_label:
1512 default:
1514 dwarf2_abbrev_entry_attr_t* attr;
1515 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1516 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1517 dwarf2_parse_attr(attr, ctx);
1520 break;
1525 /** set correct data cursor */
1526 dwarf2_check_sibling(ctx, next_sibling);
1529 static void dwarf2_parse_subprogram_content(struct module* module,
1530 dwarf2_abbrev_entry_t* entry,
1531 dwarf2_parse_context_t* ctx,
1532 struct symt_function_signature* sig_type,
1533 struct symt_function* func_type)
1535 if (entry->have_child) { /** any interest to not have child ? */
1536 while (ctx->data < ctx->end_data) {
1537 dwarf2_abbrev_entry_t* entry = NULL;
1538 unsigned long entry_code;
1539 unsigned long entry_ref = 0;
1541 entry_ref = ctx->data - ctx->data_stream;
1543 entry_code = dwarf2_leb128_as_unsigned(ctx);
1544 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1545 if (0 == entry_code) {
1546 break ;
1549 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1550 assert( NULL != entry );
1552 switch (entry->tag) {
1553 case DW_TAG_formal_parameter:
1554 dwarf2_parse_subprogram_parameter(module, entry, ctx, sig_type, func_type);
1555 break;
1556 case DW_TAG_lexical_block:
1557 dwarf2_parse_subprogram_block(module, entry, ctx, sig_type, func_type);
1558 break;
1559 case DW_TAG_variable:
1560 dwarf2_parse_variable(module, entry, ctx);
1561 break;
1562 case DW_TAG_label:
1563 default:
1565 dwarf2_abbrev_entry_attr_t* attr;
1566 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1567 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1568 dwarf2_parse_attr(attr, ctx);
1571 break;
1577 static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1579 struct symt_function* func_type = NULL;
1580 const char* name = NULL;
1581 struct symt* ret_type = NULL;
1582 struct symt_function_signature* sig_type = NULL;
1583 unsigned long addr = 0;
1584 unsigned long low_pc = 0;
1585 unsigned long high_pc = 0;
1586 unsigned size = 0;
1587 unsigned char is_decl = 0;
1588 unsigned char inl_flags = 0;
1589 unsigned char decl_file = 0;
1590 unsigned char decl_line = 0;
1591 dwarf2_abbrev_entry_attr_t* attr = NULL;
1592 unsigned long next_sibling = 0;
1593 enum CV_call_e call_conv = CV_CALL_FAR_C; /* FIXME: assuming C source code */
1594 unsigned cc;
1596 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code);
1598 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1599 switch (attr->attribute) {
1600 case DW_AT_sibling:
1601 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1602 break;
1603 case DW_AT_low_pc:
1604 low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1605 addr = module->module.BaseOfImage + low_pc;
1606 break;
1607 case DW_AT_high_pc:
1608 high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1609 size = high_pc - low_pc;
1610 break;
1611 case DW_AT_name:
1612 name = dwarf2_parse_attr_as_string(attr, ctx);
1613 TRACE("found name %s\n", name);
1614 break;
1615 case DW_AT_type:
1617 unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1618 ret_type = dwarf2_find_symt_by_ref(module, ref);
1620 break;
1621 case DW_AT_declaration:
1622 is_decl = dwarf2_parse_byte(ctx);
1623 break;
1624 case DW_AT_inline:
1625 inl_flags = dwarf2_parse_byte(ctx);
1626 break;
1627 case DW_AT_calling_convention:
1628 switch (cc = dwarf2_parse_byte(ctx))
1630 case DW_CC_normal: break;
1631 case DW_CC_nocall: call_conv = -1;
1632 default: FIXME("Unsupported calling convention %d\n", cc);
1634 break;
1635 /* not work yet, need parsing .debug_line and using Compil Unit stmt_list
1636 case DW_AT_decl_file:
1637 decl_file = dwarf2_parse_byte(ctx);
1638 break;
1639 case DW_AT_decl_line:
1640 decl_line = dwarf2_parse_byte(ctx);
1641 break;
1643 default:
1644 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1645 dwarf2_parse_attr(attr, ctx);
1648 sig_type = symt_new_function_signature(module, ret_type, call_conv);
1649 if (!is_decl) {
1650 func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt);
1651 if (low_pc && high_pc) {
1652 symt_add_function_point(module, func_type, SymTagFuncDebugStart, low_pc, NULL);
1653 symt_add_function_point(module, func_type, SymTagFuncDebugEnd, high_pc, NULL);
1655 if (decl_file && decl_line) {
1656 symt_add_func_line(module, func_type, decl_file, decl_line, low_pc);
1659 dwarf2_parse_subprogram_content(module, entry, ctx, sig_type, func_type);
1660 symt_normalize_function(module, func_type);
1662 /** set correct data cursor */
1663 dwarf2_check_sibling(ctx, next_sibling);
1665 return func_type;
1668 static void dwarf2_parse_compiland_content(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1670 if (entry->have_child) { /** any interest to not have child ? */
1671 while (ctx->data < ctx->end_data) {
1672 dwarf2_abbrev_entry_t* entry = NULL;
1673 unsigned long entry_code;
1674 unsigned long entry_ref = 0;
1676 entry_ref = ctx->data - ctx->data_stream;
1678 entry_code = dwarf2_leb128_as_unsigned(ctx);
1679 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1680 if (0 == entry_code) {
1681 break ;
1684 entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1685 assert( NULL != entry );
1687 switch (entry->tag) {
1688 case DW_TAG_typedef:
1689 dwarf2_parse_typedef(module, entry, ctx);
1690 break;
1691 case DW_TAG_base_type:
1692 dwarf2_parse_base_type(module, entry, ctx);
1693 break;
1694 case DW_TAG_pointer_type:
1695 dwarf2_parse_pointer_type(module, entry, ctx);
1696 break;
1697 case DW_TAG_class_type:
1698 dwarf2_parse_udt_type(module, entry, ctx, UdtClass);
1699 break;
1700 case DW_TAG_structure_type:
1701 dwarf2_parse_udt_type(module, entry, ctx, UdtStruct);
1702 break;
1703 case DW_TAG_union_type:
1704 dwarf2_parse_udt_type(module, entry, ctx, UdtUnion);
1705 break;
1706 case DW_TAG_array_type:
1707 dwarf2_parse_array_type(module, entry, ctx);
1708 break;
1709 case DW_TAG_const_type:
1710 dwarf2_parse_const_type(module, entry, ctx);
1711 break;
1712 case DW_TAG_reference_type:
1713 dwarf2_parse_reference_type(module, entry, ctx);
1714 break;
1715 case DW_TAG_enumeration_type:
1716 dwarf2_parse_enumeration_type(module, entry, ctx);
1717 break;
1718 case DW_TAG_subprogram:
1719 dwarf2_parse_subprogram(module, entry, ctx, compiland);
1720 break;
1722 default:
1724 dwarf2_abbrev_entry_attr_t* attr;
1725 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
1726 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1727 dwarf2_parse_attr(attr, ctx);
1730 break;
1736 static struct symt_compiland* dwarf2_parse_compiland(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1738 struct symt_compiland* compiland = NULL;
1739 const char* name = NULL;
1740 unsigned long next_sibling = 0;
1741 dwarf2_abbrev_entry_attr_t* attr = NULL;
1743 TRACE("beginning at Ox%x, for %lu\n", ctx->data - ctx->start_data, entry->entry_code);
1745 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1746 switch (attr->attribute) {
1747 case DW_AT_sibling:
1748 next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1749 break;
1750 case DW_AT_name:
1751 name = dwarf2_parse_attr_as_string(attr, ctx);
1752 TRACE("found name %s\n", name);
1753 break;
1754 default:
1755 WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1756 dwarf2_parse_attr(attr, ctx);
1759 compiland = symt_new_compiland(module, name);
1760 dwarf2_parse_compiland_content(module, entry, ctx, compiland);
1762 dwarf2_check_sibling(ctx, next_sibling);
1764 return compiland;
1767 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
1768 const unsigned char* debug, unsigned int debug_size,
1769 const unsigned char* abbrev, unsigned int abbrev_size,
1770 const unsigned char* str, unsigned int str_sz)
1772 const unsigned char* comp_unit_cursor = debug;
1773 const unsigned char* end_debug = debug + debug_size;
1775 while (comp_unit_cursor < end_debug) {
1776 const dwarf2_comp_unit_stream_t* comp_unit_stream;
1777 dwarf2_comp_unit_t comp_unit;
1778 dwarf2_parse_context_t ctx;
1779 dwarf2_parse_context_t abbrev_ctx;
1780 struct symt_compiland* compiland = NULL;
1781 dwarf2_debug_info_t* di;
1783 comp_unit_stream = (const dwarf2_comp_unit_stream_t*) comp_unit_cursor;
1785 comp_unit.length = *(unsigned long*) comp_unit_stream->length;
1786 comp_unit.version = *(unsigned short*) comp_unit_stream->version;
1787 comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset;
1788 comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size;
1790 TRACE("Compilation Unit Herder found at 0x%x:\n", comp_unit_cursor - debug);
1791 TRACE("- length: %lu\n", comp_unit.length);
1792 TRACE("- version: %u\n", comp_unit.version);
1793 TRACE("- abbrev_offset: %lu\n", comp_unit.abbrev_offset);
1794 TRACE("- word_size: %u\n", comp_unit.word_size);
1796 pool_init(&ctx.pool, 65536);
1797 ctx.data_stream = debug;
1798 ctx.data = ctx.start_data = comp_unit_cursor + sizeof(dwarf2_comp_unit_stream_t);
1799 ctx.offset = comp_unit_cursor - debug;
1800 ctx.word_size = comp_unit.word_size;
1801 ctx.str_section = str;
1803 comp_unit_cursor += comp_unit.length + sizeof(unsigned);
1804 ctx.end_data = comp_unit_cursor;
1806 if (2 != comp_unit.version) {
1807 WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", comp_unit.version);
1808 continue ;
1811 abbrev_ctx.data_stream = abbrev;
1812 abbrev_ctx.data = abbrev_ctx.start_data = abbrev + comp_unit.abbrev_offset;
1813 abbrev_ctx.end_data = abbrev + abbrev_size;
1814 abbrev_ctx.offset = comp_unit.abbrev_offset;
1815 abbrev_ctx.str_section = str;
1816 dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
1818 sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128);
1819 dwarf2_read_one_debug_info(&ctx, &di);
1820 ctx.data = ctx.start_data; /* FIXME */
1822 while (ctx.data < ctx.end_data) {
1823 const dwarf2_abbrev_entry_t* entry = NULL;
1824 unsigned long entry_code;
1825 unsigned long entry_ref = 0;
1827 entry_ref = ctx.data - ctx.data_stream;
1829 entry_code = dwarf2_leb128_as_unsigned(&ctx);
1830 TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1831 if (0 == entry_code) {
1832 continue ;
1834 entry = dwarf2_abbrev_table_find_entry(&ctx.abbrev_table, entry_code);
1835 if (NULL == entry) {
1836 WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, entry_ref);
1837 pool_destroy(&ctx.pool);
1838 return FALSE;
1841 switch (entry->tag) {
1842 case DW_TAG_compile_unit:
1843 compiland = dwarf2_parse_compiland(module, entry, &ctx);
1844 break;
1845 default:
1847 dwarf2_abbrev_entry_attr_t* attr;
1848 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(&ctx), entry->entry_code);
1849 for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1850 dwarf2_parse_attr(attr, &ctx);
1853 break;
1856 pool_destroy(&ctx.pool);
1859 module->module.SymType = SymDia;
1860 return TRUE;