dbghelp: Dwarf abbrev table is now a sparse array.
[wine] / dlls / dbghelp / dwarf.c
1 /*
2  * File dwarf.c - read dwarf2 information from the ELF modules
3  *
4  * Copyright (C) 2005, Raphael Junqueira
5  * Copyright (C) 2006, Eric Pouech
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include "config.h"
23
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>
44
45 #include "windef.h"
46 #include "winbase.h"
47 #include "winreg.h"
48 #include "winnls.h"
49
50 #include "dbghelp_private.h"
51
52 #include "wine/debug.h"
53
54 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_dwarf);
55
56 #if 0
57 static void dump(const void* ptr, unsigned len)
58 {
59   int         i, j;
60   BYTE        msg[128];
61   static const char hexof[] = "0123456789abcdef";
62   const BYTE* x = (const BYTE*)ptr;
63
64   for (i = 0; i < len; i += 16)
65   {
66     sprintf(msg, "%08x: ", i);
67     memset(msg + 10, ' ', 3 * 16 + 1 + 16);
68     for (j = 0; j < min(16, len - i); j++)
69     {
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] : '.';
75     }
76     msg[10 + 3 * 16] = ' ';
77     msg[10 + 3 * 16 + 1 + 16] = '\0';
78     TRACE("%s\n", msg);
79   }
80 }
81 #endif
82
83 /**
84  *
85  * Main Specs:
86  *  http://www.eagercon.com/dwarf/dwarf3std.htm
87  *  http://www.eagercon.com/dwarf/dwarf-2.0.0.pdf
88  *
89  * dwarf2.h: http://www.hakpetzna.com/b/binutils/dwarf2_8h-source.html
90  *
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
94  */
95 #include "dwarf.h"
96
97 /**
98  * Parsers
99  */
100
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;
106
107 typedef struct dwarf2_abbrev_entry_s
108 {
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;
115
116 typedef struct dwarf2_parse_context_s {
117   struct pool pool;
118   struct sparse_array abbrev_table;
119   const unsigned char* data_stream;
120   const unsigned char* data;
121   const unsigned char* start_data;
122   const unsigned char* end_data;
123   const unsigned char* str_section;
124   unsigned long offset;
125   unsigned char word_size;
126 } dwarf2_parse_context_t;
127
128 /* forward declarations */
129 static struct symt_enum* dwarf2_parse_enumeration_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx);
130
131 static unsigned char dwarf2_parse_byte(dwarf2_parse_context_t* ctx)
132 {
133   unsigned char uvalue = *(const unsigned char*) ctx->data;
134   ctx->data += 1;
135   return uvalue;
136 }
137
138 static unsigned short dwarf2_parse_u2(dwarf2_parse_context_t* ctx)
139 {
140   unsigned short uvalue = *(const unsigned short*) ctx->data;
141   ctx->data += 2;
142   return uvalue;
143 }
144
145 static unsigned long dwarf2_parse_u4(dwarf2_parse_context_t* ctx)
146 {
147   unsigned long uvalue = *(const unsigned int*) ctx->data;
148   ctx->data += 4;
149   return uvalue;
150 }
151
152 static unsigned long dwarf2_leb128_as_unsigned(dwarf2_parse_context_t* ctx)
153 {
154   unsigned long ret = 0;
155   unsigned char byte;
156   unsigned shift = 0;
157
158   assert( NULL != ctx );
159
160   while (1) {
161     byte = dwarf2_parse_byte(ctx);
162     ret |= (byte & 0x7f) << shift;
163     shift += 7;
164     if (0 == (byte & 0x80)) { break ; }
165   }
166
167   return ret;
168 }
169
170 static long dwarf2_leb128_as_signed(dwarf2_parse_context_t* ctx)
171 {
172   long ret = 0;
173   unsigned char byte;
174   unsigned shift = 0;
175   const unsigned size = sizeof(int) * 8;
176
177   assert( NULL != ctx );
178
179   while (1) {
180     byte = dwarf2_parse_byte(ctx);
181     ret |= (byte & 0x7f) << shift;
182     shift += 7;
183     if (0 == (byte & 0x80)) { break ; }
184   }
185   /* as spec: sign bit of byte is 2nd high order bit (80x40)
186    *  -> 0x80 is used as flag.
187    */
188   if ((shift < size) && (byte & 0x40)) {
189     ret |= - (1 << shift);
190   }
191   return ret;
192 }
193
194 static const char* dwarf2_debug_ctx(dwarf2_parse_context_t* ctx) 
195 {
196   /*return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->start_data, ctx->level); */
197   return wine_dbg_sprintf("ctx(0x%x)", ctx->data - ctx->data_stream); 
198 }
199 static const char* dwarf2_debug_attr(dwarf2_abbrev_entry_attr_t* attr) 
200 {
201   return wine_dbg_sprintf("attr(attr:0x%lx,form:0x%lx)", attr->attribute, attr->form);
202 }
203
204 static void dwarf2_check_sibling(dwarf2_parse_context_t* ctx, unsigned long next_sibling)
205
206   if (0 < next_sibling && ctx->data != ctx->data_stream + next_sibling) {
207     if ((ctx->data + 1) != ctx->data_stream + next_sibling) {
208       /** padding check */
209       WARN("cursor error for %s should be sibling<0x%lx>\n", dwarf2_debug_ctx(ctx), next_sibling);
210     }
211     ctx->data = ctx->data_stream + next_sibling;
212   }
213 }
214
215
216 static dwarf2_abbrev_entry_t*
217 dwarf2_abbrev_table_find_entry(struct sparse_array* abbrev_table,
218                                unsigned long entry_code)
219 {
220     assert( NULL != abbrev_table );
221     return sparse_array_find(abbrev_table, entry_code);
222 }
223
224 static void dwarf2_parse_abbrev_set(dwarf2_parse_context_t* abbrev_ctx, 
225                                     struct sparse_array* abbrev_table,
226                                     struct pool* pool)
227 {
228     unsigned long entry_code;
229     dwarf2_abbrev_entry_t* abbrev_entry;
230     dwarf2_abbrev_entry_attr_t* new = NULL;
231     dwarf2_abbrev_entry_attr_t* last = NULL;
232     unsigned long attribute;
233     unsigned long form;
234
235     TRACE("%s, end at %p\n", dwarf2_debug_ctx(abbrev_ctx), abbrev_ctx->end_data); 
236
237     assert( NULL != abbrev_ctx );
238
239     sparse_array_init(abbrev_table, sizeof(dwarf2_abbrev_entry_t), 32);
240     while (abbrev_ctx->data < abbrev_ctx->end_data)
241     {
242         TRACE("now at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
243         entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx);
244         TRACE("found entry_code %lu\n", entry_code);
245         if (!entry_code)
246         {
247             TRACE("NULL entry code at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
248             break;
249         }
250         abbrev_entry = sparse_array_add(abbrev_table, entry_code, pool);
251         assert( NULL != abbrev_entry );
252
253         abbrev_entry->entry_code = entry_code;
254         abbrev_entry->tag        = dwarf2_leb128_as_unsigned(abbrev_ctx);
255         abbrev_entry->have_child = dwarf2_parse_byte(abbrev_ctx);
256         abbrev_entry->attrs      = NULL;
257         abbrev_entry->num_attr   = 0;
258
259         TRACE("table:(%p,#%u) entry_code(%lu) tag(0x%lx) have_child(%u) -> %p\n",
260               abbrev_table, sparse_array_length(abbrev_table),
261               entry_code, abbrev_entry->tag, abbrev_entry->have_child, abbrev_entry);
262
263         last = NULL;
264         while (1)
265         {
266             attribute = dwarf2_leb128_as_unsigned(abbrev_ctx);
267             form = dwarf2_leb128_as_unsigned(abbrev_ctx);
268             if (!attribute) break;
269
270             new = pool_alloc(pool, sizeof(dwarf2_abbrev_entry_attr_t));
271             assert(new);
272
273             new->attribute = attribute;
274             new->form      = form;
275             new->next      = NULL;
276             if (abbrev_entry->attrs)    last->next = new;
277             else                        abbrev_entry->attrs = new;
278             last = new;
279             abbrev_entry->num_attr++;
280         }
281     }
282     TRACE("found %u entries\n", sparse_array_length(abbrev_table));
283 }
284
285 static const char* dwarf2_parse_attr_as_string(dwarf2_abbrev_entry_attr_t* attr,
286                                                dwarf2_parse_context_t* ctx)
287 {
288   const char* ret = NULL;
289   switch (attr->form) {
290   case DW_FORM_string:
291     ret = (const char*) ctx->data;
292     ctx->data += strlen(ret) + 1;
293     break;
294   case DW_FORM_strp:
295     {
296       unsigned long offset = dwarf2_parse_u4(ctx);
297       ret = (const char*) ctx->str_section + offset;
298       /*FIXME("Unsupported indirect string format offset 0x%lx (in .debug_str)\n", offset);*/
299     }
300     break;
301   default:
302     ERR("Unsupported string format 0x%lx for attr 0x%lx\n", attr->form, attr->attribute);
303   }
304   return ret;
305 }
306
307 static unsigned long dwarf2_parse_attr_as_addr(dwarf2_abbrev_entry_attr_t* attr,
308                                                dwarf2_parse_context_t* ctx)
309 {
310   unsigned long offset = 0;
311   switch (ctx->word_size) {
312   case 4:
313     offset = *(const unsigned int*) ctx->data;
314     break;
315   case 8:
316   default:
317     FIXME("Unsupported Word Size %u\n", ctx->word_size);
318   }
319   ctx->data += ctx->word_size;
320   return offset;  
321 }
322
323 static unsigned long dwarf2_parse_attr_as_ref(dwarf2_abbrev_entry_attr_t* attr,
324                                               dwarf2_parse_context_t* ctx)
325 {
326   unsigned long uvalue = 0;
327   switch (attr->form) {
328   case DW_FORM_ref1:
329     uvalue = ctx->offset + dwarf2_parse_byte(ctx);
330     TRACE("ref1<0x%lx>\n", uvalue);
331     break;
332
333   case DW_FORM_ref2:
334     uvalue = ctx->offset + dwarf2_parse_u2(ctx);
335     TRACE("ref2<0x%lx>\n", uvalue);
336     break;
337
338   case DW_FORM_ref4:
339     uvalue = ctx->offset + dwarf2_parse_u4(ctx);
340     TRACE("ref4<0x%lx>\n", uvalue);
341     break;
342
343   case DW_FORM_ref8:
344     /* FIXME: 64bits support */
345     /*
346     uvalue = ctx->offset + dwarf2_parse_u8(ctx);
347     TRACE("ref8<0x%lx>\n", uvalue);
348     */
349     ctx->data += 8;
350     break;
351   }
352   return uvalue;
353 }
354
355
356 static unsigned long dwarf2_parse_attr_as_data(dwarf2_abbrev_entry_attr_t* attr,
357                                                dwarf2_parse_context_t* ctx)
358 {
359   unsigned long uvalue = 0;
360   switch (attr->form) {
361   case DW_FORM_data1:
362     uvalue = dwarf2_parse_byte(ctx);
363     TRACE("data1<%lu>\n", uvalue);
364     break;
365
366   case DW_FORM_data2:
367     uvalue = dwarf2_parse_u2(ctx);
368     TRACE("data2<%lu>\n", uvalue);
369     break;
370
371   case DW_FORM_data4:
372     uvalue = dwarf2_parse_u4(ctx);
373     TRACE("data4<%lu>\n", uvalue);
374     break;
375
376   case DW_FORM_data8:
377     FIXME("Unsupported 64bits support\n");
378     ctx->data += 8;
379     break;
380   }
381   return uvalue;
382 }
383
384 static void dwarf2_parse_attr(dwarf2_abbrev_entry_attr_t* attr,
385                               dwarf2_parse_context_t* ctx)
386 {
387   const unsigned long attribute = attr->attribute;
388   const unsigned long form = attr->form;
389   unsigned long uvalue = 0;
390   long svalue = 0;
391   const char* str = NULL;
392
393   TRACE("(attr:0x%lx,form:0x%lx)\n", attribute, form);
394
395   switch (form) {
396   case DW_FORM_ref_addr:
397   case DW_FORM_addr:
398     uvalue = dwarf2_parse_attr_as_addr(attr, ctx);
399     break;
400
401   case DW_FORM_flag:
402     uvalue = dwarf2_parse_byte(ctx);
403     TRACE("flag<0x%lx>\n", uvalue);
404     break;
405
406   case DW_FORM_data1:
407     uvalue = dwarf2_parse_byte(ctx);
408     TRACE("data1<%lu>\n", uvalue);
409     break;
410
411   case DW_FORM_data2:
412     uvalue = dwarf2_parse_u2(ctx);
413     TRACE("data2<%lu>\n", uvalue);
414     break;
415
416   case DW_FORM_data4:
417     uvalue = dwarf2_parse_u4(ctx);
418     TRACE("data4<%lu>\n", uvalue);
419     break;
420
421   case DW_FORM_ref1:
422   case DW_FORM_ref2:
423   case DW_FORM_ref4:
424   case DW_FORM_ref8:
425     uvalue = dwarf2_parse_attr_as_ref(attr, ctx);
426     /*TRACE("ref<0x%lx>\n", ctx->offset + uvalue);*/
427     break;
428
429   case DW_FORM_data8:
430     FIXME("Unsupported 64bits support\n");
431     ctx->data += 8;
432     break;
433
434   case DW_FORM_sdata:
435     svalue = dwarf2_leb128_as_signed(ctx);
436     break;
437
438   case DW_FORM_ref_udata:
439   case DW_FORM_udata:
440     uvalue = dwarf2_leb128_as_unsigned(ctx);
441     break;
442
443   case DW_FORM_string:
444   case DW_FORM_strp:
445     str = dwarf2_parse_attr_as_string(attr, ctx);
446     TRACE("string<%s>\n", str);
447     break;
448
449   case DW_FORM_block:
450     uvalue = dwarf2_leb128_as_unsigned(ctx);
451     ctx->data += uvalue;
452     break;
453
454   case DW_FORM_block1:
455     uvalue = dwarf2_parse_byte(ctx);
456     ctx->data += uvalue;
457     break;
458
459   case DW_FORM_block2:
460     uvalue = dwarf2_parse_u2(ctx);
461     ctx->data += uvalue;
462     break;
463
464   case DW_FORM_block4:
465     uvalue = dwarf2_parse_u4(ctx);
466     ctx->data += uvalue;
467     break;
468
469   default:
470     break;
471   }
472 }
473
474 static struct symt* dwarf2_find_symt_by_ref(struct module* module, unsigned long ref)
475 {
476   WARN("want ref<0x%lx>\n", ref); 
477   return NULL;
478 }
479
480 static struct symt* dwarf2_add_symt_ref(struct module* module, unsigned long ref, struct symt* symt)
481 {
482   if (NULL != symt) return NULL;
483   return NULL;
484 }
485
486 static struct symt_basic* dwarf2_parse_base_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
487 {
488   struct symt_basic* symt = NULL;
489   const char* name = NULL;
490   unsigned size = 0;
491   unsigned encoding = 0;
492   enum BasicType bt;
493   dwarf2_abbrev_entry_attr_t* attr = NULL;
494
495   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
496
497   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
498     switch (attr->attribute) {
499     case DW_AT_name:
500       name = dwarf2_parse_attr_as_string(attr, ctx);
501       TRACE("found name %s\n", name);
502       break;
503     case DW_AT_byte_size:
504       size = dwarf2_parse_attr_as_data(attr, ctx);
505       break;
506     case DW_AT_encoding:
507       encoding = dwarf2_parse_byte(ctx);
508       break;
509     default:
510       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
511       dwarf2_parse_attr(attr, ctx);
512     }
513   }
514   switch (encoding) {
515   case DW_ATE_void: bt = btVoid; break;
516   case DW_ATE_address: bt = btULong; break;
517   case DW_ATE_boolean: bt = btBool; break;
518   case DW_ATE_complex_float: bt = btComplex; break;
519   case DW_ATE_float: bt = btFloat; break;
520   case DW_ATE_signed: bt = btInt; break;
521   case DW_ATE_unsigned: bt = btUInt; break;
522   case DW_ATE_signed_char: bt = btChar; break;
523   case DW_ATE_unsigned_char: bt = btChar; break;
524   default:
525     bt = btNoType;
526   }
527   /*TRACE("symt_new_basic(%p, %u, %s, %u)", module, bt, name, size);*/
528   symt = symt_new_basic(module, bt, name, size);
529
530   if (entry->have_child) {
531     FIXME("Unsupported children\n");
532   }
533   return symt;
534 }
535
536 static struct symt_typedef* dwarf2_parse_typedef(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
537 {
538   struct symt_typedef* symt = NULL;
539   struct symt* ref_type = NULL;
540   const char* name = NULL;
541   dwarf2_abbrev_entry_attr_t* attr = NULL;
542
543   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
544
545   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
546     switch (attr->attribute) {
547     case DW_AT_name:
548       name = dwarf2_parse_attr_as_string(attr, ctx);
549       TRACE("found name %s\n", name);
550       break;
551     case DW_AT_type:
552       {
553         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
554         ref_type = dwarf2_find_symt_by_ref(module, ref);
555       }
556       break;
557     case DW_AT_decl_file:
558     case DW_AT_decl_line:
559       dwarf2_parse_attr(attr, ctx);
560       break;
561     default:
562       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
563       dwarf2_parse_attr(attr, ctx);
564     }
565   }
566   if (NULL != name) {
567     symt = symt_new_typedef(module, ref_type, name);
568   }
569
570   if (entry->have_child) {
571     FIXME("Unsupported children\n");
572   }
573   return symt;
574 }
575
576 static struct symt_pointer* dwarf2_parse_pointer_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
577 {
578   struct symt_pointer* symt = NULL;
579   struct symt* ref_type = NULL;
580   unsigned size = 0;
581   dwarf2_abbrev_entry_attr_t* attr = NULL;
582
583   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
584
585   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
586     switch (attr->attribute) {
587     case DW_AT_byte_size:
588       size = dwarf2_parse_attr_as_data(attr, ctx);
589       break;
590     case DW_AT_type:
591       {
592         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
593         ref_type = dwarf2_find_symt_by_ref(module, ref);
594       }
595       break;
596     default:
597       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
598       dwarf2_parse_attr(attr, ctx);
599     }
600   }
601   symt = symt_new_pointer(module, ref_type);
602
603   if (entry->have_child) {
604     FIXME("Unsupported children\n");
605   }
606   return symt;
607 }
608
609 static void dwarf2_parse_array_subrange_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_array* parent)
610 {
611   unsigned min = 0;
612   unsigned max = 0;
613   struct symt* idx_type = NULL;
614   dwarf2_abbrev_entry_attr_t* attr = NULL;
615
616   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
617
618   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
619     switch (attr->attribute) {
620     case DW_AT_type:
621       {
622         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
623         idx_type = dwarf2_find_symt_by_ref(module, ref);
624         /** check if idx_type is a basic_type integer */
625       }
626       break;
627     case DW_AT_lower_bound:
628       TRACE("%s %s, lower_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
629       min = dwarf2_parse_attr_as_data(attr, ctx);
630       break;
631     case DW_AT_upper_bound:
632       TRACE("%s %s, upper_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
633       max = dwarf2_parse_attr_as_data(attr, ctx);
634       break;
635     case DW_AT_count:
636       TRACE("%s %s, count min:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), min); 
637       max = min + dwarf2_parse_attr_as_data(attr, ctx);
638       break;
639     default:
640       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
641       dwarf2_parse_attr(attr, ctx);
642     }
643   }
644   parent->start = min;
645   parent->end = max;
646   parent->index_type = idx_type;
647
648   TRACE("found min:%u max:%u\n", min, max);   
649
650   if (entry->have_child) {
651     FIXME("Unsupported children\n");
652   }
653 }
654
655
656 static struct symt_array* dwarf2_parse_array_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
657 {
658   struct symt_array* symt = NULL;
659   struct symt* ref_type = NULL;
660   unsigned min = 0;
661   unsigned max = 0;
662   dwarf2_abbrev_entry_attr_t* attr = NULL;
663   unsigned long next_sibling = 0;
664
665   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
666
667   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
668     switch (attr->attribute) {
669     case DW_AT_sibling:
670       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
671       break;
672     case DW_AT_type:
673       {
674         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
675         ref_type = dwarf2_find_symt_by_ref(module, ref);
676       }
677       break;
678     default:
679       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
680       dwarf2_parse_attr(attr, ctx);
681     }
682   }
683
684   /* FIXME: ugly as hell */
685   symt = symt_new_array(module, min, max, ref_type, NULL);
686
687   if (entry->have_child) { /** any interest to not have child ? */
688     while (ctx->data < ctx->end_data) {
689       dwarf2_abbrev_entry_t* entry = NULL;
690       unsigned long entry_code;
691       unsigned long entry_ref = 0;
692
693       entry_ref = ctx->data - ctx->data_stream;
694       
695       entry_code = dwarf2_leb128_as_unsigned(ctx);
696       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
697       if (0 == entry_code) {
698         break ;
699       }
700
701       entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
702       assert( NULL != entry );
703
704       switch (entry->tag) {
705       case DW_TAG_subrange_type:
706         dwarf2_parse_array_subrange_type(module, entry, ctx, symt);
707         break;
708       default:
709         {
710           dwarf2_abbrev_entry_attr_t* attr;
711           WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
712           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
713             dwarf2_parse_attr(attr, ctx);
714           }
715         }
716         break;
717       }
718     }
719   }
720
721   /** set correct data cursor */
722   dwarf2_check_sibling(ctx, next_sibling);
723
724   return symt;
725 }
726
727 static struct symt* dwarf2_parse_const_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
728 {
729   struct symt* ref_type = NULL;
730   dwarf2_abbrev_entry_attr_t* attr = NULL;
731   unsigned long next_sibling = 0;
732
733   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
734
735   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
736     switch (attr->attribute) {
737     case DW_AT_type:
738       {
739         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
740         ref_type = dwarf2_find_symt_by_ref(module, ref);
741       }
742       break;
743     default:
744       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
745       dwarf2_parse_attr(attr, ctx);
746     }
747   }
748
749   if (entry->have_child) {
750     FIXME("Unsupported children\n");
751   }
752
753   /** set correct data cursor */
754   dwarf2_check_sibling(ctx, next_sibling);
755
756   return ref_type;
757 }
758
759 static struct symt* dwarf2_parse_reference_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
760 {
761   struct symt* symt = NULL;
762   struct symt* ref_type = NULL;
763   dwarf2_abbrev_entry_attr_t* attr = NULL;
764   unsigned long next_sibling = 0;
765
766   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
767
768   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
769     switch (attr->attribute) {
770     case DW_AT_sibling:
771       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
772       break;
773     case DW_AT_type:
774       {
775         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
776         ref_type = dwarf2_find_symt_by_ref(module, ref);
777       }
778       break;
779     default:
780       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
781       dwarf2_parse_attr(attr, ctx);
782     }
783   }
784   /* FIXME: for now, we hard-wire C++ references to pointers */
785   symt = &symt_new_pointer(module, ref_type)->symt;
786
787   if (entry->have_child) {
788     FIXME("Unsupported children\n");
789   }
790
791   /** set correct data cursor */
792   dwarf2_check_sibling(ctx, next_sibling);
793
794   return symt;
795 }
796
797 static void dwarf2_parse_udt_member(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* parent)
798 {
799   struct symt* elt_type = NULL;
800   const char* name = NULL; 
801   unsigned long offset = 0;
802   unsigned size = 0;
803   dwarf2_abbrev_entry_attr_t* attr = NULL;
804   unsigned long next_sibling = 0;
805
806   assert( NULL != parent );
807
808   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
809
810   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
811     switch (attr->attribute) {
812     case DW_AT_sibling:
813       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
814       break;
815     case DW_AT_name:
816       name = dwarf2_parse_attr_as_string(attr, ctx);
817       TRACE("found name %s\n", name);
818       break;
819     case DW_AT_type:
820       {
821         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
822         elt_type = dwarf2_find_symt_by_ref(module, ref);
823       }
824       break;
825     case DW_AT_data_member_location:
826       {
827         unsigned long uvalue = 0;
828         TRACE("found member_location at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
829         /*offset = dwarf2_parse_attr_as_data(attr, ctx);*/
830         switch (attr->form) {
831         case DW_FORM_block:
832           uvalue = dwarf2_leb128_as_unsigned(ctx);
833           break;
834         case DW_FORM_block1:
835           uvalue = dwarf2_parse_byte(ctx);
836           break;
837         case DW_FORM_block2:
838           uvalue = dwarf2_parse_u2(ctx);
839           break;
840         case DW_FORM_block4:
841           uvalue = dwarf2_parse_u4(ctx);
842           break;
843         default:
844           WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
845           dwarf2_parse_attr(attr, ctx);
846         }
847         if (uvalue) {
848           unsigned char op = dwarf2_parse_byte(ctx);
849           --uvalue;
850           switch (op) {
851           case DW_OP_plus_uconst:
852             offset = dwarf2_leb128_as_unsigned(ctx);
853             break;
854           default:
855             WARN("Unhandled attr op at %s, for %s, op:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), op);
856             ctx->data += uvalue;
857           }
858           TRACE("found offset:%lu\n", offset);            
859         }
860       }
861       break;
862     case DW_AT_decl_file:
863     case DW_AT_decl_line:
864       dwarf2_parse_attr(attr, ctx);
865       break;
866     default:
867       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
868       dwarf2_parse_attr(attr, ctx);
869     }
870   }
871   symt_add_udt_element(module, parent, name, elt_type, offset, size);
872
873   if (entry->have_child) {
874     FIXME("Unsupported children\n");
875   }
876
877   /** set correct data cursor */
878   dwarf2_check_sibling(ctx, next_sibling);
879 }
880
881 static void dwarf2_parse_udt_members(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* symt)
882 {
883   if (entry->have_child) { /** any interest to not have child ? */
884     while (ctx->data < ctx->end_data) {
885       dwarf2_abbrev_entry_t* entry = NULL;
886       unsigned long entry_code;
887       unsigned long entry_ref = 0;
888
889       entry_ref = ctx->data - ctx->data_stream;
890       
891       entry_code = dwarf2_leb128_as_unsigned(ctx);
892       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
893       if (0 == entry_code) {
894         break ;
895       }
896
897       entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
898       assert( NULL != entry );
899
900       switch (entry->tag) {
901       case DW_TAG_member:
902         dwarf2_parse_udt_member(module, entry, ctx, symt);
903         break;
904       case DW_TAG_enumeration_type:
905         {
906           struct symt_enum* symt = dwarf2_parse_enumeration_type(module, entry, ctx);
907           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
908         }
909         break;
910       default:
911         {
912           dwarf2_abbrev_entry_attr_t* attr;
913           WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
914           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
915             dwarf2_parse_attr(attr, ctx);
916           }
917         }
918         break;
919       }
920     }
921   }
922 }
923
924 static struct symt_udt* dwarf2_parse_class_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
925 {
926   struct symt_udt* symt = NULL;
927   const char* name = NULL;
928   unsigned size = 0;
929   dwarf2_abbrev_entry_attr_t* attr = NULL;
930   unsigned long next_sibling = 0;
931
932   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
933
934   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
935     switch (attr->attribute) {
936     case DW_AT_sibling:
937       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
938       break;
939     case DW_AT_name:
940       name = dwarf2_parse_attr_as_string(attr, ctx);
941       TRACE("found name %s\n", name);
942       break;
943     case DW_AT_byte_size:
944       size = dwarf2_parse_attr_as_data(attr, ctx);
945       break;
946     case DW_AT_decl_file:
947     case DW_AT_decl_line:
948       dwarf2_parse_attr(attr, ctx);
949       break;
950     default:
951       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
952       dwarf2_parse_attr(attr, ctx);
953     }
954   }
955   symt = symt_new_udt(module, name, size, UdtClass);
956   dwarf2_parse_udt_members(module, entry, ctx, symt);
957
958   /** set correct data cursor */
959   dwarf2_check_sibling(ctx, next_sibling);
960
961   return symt;
962 }
963
964 static struct symt_udt* dwarf2_parse_struct_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
965 {
966   struct symt_udt* symt = NULL;
967   const char* name = NULL;
968   unsigned size = 0;
969   dwarf2_abbrev_entry_attr_t* attr = NULL;
970   unsigned long next_sibling = 0;
971
972   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
973
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_name:
980       name = dwarf2_parse_attr_as_string(attr, ctx);
981       TRACE("found name %s\n", name);
982       break;
983     case DW_AT_byte_size:
984       size = dwarf2_parse_attr_as_data(attr, ctx);
985       break;
986     case DW_AT_decl_file:
987     case DW_AT_decl_line:
988       dwarf2_parse_attr(attr, ctx);
989       break;
990     default:
991       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
992       dwarf2_parse_attr(attr, ctx);
993     }
994   }
995   symt = symt_new_udt(module, name, size, UdtStruct);
996   dwarf2_parse_udt_members(module, entry, ctx, symt);
997
998   /** set correct data cursor */
999   dwarf2_check_sibling(ctx, next_sibling);
1000
1001   return symt;
1002 }
1003
1004 static struct symt_udt* dwarf2_parse_union_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1005 {
1006   struct symt_udt* symt = NULL;
1007   const char* name = NULL;
1008   unsigned size = 0;
1009   dwarf2_abbrev_entry_attr_t* attr = NULL;
1010   unsigned long next_sibling = 0;
1011
1012   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1013
1014   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1015     switch (attr->attribute) {
1016     case DW_AT_sibling:
1017       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1018       break;
1019     case DW_AT_name:
1020       name = dwarf2_parse_attr_as_string(attr, ctx);
1021       TRACE("found name %s\n", name);
1022       break;
1023     case DW_AT_byte_size:
1024       size = dwarf2_parse_attr_as_data(attr, ctx);
1025       break;
1026     case DW_AT_decl_file:
1027     case DW_AT_decl_line:
1028       dwarf2_parse_attr(attr, ctx);
1029       break;
1030     default:
1031       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1032       dwarf2_parse_attr(attr, ctx);
1033     }
1034   }
1035   symt = symt_new_udt(module, name, size, UdtUnion);
1036   dwarf2_parse_udt_members(module, entry, ctx, symt);
1037
1038   /** set correct data cursor */
1039   dwarf2_check_sibling(ctx, next_sibling);
1040
1041   return symt;
1042 }
1043
1044 static void dwarf2_parse_enumerator(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_enum* parent)
1045 {
1046   const char* name = NULL;
1047   long value = 0;
1048   dwarf2_abbrev_entry_attr_t* attr = NULL;
1049
1050   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1051
1052   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1053     switch (attr->attribute) {
1054     case DW_AT_name:
1055       name = dwarf2_parse_attr_as_string(attr, ctx);
1056       TRACE("found name %s\n", name);
1057       break;
1058     case DW_AT_const_value:
1059       switch (attr->form) {
1060       case DW_FORM_sdata:
1061         value = dwarf2_leb128_as_signed(ctx);
1062         TRACE("found value %ld\n", value);
1063         break;
1064       case DW_FORM_udata:
1065         value = dwarf2_leb128_as_unsigned(ctx);
1066         TRACE("found value %ld\n", value);
1067         break;
1068       default:
1069         WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1070         dwarf2_parse_attr(attr, ctx);
1071       }
1072       break;
1073     default:
1074       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1075       dwarf2_parse_attr(attr, ctx);
1076     }
1077   }
1078   symt_add_enum_element(module, parent, name, value);
1079
1080   if (entry->have_child) {
1081     FIXME("Unsupported children\n");
1082   }
1083 }
1084
1085 static struct symt_enum* dwarf2_parse_enumeration_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1086 {
1087   struct symt_enum* symt = NULL;
1088   const char* name = NULL;
1089   unsigned long size = 0;
1090   dwarf2_abbrev_entry_attr_t* attr = NULL;
1091   unsigned long next_sibling = 0;
1092
1093   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1094
1095   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1096     switch (attr->attribute) {
1097     case DW_AT_sibling:
1098       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1099       break;
1100     case DW_AT_name:
1101       name = dwarf2_parse_attr_as_string(attr, ctx);
1102       TRACE("found name %s\n", name);
1103       break;
1104     case DW_AT_byte_size:
1105       size = dwarf2_parse_attr_as_data(attr, ctx);
1106       break;
1107     case DW_AT_decl_file:
1108     case DW_AT_decl_line:
1109       dwarf2_parse_attr(attr, ctx);
1110       break;
1111     default:
1112       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1113       dwarf2_parse_attr(attr, ctx);
1114     }
1115   }
1116   symt = symt_new_enum(module, name);
1117
1118   if (entry->have_child) { /** any interest to not have child ? */
1119     while (ctx->data < ctx->end_data) {
1120       dwarf2_abbrev_entry_t* entry = NULL;
1121       unsigned long entry_code;
1122       unsigned long entry_ref = 0;
1123
1124       entry_ref = ctx->data - ctx->data_stream;
1125       
1126       entry_code = dwarf2_leb128_as_unsigned(ctx);
1127       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1128       if (0 == entry_code) {
1129         break ;
1130       }
1131
1132       entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1133       assert( NULL != entry );
1134
1135       switch (entry->tag) {
1136       case DW_TAG_enumerator:
1137         dwarf2_parse_enumerator(module, entry, ctx, symt);
1138         break;
1139       default:
1140         {
1141           dwarf2_abbrev_entry_attr_t* attr;
1142           WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1143           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1144             dwarf2_parse_attr(attr, ctx);
1145           }
1146         }
1147         break;
1148       }
1149     }
1150   }
1151
1152   /** set correct data cursor */
1153   dwarf2_check_sibling(ctx, next_sibling);
1154
1155   return symt;
1156 }
1157
1158 static void dwarf2_parse_variable(struct module* module, 
1159                                   dwarf2_abbrev_entry_t* entry, 
1160                                   dwarf2_parse_context_t* ctx) 
1161 {
1162   struct symt* var_type = NULL;
1163   dwarf2_abbrev_entry_attr_t* attr = NULL;
1164   const char* name = NULL;
1165   unsigned long next_sibling = 0;
1166
1167   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1168
1169   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1170     switch (attr->attribute) {
1171     case DW_AT_sibling:
1172       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1173       break;
1174     case DW_AT_type:
1175       {
1176         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1177         var_type = dwarf2_find_symt_by_ref(module, ref);
1178       }
1179       break;
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_decl_file:
1185     case DW_AT_decl_line:
1186       dwarf2_parse_attr(attr, ctx);
1187       break;
1188     default:
1189       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1190       dwarf2_parse_attr(attr, ctx);
1191     }
1192   }
1193
1194   if (entry->have_child) {
1195     FIXME("Unsupported children\n");
1196   }
1197
1198   /** set correct data cursor */
1199   dwarf2_check_sibling(ctx, next_sibling);  
1200 }
1201
1202 static void dwarf2_parse_subprogram_parameter(struct module* module, 
1203                                               dwarf2_abbrev_entry_t* entry, 
1204                                               dwarf2_parse_context_t* ctx, 
1205                                               struct symt_function_signature* sig_type,
1206                                               struct symt_function* func_type)
1207 {
1208   struct symt* param_type = NULL;
1209   const char* name = NULL;
1210   dwarf2_abbrev_entry_attr_t* attr = NULL;
1211   unsigned long next_sibling = 0;
1212
1213   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1214
1215   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1216     switch (attr->attribute) {
1217     case DW_AT_sibling:
1218       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1219       break;
1220     case DW_AT_type:
1221       {
1222         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1223         param_type = dwarf2_find_symt_by_ref(module, ref);
1224       }
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_decl_file:
1231     case DW_AT_decl_line:
1232       dwarf2_parse_attr(attr, ctx);
1233       break;
1234     case DW_AT_location:
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);
1240     }
1241   }
1242   if (NULL != sig_type) {
1243     symt_add_function_signature_parameter(module, sig_type, param_type);
1244   }
1245
1246   if (entry->have_child) {
1247     FIXME("Unsupported children\n");
1248   }
1249
1250   /** set correct data cursor */
1251   dwarf2_check_sibling(ctx, next_sibling);  
1252 }
1253
1254 static void dwarf2_parse_inlined_subroutine(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1255 {
1256   const char* name = NULL;
1257   unsigned long addr = 0;
1258   unsigned long low_pc = 0;
1259   unsigned long high_pc = 0;
1260   unsigned size = 0;
1261   dwarf2_abbrev_entry_attr_t* attr = NULL;
1262   unsigned long next_sibling = 0;
1263
1264   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1265
1266   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1267     switch (attr->attribute) {
1268     case DW_AT_sibling:
1269       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1270       break;
1271     case DW_AT_low_pc:
1272       low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1273       addr = module->module.BaseOfImage + low_pc;
1274       break;
1275     case DW_AT_high_pc:
1276       high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1277       size = high_pc - low_pc;
1278       break;
1279     case DW_AT_name:
1280       name = dwarf2_parse_attr_as_string(attr, ctx);
1281       TRACE("found name %s\n", name);
1282       break;
1283     case DW_AT_decl_file:
1284     case DW_AT_decl_line:
1285       dwarf2_parse_attr(attr, ctx);
1286       break;
1287     default:
1288       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1289       dwarf2_parse_attr(attr, ctx);
1290     }
1291   }
1292
1293   if (entry->have_child) { /** any interest to not have child ? */
1294     while (ctx->data < ctx->end_data) {
1295       dwarf2_abbrev_entry_t* entry = NULL;
1296       unsigned long entry_code;
1297       unsigned long entry_ref = 0;
1298
1299       entry_ref = ctx->data - ctx->data_stream;
1300       
1301       entry_code = dwarf2_leb128_as_unsigned(ctx);
1302       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1303       if (0 == entry_code) {
1304         break ;
1305       }
1306
1307       entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1308       assert( NULL != entry );
1309
1310       switch (entry->tag) {
1311       case DW_TAG_formal_parameter:
1312         dwarf2_parse_subprogram_parameter(module, entry, ctx, NULL, NULL);
1313         break;
1314       case DW_TAG_variable:
1315         dwarf2_parse_variable(module, entry, ctx);
1316         break;
1317       case DW_TAG_label:
1318       default:
1319         {
1320           dwarf2_abbrev_entry_attr_t* attr;
1321           WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1322           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1323             dwarf2_parse_attr(attr, ctx);
1324           }
1325         }
1326         break;
1327       }
1328     }
1329   }
1330
1331   /** set correct data cursor */
1332   dwarf2_check_sibling(ctx, next_sibling);
1333 }
1334
1335
1336 static void dwarf2_parse_subprogram_block(struct module* module, 
1337                                           dwarf2_abbrev_entry_t* entry, 
1338                                           dwarf2_parse_context_t* ctx, 
1339                                           struct symt_function_signature* sig_type,
1340                                           struct symt_function* func_type)
1341 {
1342   dwarf2_abbrev_entry_attr_t* attr = NULL;
1343   const char* name = NULL;
1344   unsigned long next_sibling = 0;
1345
1346   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1347
1348   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1349     switch (attr->attribute) {
1350     case DW_AT_sibling:
1351       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1352       break;
1353     case DW_AT_name:
1354       name = dwarf2_parse_attr_as_string(attr, ctx);
1355       TRACE("found name %s\n", name);
1356       break;
1357     case DW_AT_decl_file:
1358     case DW_AT_decl_line:
1359       dwarf2_parse_attr(attr, ctx);
1360       break;
1361     case DW_AT_ranges: /** what to do ? */
1362       dwarf2_parse_attr(attr, ctx);
1363       break;
1364     default:
1365       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1366       dwarf2_parse_attr(attr, ctx);
1367     }
1368   }
1369   
1370   if (entry->have_child) { /** any interest to not have child ? */
1371     while (ctx->data < ctx->end_data) {
1372       dwarf2_abbrev_entry_t* entry = NULL;
1373       unsigned long entry_code;
1374       unsigned long entry_ref = 0;
1375
1376       entry_ref = ctx->data - ctx->data_stream;
1377       
1378       entry_code = dwarf2_leb128_as_unsigned(ctx);
1379       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1380       if (0 == entry_code) {
1381         break ;
1382       }
1383
1384       entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1385       assert( NULL != entry );
1386
1387       switch (entry->tag) {
1388       case DW_TAG_inlined_subroutine:
1389         dwarf2_parse_inlined_subroutine(module, entry, ctx);
1390         break;
1391       case DW_TAG_variable:
1392         dwarf2_parse_variable(module, entry, ctx);
1393         break;
1394       case DW_TAG_label:
1395       default:
1396         {
1397           dwarf2_abbrev_entry_attr_t* attr;
1398           WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1399           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1400             dwarf2_parse_attr(attr, ctx);
1401           }
1402         }
1403         break;
1404       }
1405     }
1406   }
1407
1408   /** set correct data cursor */
1409   dwarf2_check_sibling(ctx, next_sibling);
1410 }
1411
1412 static void dwarf2_parse_subprogram_content(struct module* module, 
1413                                             dwarf2_abbrev_entry_t* entry, 
1414                                             dwarf2_parse_context_t* ctx, 
1415                                             struct symt_function_signature* sig_type,
1416                                             struct symt_function* func_type)
1417 {
1418   if (entry->have_child) { /** any interest to not have child ? */
1419     while (ctx->data < ctx->end_data) {
1420       dwarf2_abbrev_entry_t* entry = NULL;
1421       unsigned long entry_code;
1422       unsigned long entry_ref = 0;
1423
1424       entry_ref = ctx->data - ctx->data_stream;
1425       
1426       entry_code = dwarf2_leb128_as_unsigned(ctx);
1427       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1428       if (0 == entry_code) {
1429         break ;
1430       }
1431
1432       entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1433       assert( NULL != entry );
1434
1435       switch (entry->tag) {
1436       case DW_TAG_formal_parameter:
1437         dwarf2_parse_subprogram_parameter(module, entry, ctx, sig_type, func_type);
1438         break;
1439       case DW_TAG_lexical_block:
1440         dwarf2_parse_subprogram_block(module, entry, ctx, sig_type, func_type);
1441         break;
1442       case DW_TAG_variable:
1443         dwarf2_parse_variable(module, entry, ctx);
1444         break;
1445       case DW_TAG_label:
1446       default:
1447         {
1448           dwarf2_abbrev_entry_attr_t* attr;
1449           WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1450           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1451             dwarf2_parse_attr(attr, ctx);
1452           }
1453         }
1454         break;
1455       }
1456     }
1457   }
1458 }
1459
1460 static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1461 {
1462   struct symt_function* func_type = NULL;
1463   const char* name = NULL;
1464   struct symt* ret_type = NULL;
1465   struct symt_function_signature* sig_type = NULL;
1466   unsigned long addr = 0;
1467   unsigned long low_pc = 0;
1468   unsigned long high_pc = 0;
1469   unsigned size = 0;
1470   unsigned char is_decl = 0;
1471   unsigned char inl_flags = 0;
1472   unsigned char decl_file = 0;
1473   unsigned char decl_line = 0;
1474   dwarf2_abbrev_entry_attr_t* attr = NULL;
1475   unsigned long next_sibling = 0;
1476   enum CV_call_e call_conv = CV_CALL_FAR_C; /* FIXME: assuming C source code */
1477   unsigned cc;
1478
1479   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1480
1481   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1482     switch (attr->attribute) {
1483     case DW_AT_sibling:
1484       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1485       break;
1486     case DW_AT_low_pc:
1487       low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1488       addr = module->module.BaseOfImage + low_pc;
1489       break;
1490     case DW_AT_high_pc:
1491       high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1492       size = high_pc - low_pc;
1493       break;
1494     case DW_AT_name:
1495       name = dwarf2_parse_attr_as_string(attr, ctx);
1496       TRACE("found name %s\n", name);
1497       break;
1498     case DW_AT_type:
1499       {
1500         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1501         ret_type = dwarf2_find_symt_by_ref(module, ref);
1502       }
1503       break;
1504     case DW_AT_declaration:
1505       is_decl = dwarf2_parse_byte(ctx);
1506       break;
1507     case DW_AT_inline:
1508       inl_flags = dwarf2_parse_byte(ctx);
1509       break;
1510     case DW_AT_calling_convention:
1511         switch (cc = dwarf2_parse_byte(ctx))
1512         {
1513         case DW_CC_normal: break;
1514         case DW_CC_nocall: call_conv = -1;
1515         default: FIXME("Unsupported calling convention %d\n", cc);
1516         }
1517         break;
1518     /* not work yet, need parsing .debug_line and using Compil Unit stmt_list
1519     case DW_AT_decl_file:
1520       decl_file =  dwarf2_parse_byte(ctx);
1521       break;
1522     case DW_AT_decl_line:
1523       decl_line =  dwarf2_parse_byte(ctx);
1524       break;
1525     */
1526     default:
1527       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1528       dwarf2_parse_attr(attr, ctx);
1529     }
1530   }
1531   sig_type = symt_new_function_signature(module, ret_type, call_conv);
1532   if (!is_decl) {
1533     func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt);
1534     if (low_pc && high_pc) {
1535       symt_add_function_point(module, func_type, SymTagFuncDebugStart, low_pc, NULL);
1536       symt_add_function_point(module, func_type, SymTagFuncDebugEnd, high_pc, NULL);
1537     }
1538     if (decl_file && decl_line) {
1539       symt_add_func_line(module, func_type, decl_file, decl_line, low_pc);
1540     }
1541   }
1542   dwarf2_parse_subprogram_content(module, entry, ctx, sig_type, func_type);
1543   symt_normalize_function(module, func_type);
1544
1545   /** set correct data cursor */
1546   dwarf2_check_sibling(ctx, next_sibling);
1547
1548   return func_type;
1549 }
1550
1551 static void dwarf2_parse_compiland_content(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1552 {
1553   if (entry->have_child) { /** any interest to not have child ? */
1554     while (ctx->data < ctx->end_data) {
1555       dwarf2_abbrev_entry_t* entry = NULL;
1556       unsigned long entry_code;
1557       unsigned long entry_ref = 0;
1558
1559       entry_ref = ctx->data - ctx->data_stream;
1560       
1561       entry_code = dwarf2_leb128_as_unsigned(ctx);
1562       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1563       if (0 == entry_code) {
1564         break ;
1565       }
1566
1567       entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
1568       assert( NULL != entry );
1569
1570       switch (entry->tag) {
1571       case DW_TAG_typedef:
1572         {
1573           struct symt_typedef* symt = dwarf2_parse_typedef(module, entry, ctx);
1574           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1575         }
1576         break;
1577       case DW_TAG_base_type:
1578         {
1579           struct symt_basic* symt = dwarf2_parse_base_type(module, entry, ctx);
1580           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1581         }
1582         break;
1583       case DW_TAG_pointer_type:
1584         {
1585           struct symt_pointer* symt = dwarf2_parse_pointer_type(module, entry, ctx);
1586           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1587         }
1588         break;
1589       case DW_TAG_class_type:
1590         {
1591           struct symt_udt* symt = dwarf2_parse_class_type(module, entry, ctx);
1592           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1593         }
1594         break;
1595       case DW_TAG_structure_type:
1596         {
1597           struct symt_udt* symt = dwarf2_parse_struct_type(module, entry, ctx);
1598           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1599         }
1600         break;
1601       case DW_TAG_union_type:
1602         {
1603           struct symt_udt* symt = dwarf2_parse_union_type(module, entry, ctx);
1604           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1605         }
1606         break;
1607       case DW_TAG_array_type:
1608         {
1609           struct symt_array* symt = dwarf2_parse_array_type(module, entry, ctx);
1610           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1611         }
1612         break;
1613       case DW_TAG_const_type:
1614         {
1615           struct symt* symt = dwarf2_parse_const_type(module, entry, ctx);
1616           dwarf2_add_symt_ref(module, entry_ref, symt);
1617         }
1618         break;
1619       case DW_TAG_reference_type:
1620         {
1621           struct symt* symt = dwarf2_parse_reference_type(module, entry, ctx);
1622           dwarf2_add_symt_ref(module, entry_ref, symt);
1623         }
1624         break;
1625       case DW_TAG_enumeration_type:
1626         {
1627           struct symt_enum* symt = dwarf2_parse_enumeration_type(module, entry, ctx);
1628           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1629         }
1630         break;
1631       case DW_TAG_subprogram:
1632         {
1633           struct symt_function* symt = dwarf2_parse_subprogram(module, entry, ctx, compiland);
1634           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1635         }
1636         break;
1637
1638       default:
1639         {
1640           dwarf2_abbrev_entry_attr_t* attr;
1641           WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1642           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1643             dwarf2_parse_attr(attr, ctx);
1644           }
1645         }
1646         break;
1647       }
1648     }
1649   }
1650 }
1651
1652 static struct symt_compiland* dwarf2_parse_compiland(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1653 {
1654   struct symt_compiland* compiland = NULL;
1655   const char* name = NULL;
1656   unsigned long next_sibling = 0;
1657   dwarf2_abbrev_entry_attr_t* attr = NULL;
1658
1659   TRACE("beginning at Ox%x, for %lu\n", ctx->data - ctx->start_data, entry->entry_code); 
1660
1661   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1662     switch (attr->attribute) {
1663     case DW_AT_sibling:
1664       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1665       break;
1666     case DW_AT_name:
1667       name = dwarf2_parse_attr_as_string(attr, ctx);
1668       TRACE("found name %s\n", name);
1669       break;
1670     default:
1671       WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1672       dwarf2_parse_attr(attr, ctx);
1673     }
1674   }
1675   compiland = symt_new_compiland(module, name);
1676   dwarf2_parse_compiland_content(module, entry, ctx, compiland);
1677
1678   dwarf2_check_sibling(ctx, next_sibling);
1679
1680   return compiland;
1681 }
1682
1683 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
1684                   const unsigned char* debug, unsigned int debug_size,
1685                   const unsigned char* abbrev, unsigned int abbrev_size,
1686                   const unsigned char* str, unsigned int str_sz)
1687 {
1688   const unsigned char* comp_unit_cursor = debug;
1689   const unsigned char* end_debug = debug + debug_size;
1690
1691   while (comp_unit_cursor < end_debug) {
1692     const dwarf2_comp_unit_stream_t* comp_unit_stream;
1693     dwarf2_comp_unit_t comp_unit;
1694     dwarf2_parse_context_t ctx;
1695     dwarf2_parse_context_t abbrev_ctx;
1696     struct symt_compiland* compiland = NULL;
1697     
1698     comp_unit_stream = (const dwarf2_comp_unit_stream_t*) comp_unit_cursor;
1699
1700     comp_unit.length = *(unsigned long*)  comp_unit_stream->length;
1701     comp_unit.version = *(unsigned short*) comp_unit_stream->version;
1702     comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset;
1703     comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size;
1704
1705     TRACE("Compilation Unit Herder found at 0x%x:\n", comp_unit_cursor - debug);
1706     TRACE("- length:        %lu\n", comp_unit.length);
1707     TRACE("- version:       %u\n",  comp_unit.version);
1708     TRACE("- abbrev_offset: %lu\n", comp_unit.abbrev_offset);
1709     TRACE("- word_size:     %u\n",  comp_unit.word_size);
1710
1711     pool_init(&ctx.pool, 65536);
1712     ctx.data_stream = debug;
1713     ctx.data = ctx.start_data = comp_unit_cursor + sizeof(dwarf2_comp_unit_stream_t);
1714     ctx.offset = comp_unit_cursor - debug;
1715     ctx.word_size = comp_unit.word_size;
1716     ctx.str_section = str;
1717
1718     comp_unit_cursor += comp_unit.length + sizeof(unsigned);
1719     ctx.end_data = comp_unit_cursor;
1720
1721     if (2 != comp_unit.version) {
1722       WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", comp_unit.version);
1723       continue ;
1724     }
1725
1726     abbrev_ctx.data_stream = abbrev;
1727     abbrev_ctx.data = abbrev_ctx.start_data = abbrev + comp_unit.abbrev_offset;
1728     abbrev_ctx.end_data = abbrev + abbrev_size;
1729     abbrev_ctx.offset = comp_unit.abbrev_offset;
1730     abbrev_ctx.str_section = str;
1731     dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
1732
1733     while (ctx.data < ctx.end_data) {
1734       const dwarf2_abbrev_entry_t* entry = NULL;
1735       unsigned long entry_code;
1736       unsigned long entry_ref = 0;
1737
1738       entry_ref = ctx.data - ctx.data_stream;
1739       
1740       entry_code = dwarf2_leb128_as_unsigned(&ctx);
1741       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1742       if (0 == entry_code) {
1743         continue ;
1744       }
1745       entry = dwarf2_abbrev_table_find_entry(&ctx.abbrev_table, entry_code);
1746       if (NULL == entry) {
1747         WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, entry_ref);
1748         pool_destroy(&ctx.pool);
1749         return FALSE;
1750       }
1751
1752       switch (entry->tag) {
1753       case DW_TAG_compile_unit:
1754         {
1755           struct symt_compiland* symt = dwarf2_parse_compiland(module, entry, &ctx);
1756           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1757           compiland = symt;
1758         }
1759         break;
1760       default:
1761         {
1762           dwarf2_abbrev_entry_attr_t* attr;
1763           WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(&ctx), entry->entry_code); 
1764           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1765             dwarf2_parse_attr(attr, &ctx);
1766           }
1767         }
1768         break;
1769       }
1770     }
1771     pool_destroy(&ctx.pool);
1772   }
1773   
1774   module->module.SymType = SymDia;
1775   return TRUE;
1776 }