rpcrt4: Use rpcrt4_conn_read in RPCRT4_OpenBinding.
[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  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <sys/types.h>
24 #include <fcntl.h>
25 #ifdef HAVE_SYS_STAT_H
26 # include <sys/stat.h>
27 #endif
28 #ifdef HAVE_SYS_MMAN_H
29 #include <sys/mman.h>
30 #endif
31 #include <limits.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #ifdef HAVE_UNISTD_H
35 # include <unistd.h>
36 #endif
37 #include <stdio.h>
38 #ifndef PATH_MAX
39 #define PATH_MAX MAX_PATH
40 #endif
41 #include <assert.h>
42 #include <stdarg.h>
43
44 #include "windef.h"
45 #include "winbase.h"
46 #include "winreg.h"
47 #include "winnls.h"
48
49 #include "dbghelp_private.h"
50
51 #include "wine/debug.h"
52
53 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_dwarf);
54
55 #if 0
56 static void dump(const void* ptr, unsigned len)
57 {
58   int         i, j;
59   BYTE        msg[128];
60   static const char hexof[] = "0123456789abcdef";
61   const BYTE* x = (const BYTE*)ptr;
62
63   for (i = 0; i < len; i += 16)
64   {
65     sprintf(msg, "%08x: ", i);
66     memset(msg + 10, ' ', 3 * 16 + 1 + 16);
67     for (j = 0; j < min(16, len - i); j++)
68     {
69       msg[10 + 3 * j + 0] = hexof[x[i + j] >> 4];
70       msg[10 + 3 * j + 1] = hexof[x[i + j] & 15];
71       msg[10 + 3 * j + 2] = ' ';
72       msg[10 + 3 * 16 + 1 + j] = (x[i + j] >= 0x20 && x[i + j] < 0x7f) ?
73         x[i + j] : '.';
74     }
75     msg[10 + 3 * 16] = ' ';
76     msg[10 + 3 * 16 + 1 + 16] = '\0';
77     TRACE("%s\n", msg);
78   }
79 }
80 #endif
81
82 /**
83  *
84  * Main Specs:
85  *  http://www.eagercon.com/dwarf/dwarf3std.htm
86  *  http://www.eagercon.com/dwarf/dwarf-2.0.0.pdf
87  *
88  * dwarf2.h: http://www.hakpetzna.com/b/binutils/dwarf2_8h-source.html
89  *
90  * example of projects who do dwarf2 parsing:
91  *  http://www.x86-64.org/cgi-bin/cvsweb.cgi/binutils.dead/binutils/readelf.c?rev=1.1.1.2
92  *  http://elis.ugent.be/diota/log/ltrace_elf.c
93  */
94
95 typedef struct {
96   unsigned char length[4];
97   unsigned char version[2];
98   unsigned char abbrev_offset[4];
99   unsigned char word_size[1];
100 } dwarf2_comp_unit_stream_t;
101
102 typedef struct {
103   unsigned long  length;
104   unsigned short version;
105   unsigned long  abbrev_offset;
106   unsigned char  word_size;
107 } dwarf2_comp_unit_t;
108
109 typedef struct {
110   unsigned int   length;
111   unsigned short version;
112   unsigned int   prologue_length;
113   unsigned char  min_insn_length;
114   unsigned char  default_is_stmt;
115   int            line_base;
116   unsigned char  line_range;
117   unsigned char  opcode_base;
118 } dwarf2_line_info_t;
119
120 typedef enum dwarf_tag_e {
121   DW_TAG_padding                = 0x00,
122   DW_TAG_array_type             = 0x01,
123   DW_TAG_class_type             = 0x02,
124   DW_TAG_entry_point            = 0x03,
125   DW_TAG_enumeration_type       = 0x04,
126   DW_TAG_formal_parameter       = 0x05,
127   DW_TAG_imported_declaration   = 0x08,
128   DW_TAG_label                  = 0x0a,
129   DW_TAG_lexical_block          = 0x0b,
130   DW_TAG_member                 = 0x0d,
131   DW_TAG_pointer_type           = 0x0f,
132   DW_TAG_reference_type         = 0x10,
133   DW_TAG_compile_unit           = 0x11,
134   DW_TAG_string_type            = 0x12,
135   DW_TAG_structure_type         = 0x13,
136   DW_TAG_subroutine_type        = 0x15,
137   DW_TAG_typedef                = 0x16,
138   DW_TAG_union_type             = 0x17,
139   DW_TAG_unspecified_parameters = 0x18,
140   DW_TAG_variant                = 0x19,
141   DW_TAG_common_block           = 0x1a,
142   DW_TAG_common_inclusion       = 0x1b,
143   DW_TAG_inheritance            = 0x1c,
144   DW_TAG_inlined_subroutine     = 0x1d,
145   DW_TAG_module                 = 0x1e,
146   DW_TAG_ptr_to_member_type     = 0x1f,
147   DW_TAG_set_type               = 0x20,
148   DW_TAG_subrange_type          = 0x21,
149   DW_TAG_with_stmt              = 0x22,
150   DW_TAG_access_declaration     = 0x23,
151   DW_TAG_base_type              = 0x24,
152   DW_TAG_catch_block            = 0x25,
153   DW_TAG_const_type             = 0x26,
154   DW_TAG_constant               = 0x27,
155   DW_TAG_enumerator             = 0x28,
156   DW_TAG_file_type              = 0x29,
157   DW_TAG_friend                 = 0x2a,
158   DW_TAG_namelist               = 0x2b,
159   DW_TAG_namelist_item          = 0x2c,
160   DW_TAG_packed_type            = 0x2d,
161   DW_TAG_subprogram             = 0x2e,
162   DW_TAG_template_type_param    = 0x2f,
163   DW_TAG_template_value_param   = 0x30,
164   DW_TAG_thrown_type            = 0x31,
165   DW_TAG_try_block              = 0x32,
166   DW_TAG_variant_part           = 0x33,
167   DW_TAG_variable               = 0x34,
168   DW_TAG_volatile_type          = 0x35,
169   /** extensions */
170   DW_TAG_MIPS_loop              = 0x4081,
171   DW_TAG_format_label           = 0x4101,
172   DW_TAG_function_template      = 0x4102,
173   DW_TAG_class_template         = 0x4103
174 } dwarf_tag_t;
175
176 typedef enum dwarf_attribute_e {
177   DW_AT_sibling              = 0x01,
178   DW_AT_location             = 0x02,
179   DW_AT_name                 = 0x03,
180   DW_AT_ordering             = 0x09,
181   DW_AT_subscr_data          = 0x0a,
182   DW_AT_byte_size            = 0x0b,
183   DW_AT_bit_offset           = 0x0c,
184   DW_AT_bit_size             = 0x0d,
185   DW_AT_element_list         = 0x0f,
186   DW_AT_stmt_list            = 0x10,
187   DW_AT_low_pc               = 0x11,
188   DW_AT_high_pc              = 0x12,
189   DW_AT_language             = 0x13,
190   DW_AT_member               = 0x14,
191   DW_AT_discr                = 0x15,
192   DW_AT_discr_value          = 0x16,
193   DW_AT_visibility           = 0x17,
194   DW_AT_import               = 0x18,
195   DW_AT_string_length        = 0x19,
196   DW_AT_common_reference     = 0x1a,
197   DW_AT_comp_dir             = 0x1b,
198   DW_AT_const_value          = 0x1c,
199   DW_AT_containing_type      = 0x1d,
200   DW_AT_default_value        = 0x1e,
201   DW_AT_inline               = 0x20,
202   DW_AT_is_optional          = 0x21,
203   DW_AT_lower_bound          = 0x22,
204   DW_AT_producer             = 0x25,
205   DW_AT_prototyped           = 0x27,
206   DW_AT_return_addr          = 0x2a,
207   DW_AT_start_scope          = 0x2c,
208   DW_AT_stride_size          = 0x2e,
209   DW_AT_upper_bound          = 0x2f,
210   DW_AT_abstract_origin      = 0x31,
211   DW_AT_accessibility        = 0x32,
212   DW_AT_address_class        = 0x33,
213   DW_AT_artificial           = 0x34,
214   DW_AT_base_types           = 0x35,
215   DW_AT_calling_convention   = 0x36,
216   DW_AT_count                = 0x37,
217   DW_AT_data_member_location = 0x38,
218   DW_AT_decl_column          = 0x39,
219   DW_AT_decl_file            = 0x3a,
220   DW_AT_decl_line            = 0x3b,
221   DW_AT_declaration          = 0x3c,
222   DW_AT_discr_list           = 0x3d,
223   DW_AT_encoding             = 0x3e,
224   DW_AT_external             = 0x3f,
225   DW_AT_frame_base           = 0x40,
226   DW_AT_friend               = 0x41,
227   DW_AT_identifier_case      = 0x42,
228   DW_AT_macro_info           = 0x43,
229   DW_AT_namelist_items       = 0x44,
230   DW_AT_priority             = 0x45,
231   DW_AT_segment              = 0x46,
232   DW_AT_specification        = 0x47,
233   DW_AT_static_link          = 0x48,
234   DW_AT_type                 = 0x49,
235   DW_AT_use_location         = 0x4a,
236   DW_AT_variable_parameter   = 0x4b,
237   DW_AT_virtuality           = 0x4c,
238   DW_AT_vtable_elem_location = 0x4d,
239
240   DW_AT_ranges               = 0x55,
241   /* extensions */
242   DW_AT_MIPS_fde                     = 0x2001,
243   DW_AT_MIPS_loop_begin              = 0x2002,
244   DW_AT_MIPS_tail_loop_begin         = 0x2003,
245   DW_AT_MIPS_epilog_begin            = 0x2004,
246   DW_AT_MIPS_loop_unroll_factor      = 0x2005,
247   DW_AT_MIPS_software_pipeline_depth = 0x2006,
248   DW_AT_MIPS_linkage_name            = 0x2007,
249   DW_AT_MIPS_stride                  = 0x2008,
250   DW_AT_MIPS_abstract_name           = 0x2009,
251   DW_AT_MIPS_clone_origin            = 0x200a,
252   DW_AT_MIPS_has_inlines             = 0x200b,
253   DW_AT_sf_names                     = 0x2101,
254   DW_AT_src_info                     = 0x2102,
255   DW_AT_mac_info                     = 0x2103,
256   DW_AT_src_coords                   = 0x2104,
257   DW_AT_body_begin                   = 0x2105,
258   DW_AT_body_end                     = 0x2106
259 } dwarf_attribute_t;
260
261 typedef enum dwarf_form_e {
262   DW_FORM_addr      = 0x01,
263   DW_FORM_block2    = 0x03,
264   DW_FORM_block4    = 0x04,
265   DW_FORM_data2     = 0x05,
266   DW_FORM_data4     = 0x06,
267   DW_FORM_data8     = 0x07,
268   DW_FORM_string    = 0x08,
269   DW_FORM_block     = 0x09,
270   DW_FORM_block1    = 0x0a,
271   DW_FORM_data1     = 0x0b,
272   DW_FORM_flag      = 0x0c,
273   DW_FORM_sdata     = 0x0d,
274   DW_FORM_strp      = 0x0e,
275   DW_FORM_udata     = 0x0f,
276   DW_FORM_ref_addr  = 0x10,
277   DW_FORM_ref1      = 0x11,
278   DW_FORM_ref2      = 0x12,
279   DW_FORM_ref4      = 0x13,
280   DW_FORM_ref8      = 0x14,
281   DW_FORM_ref_udata = 0x15,
282   DW_FORM_indirect  = 0x16
283 } dwarf_form_t;
284
285 /** type encoding */
286 typedef enum dwarf_type_e {
287   DW_ATE_void          = 0x0,
288   DW_ATE_address       = 0x1,
289   DW_ATE_boolean       = 0x2,
290   DW_ATE_complex_float = 0x3,
291   DW_ATE_float         = 0x4,
292   DW_ATE_signed        = 0x5,
293   DW_ATE_signed_char   = 0x6,
294   DW_ATE_unsigned      = 0x7,
295   DW_ATE_unsigned_char = 0x8
296 } dwarf_type_t;
297
298 typedef enum dwarf_operation_e {
299   DW_OP_addr = 0x03,
300   DW_OP_deref = 0x06,
301   DW_OP_const1u = 0x08,
302   DW_OP_const1s = 0x09,
303   DW_OP_const2u = 0x0a,
304   DW_OP_const2s = 0x0b,
305   DW_OP_const4u = 0x0c,
306   DW_OP_const4s = 0x0d,
307   DW_OP_const8u = 0x0e,
308   DW_OP_const8s = 0x0f,
309   DW_OP_constu = 0x10,
310   DW_OP_consts = 0x11,
311   DW_OP_dup = 0x12,
312   DW_OP_drop = 0x13,
313   DW_OP_over = 0x14,
314   DW_OP_pick = 0x15,
315   DW_OP_swap = 0x16,
316   DW_OP_rot = 0x17,
317   DW_OP_xderef = 0x18,
318   DW_OP_abs = 0x19,
319   DW_OP_and = 0x1a,
320   DW_OP_div = 0x1b,
321   DW_OP_minus = 0x1c,
322   DW_OP_mod = 0x1d,
323   DW_OP_mul = 0x1e,
324   DW_OP_neg = 0x1f,
325   DW_OP_not = 0x20,
326   DW_OP_or = 0x21,
327   DW_OP_plus = 0x22,
328   DW_OP_plus_uconst = 0x23,
329   DW_OP_shl = 0x24,
330   DW_OP_shr = 0x25,
331   DW_OP_shra = 0x26,
332   DW_OP_xor = 0x27,
333   DW_OP_bra = 0x28,
334   DW_OP_eq = 0x29,
335   DW_OP_ge = 0x2a,
336   DW_OP_gt = 0x2b,
337   DW_OP_le = 0x2c,
338   DW_OP_lt = 0x2d,
339   DW_OP_ne = 0x2e,
340   DW_OP_skip = 0x2f,
341   DW_OP_lit0 = 0x30,
342   DW_OP_lit1 = 0x31,
343   DW_OP_lit2 = 0x32,
344   DW_OP_lit3 = 0x33,
345   DW_OP_lit4 = 0x34,
346   DW_OP_lit5 = 0x35,
347   DW_OP_lit6 = 0x36,
348   DW_OP_lit7 = 0x37,
349   DW_OP_lit8 = 0x38,
350   DW_OP_lit9 = 0x39,
351   DW_OP_lit10 = 0x3a,
352   DW_OP_lit11 = 0x3b,
353   DW_OP_lit12 = 0x3c,
354   DW_OP_lit13 = 0x3d,
355   DW_OP_lit14 = 0x3e,
356   DW_OP_lit15 = 0x3f,
357   DW_OP_lit16 = 0x40,
358   DW_OP_lit17 = 0x41,
359   DW_OP_lit18 = 0x42,
360   DW_OP_lit19 = 0x43,
361   DW_OP_lit20 = 0x44,
362   DW_OP_lit21 = 0x45,
363   DW_OP_lit22 = 0x46,
364   DW_OP_lit23 = 0x47,
365   DW_OP_lit24 = 0x48,
366   DW_OP_lit25 = 0x49,
367   DW_OP_lit26 = 0x4a,
368   DW_OP_lit27 = 0x4b,
369   DW_OP_lit28 = 0x4c,
370   DW_OP_lit29 = 0x4d,
371   DW_OP_lit30 = 0x4e,
372   DW_OP_lit31 = 0x4f,
373   DW_OP_reg0 = 0x50,
374   DW_OP_reg1 = 0x51,
375   DW_OP_reg2 = 0x52,
376   DW_OP_reg3 = 0x53,
377   DW_OP_reg4 = 0x54,
378   DW_OP_reg5 = 0x55,
379   DW_OP_reg6 = 0x56,
380   DW_OP_reg7 = 0x57,
381   DW_OP_reg8 = 0x58,
382   DW_OP_reg9 = 0x59,
383   DW_OP_reg10 = 0x5a,
384   DW_OP_reg11 = 0x5b,
385   DW_OP_reg12 = 0x5c,
386   DW_OP_reg13 = 0x5d,
387   DW_OP_reg14 = 0x5e,
388   DW_OP_reg15 = 0x5f,
389   DW_OP_reg16 = 0x60,
390   DW_OP_reg17 = 0x61,
391   DW_OP_reg18 = 0x62,
392   DW_OP_reg19 = 0x63,
393   DW_OP_reg20 = 0x64,
394   DW_OP_reg21 = 0x65,
395   DW_OP_reg22 = 0x66,
396   DW_OP_reg23 = 0x67,
397   DW_OP_reg24 = 0x68,
398   DW_OP_reg25 = 0x69,
399   DW_OP_reg26 = 0x6a,
400   DW_OP_reg27 = 0x6b,
401   DW_OP_reg28 = 0x6c,
402   DW_OP_reg29 = 0x6d,
403   DW_OP_reg30 = 0x6e,
404   DW_OP_reg31 = 0x6f,
405   DW_OP_breg0 = 0x70,
406   DW_OP_breg1 = 0x71,
407   DW_OP_breg2 = 0x72,
408   DW_OP_breg3 = 0x73,
409   DW_OP_breg4 = 0x74,
410   DW_OP_breg5 = 0x75,
411   DW_OP_breg6 = 0x76,
412   DW_OP_breg7 = 0x77,
413   DW_OP_breg8 = 0x78,
414   DW_OP_breg9 = 0x79,
415   DW_OP_breg10 = 0x7a,
416   DW_OP_breg11 = 0x7b,
417   DW_OP_breg12 = 0x7c,
418   DW_OP_breg13 = 0x7d,
419   DW_OP_breg14 = 0x7e,
420   DW_OP_breg15 = 0x7f,
421   DW_OP_breg16 = 0x80,
422   DW_OP_breg17 = 0x81,
423   DW_OP_breg18 = 0x82,
424   DW_OP_breg19 = 0x83,
425   DW_OP_breg20 = 0x84,
426   DW_OP_breg21 = 0x85,
427   DW_OP_breg22 = 0x86,
428   DW_OP_breg23 = 0x87,
429   DW_OP_breg24 = 0x88,
430   DW_OP_breg25 = 0x89,
431   DW_OP_breg26 = 0x8a,
432   DW_OP_breg27 = 0x8b,
433   DW_OP_breg28 = 0x8c,
434   DW_OP_breg29 = 0x8d,
435   DW_OP_breg30 = 0x8e,
436   DW_OP_breg31 = 0x8f,
437   DW_OP_regx = 0x90,
438   DW_OP_fbreg = 0x91,
439   DW_OP_bregx = 0x92,
440   DW_OP_piece = 0x93,
441   DW_OP_deref_size = 0x94,
442   DW_OP_xderef_size = 0x95,
443   DW_OP_nop = 0x96
444 } dwarf_operation_t;
445
446 enum dwarf_calling_convention
447 {
448     DW_CC_normal = 0x1,
449     DW_CC_program = 0x2,
450     DW_CC_nocall = 0x3
451 };
452
453 #define DW_CC_lo_user 0x40
454 #define DW_CC_hi_user 0xff
455
456
457 /**
458  * Parsers
459  */
460
461 typedef struct dwarf2_abbrev_entry_attr_s {
462   unsigned long attribute;
463   unsigned long form;
464   struct dwarf2_abbrev_entry_attr_s* next;
465 } dwarf2_abbrev_entry_attr_t;
466
467 typedef struct dwarf2_abbrev_entry_s {
468   unsigned long entry_code;
469   unsigned long tag;
470   unsigned char have_child;
471   dwarf2_abbrev_entry_attr_t* attrs;
472   struct dwarf2_abbrev_entry_s* next;
473 } dwarf2_abbrev_entry_t;
474
475 typedef struct dwarf2_abbrev_table_s {
476   dwarf2_abbrev_entry_t* first;
477   unsigned n_entries;
478 } dwarf2_abbrev_table_t;
479
480 typedef struct dwarf2_parse_context_s {
481   dwarf2_abbrev_table_t* abbrev_table;
482   const unsigned char* data_stream;
483   const unsigned char* data;
484   const unsigned char* start_data;
485   const unsigned char* end_data;
486   const unsigned char* str_section;
487   unsigned long offset;
488   unsigned char word_size;
489   unsigned char level;
490 } dwarf2_parse_context_t;
491
492 static unsigned char dwarf2_parse_byte(dwarf2_parse_context_t* ctx)
493 {
494   unsigned char uvalue = *(const unsigned char*) ctx->data;
495   ctx->data += 1;
496   return uvalue;
497 }
498
499 static unsigned short dwarf2_parse_u2(dwarf2_parse_context_t* ctx)
500 {
501   unsigned short uvalue = *(const unsigned short*) ctx->data;
502   ctx->data += 2;
503   return uvalue;
504 }
505
506 static unsigned long dwarf2_parse_u4(dwarf2_parse_context_t* ctx)
507 {
508   unsigned long uvalue = *(const unsigned int*) ctx->data;
509   ctx->data += 4;
510   return uvalue;
511 }
512
513 static unsigned long dwarf2_leb128_as_unsigned(dwarf2_parse_context_t* ctx)
514 {
515   unsigned long ret = 0;
516   unsigned char byte;
517   unsigned shift = 0;
518
519   assert( NULL != ctx );
520
521   while (1) {
522     byte = dwarf2_parse_byte(ctx);
523     ret |= (byte & 0x7f) << shift;
524     shift += 7;
525     if (0 == (byte & 0x80)) { break ; }
526   }
527
528   return ret;
529 }
530
531 static long dwarf2_leb128_as_signed(dwarf2_parse_context_t* ctx)
532 {
533   long ret = 0;
534   unsigned char byte;
535   unsigned shift = 0;
536   const unsigned size = sizeof(int) * 8;
537
538   assert( NULL != ctx );
539
540   while (1) {
541     byte = dwarf2_parse_byte(ctx);
542     ret |= (byte & 0x7f) << shift;
543     shift += 7;
544     if (0 == (byte & 0x80)) { break ; }
545   }
546   /* as spec: sign bit of byte is 2nd high order bit (80x40)
547    *  -> 0x80 is used as flag.
548    */
549   if ((shift < size) && (byte & 0x40)) {
550     ret |= - (1 << shift);
551   }
552   return ret;
553 }
554
555 static const char* dwarf2_debug_ctx(dwarf2_parse_context_t* ctx) 
556 {
557   /*return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->start_data, ctx->level); */
558   return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->data_stream, ctx->level); 
559 }
560 static const char* dwarf2_debug_attr(dwarf2_abbrev_entry_attr_t* attr) 
561 {
562   return wine_dbg_sprintf("attr(attr:0x%lx,form:0x%lx)", attr->attribute, attr->form);
563 }
564
565 static void dwarf2_check_sibling(dwarf2_parse_context_t* ctx, unsigned long next_sibling)
566
567   if (0 < next_sibling && ctx->data != ctx->data_stream + next_sibling) {
568     if ((ctx->data + 1) != ctx->data_stream + next_sibling) {
569       /** padding check */
570       WARN("cursor error for %s should be sibling<0x%lx>\n", dwarf2_debug_ctx(ctx), next_sibling);
571     }
572     ctx->data = ctx->data_stream + next_sibling;
573   }
574 }
575
576
577 static dwarf2_abbrev_entry_attr_t* dwarf2_abbrev_entry_add_attr(dwarf2_abbrev_entry_t* abbrev_entry, unsigned long attribute, unsigned long form)
578 {
579   dwarf2_abbrev_entry_attr_t* ret = NULL;
580   dwarf2_abbrev_entry_attr_t* it = NULL;
581
582   assert( NULL != abbrev_entry );
583   ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_entry_attr_t));
584   assert( NULL != ret );
585
586   ret->attribute = attribute;
587   ret->form      = form;
588
589   ret->next = NULL;
590   if (NULL == abbrev_entry->attrs) {
591     abbrev_entry->attrs = ret;
592   } else {
593     for (it = abbrev_entry->attrs; NULL != it->next; it = it->next) ;
594     it->next = ret;
595   }
596   return ret;
597 }
598
599 static dwarf2_abbrev_entry_t* dwarf2_abbrev_table_add_entry(dwarf2_abbrev_table_t* abbrev_table, unsigned long entry_code, unsigned long tag, unsigned char have_child)
600 {
601   dwarf2_abbrev_entry_t* ret = NULL;
602
603   assert( NULL != abbrev_table );
604   ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_entry_t));
605   assert( NULL != ret );
606
607   TRACE("(table:%p,n_entries:%u) entry_code(%lu) tag(0x%lx) have_child(%u) -> %p\n", abbrev_table, abbrev_table->n_entries, entry_code, tag, have_child, ret);
608
609   ret->entry_code = entry_code;
610   ret->tag        = tag;
611   ret->have_child = have_child;
612   ret->attrs      = NULL;
613
614   ret->next       = abbrev_table->first;
615   abbrev_table->first = ret;
616   abbrev_table->n_entries++;
617   return ret;
618 }
619
620 static dwarf2_abbrev_entry_t* dwarf2_abbrev_table_find_entry(dwarf2_abbrev_table_t* abbrev_table, unsigned long entry_code)
621 {
622   dwarf2_abbrev_entry_t* ret = NULL;
623
624   assert( NULL != abbrev_table );
625   for (ret = abbrev_table->first; ret; ret = ret->next) {
626     if (ret->entry_code == entry_code) { break ; }
627   }
628   return ret;
629 }
630
631 static void dwarf2_abbrev_table_free(dwarf2_abbrev_table_t* abbrev_table)
632 {
633   dwarf2_abbrev_entry_t* entry = NULL;
634   dwarf2_abbrev_entry_t* next_entry = NULL;
635   assert( NULL != abbrev_table );
636   for (entry = abbrev_table->first; NULL != entry; entry = next_entry) {
637     dwarf2_abbrev_entry_attr_t* attr = NULL;
638     dwarf2_abbrev_entry_attr_t* next_attr = NULL;
639     for (attr = entry->attrs; NULL != attr; attr = next_attr) {
640       next_attr = attr->next;
641       HeapFree(GetProcessHeap(), 0, attr);
642     }
643     next_entry = entry->next;
644     HeapFree(GetProcessHeap(), 0, entry);
645   }
646   abbrev_table->first = NULL;
647   abbrev_table->n_entries = 0;
648 }
649
650 static dwarf2_abbrev_table_t* dwarf2_parse_abbrev_set(dwarf2_parse_context_t* abbrev_ctx)
651 {
652   dwarf2_abbrev_table_t* abbrev_table = NULL;
653
654   TRACE("%s, end at %p\n", dwarf2_debug_ctx(abbrev_ctx), abbrev_ctx->end_data); 
655
656   assert( NULL != abbrev_ctx );
657   abbrev_table = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_table_t));
658   assert( NULL != abbrev_table );
659
660   while (abbrev_ctx->data < abbrev_ctx->end_data) {
661     unsigned long entry_code;
662     unsigned long tag;
663     unsigned char have_child;
664     dwarf2_abbrev_entry_t* abbrev_entry;
665
666     TRACE("now at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
667     entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx);
668     TRACE("found entry_code %lu\n", entry_code);
669     if (0 == entry_code) {
670       TRACE("NULL entry code at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
671       break ;
672     }
673     tag = dwarf2_leb128_as_unsigned(abbrev_ctx);
674     have_child = dwarf2_parse_byte(abbrev_ctx);
675
676     abbrev_entry = dwarf2_abbrev_table_add_entry(abbrev_table, entry_code, tag, have_child);
677     assert( NULL != abbrev_entry );
678     while (1) {
679       unsigned long attribute;
680       unsigned long form;
681       attribute = dwarf2_leb128_as_unsigned(abbrev_ctx);
682       form = dwarf2_leb128_as_unsigned(abbrev_ctx);
683       if (0 == attribute) break;
684       dwarf2_abbrev_entry_add_attr(abbrev_entry, attribute, form);
685     }
686   }
687
688   TRACE("found %u entries\n", abbrev_table->n_entries);
689   return abbrev_table;
690 }
691
692 static const char* dwarf2_parse_attr_as_string(dwarf2_abbrev_entry_attr_t* attr,
693                                                dwarf2_parse_context_t* ctx)
694 {
695   const char* ret = NULL;
696   switch (attr->form) {
697   case DW_FORM_string:
698     ret = (const char*) ctx->data;
699     ctx->data += strlen(ret) + 1;
700     break;
701   case DW_FORM_strp:
702     {
703       unsigned long offset = dwarf2_parse_u4(ctx);
704       ret = (const char*) ctx->str_section + offset;
705       /*FIXME("Unsupported indirect string format offset 0x%lx (in .debug_str)\n", offset);*/
706     }
707     break;
708   default:
709     ERR("Unsupported string format 0x%lx for attr 0x%lx\n", attr->form, attr->attribute);
710   }
711   return ret;
712 }
713
714 static unsigned long dwarf2_parse_attr_as_addr(dwarf2_abbrev_entry_attr_t* attr,
715                                                dwarf2_parse_context_t* ctx)
716 {
717   unsigned long offset = 0;
718   switch (ctx->word_size) {
719   case 4:
720     offset = *(const unsigned int*) ctx->data;
721     break;
722   case 8:
723   default:
724     FIXME("Unsupported Word Size %u\n", ctx->word_size);
725   }
726   ctx->data += ctx->word_size;
727   return offset;  
728 }
729
730 static unsigned long dwarf2_parse_attr_as_ref(dwarf2_abbrev_entry_attr_t* attr,
731                                               dwarf2_parse_context_t* ctx)
732 {
733   unsigned long uvalue = 0;
734   switch (attr->form) {
735   case DW_FORM_ref1:
736     uvalue = ctx->offset + dwarf2_parse_byte(ctx);
737     TRACE("ref1<0x%lx>\n", uvalue);
738     break;
739
740   case DW_FORM_ref2:
741     uvalue = ctx->offset + dwarf2_parse_u2(ctx);
742     TRACE("ref2<0x%lx>\n", uvalue);
743     break;
744
745   case DW_FORM_ref4:
746     uvalue = ctx->offset + dwarf2_parse_u4(ctx);
747     TRACE("ref4<0x%lx>\n", uvalue);
748     break;
749
750   case DW_FORM_ref8:
751     /* FIXME: 64bits support */
752     /*
753     uvalue = ctx->offset + dwarf2_parse_u8(ctx);
754     TRACE("ref8<0x%lx>\n", uvalue);
755     */
756     ctx->data += 8;
757     break;
758   }
759   return uvalue;
760 }
761
762
763 static unsigned long dwarf2_parse_attr_as_data(dwarf2_abbrev_entry_attr_t* attr,
764                                                dwarf2_parse_context_t* ctx)
765 {
766   unsigned long uvalue = 0;
767   switch (attr->form) {
768   case DW_FORM_data1:
769     uvalue = dwarf2_parse_byte(ctx);
770     TRACE("data1<%lu>\n", uvalue);
771     break;
772
773   case DW_FORM_data2:
774     uvalue = dwarf2_parse_u2(ctx);
775     TRACE("data2<%lu>\n", uvalue);
776     break;
777
778   case DW_FORM_data4:
779     uvalue = dwarf2_parse_u4(ctx);
780     TRACE("data4<%lu>\n", uvalue);
781     break;
782
783   case DW_FORM_data8:
784     FIXME("Unsupported 64bits support\n");
785     ctx->data += 8;
786     break;
787   }
788   return uvalue;
789 }
790
791 static void dwarf2_parse_attr(dwarf2_abbrev_entry_attr_t* attr,
792                               dwarf2_parse_context_t* ctx)
793 {
794   const unsigned long attribute = attr->attribute;
795   const unsigned long form = attr->form;
796   unsigned long uvalue = 0;
797   long svalue = 0;
798   const char* str = NULL;
799
800   TRACE("(attr:0x%lx,form:0x%lx)\n", attribute, form);
801
802   switch (form) {
803   case DW_FORM_ref_addr:
804   case DW_FORM_addr:
805     uvalue = dwarf2_parse_attr_as_addr(attr, ctx);
806     break;
807
808   case DW_FORM_flag:
809     uvalue = dwarf2_parse_byte(ctx);
810     TRACE("flag<0x%lx>\n", uvalue);
811     break;
812
813   case DW_FORM_data1:
814     uvalue = dwarf2_parse_byte(ctx);
815     TRACE("data1<%lu>\n", uvalue);
816     break;
817
818   case DW_FORM_data2:
819     uvalue = dwarf2_parse_u2(ctx);
820     TRACE("data2<%lu>\n", uvalue);
821     break;
822
823   case DW_FORM_data4:
824     uvalue = dwarf2_parse_u4(ctx);
825     TRACE("data4<%lu>\n", uvalue);
826     break;
827
828   case DW_FORM_ref1:
829   case DW_FORM_ref2:
830   case DW_FORM_ref4:
831   case DW_FORM_ref8:
832     uvalue = dwarf2_parse_attr_as_ref(attr, ctx);
833     /*TRACE("ref<0x%lx>\n", ctx->offset + uvalue);*/
834     break;
835
836   case DW_FORM_data8:
837     FIXME("Unsupported 64bits support\n");
838     ctx->data += 8;
839     break;
840
841   case DW_FORM_sdata:
842     svalue = dwarf2_leb128_as_signed(ctx);
843     break;
844
845   case DW_FORM_ref_udata:
846   case DW_FORM_udata:
847     uvalue = dwarf2_leb128_as_unsigned(ctx);
848     break;
849
850   case DW_FORM_string:
851   case DW_FORM_strp:
852     str = dwarf2_parse_attr_as_string(attr, ctx);
853     TRACE("string<%s>\n", str);
854     break;
855
856   case DW_FORM_block:
857     uvalue = dwarf2_leb128_as_unsigned(ctx);
858     ctx->data += uvalue;
859     break;
860
861   case DW_FORM_block1:
862     uvalue = dwarf2_parse_byte(ctx);
863     ctx->data += uvalue;
864     break;
865
866   case DW_FORM_block2:
867     uvalue = dwarf2_parse_u2(ctx);
868     ctx->data += uvalue;
869     break;
870
871   case DW_FORM_block4:
872     uvalue = dwarf2_parse_u4(ctx);
873     ctx->data += uvalue;
874     break;
875
876   default:
877     break;
878   }
879 }
880
881 static struct symt* dwarf2_find_symt_by_ref(struct module* module, unsigned long ref)
882 {
883   TRACE("want ref<0x%lx>\n", ref); 
884   return NULL;
885 }
886
887 static struct symt* dwarf2_add_symt_ref(struct module* module, unsigned long ref, struct symt* symt)
888 {
889   if (NULL != symt) return NULL;
890   return NULL;
891 }
892
893 static struct symt_basic* dwarf2_parse_base_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
894 {
895   struct symt_basic* symt = NULL;
896   const char* name = NULL;
897   unsigned size = 0;
898   unsigned encoding = 0;
899   enum BasicType bt;
900   dwarf2_abbrev_entry_attr_t* attr = NULL;
901
902   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
903
904   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
905     switch (attr->attribute) {
906     case DW_AT_name:
907       name = dwarf2_parse_attr_as_string(attr, ctx);
908       TRACE("found name %s\n", name);
909       break;
910     case DW_AT_byte_size:
911       size = dwarf2_parse_byte(ctx);
912       break;
913     case DW_AT_encoding:
914       encoding = dwarf2_parse_byte(ctx);
915       break;
916     default:
917       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
918       dwarf2_parse_attr(attr, ctx);
919     }
920   }
921   switch (encoding) {
922   case DW_ATE_void: bt = btVoid; break;
923   case DW_ATE_address: bt = btULong; break;
924   case DW_ATE_boolean: bt = btBool; break;
925   case DW_ATE_complex_float: bt = btComplex; break;
926   case DW_ATE_float: bt = btFloat; break;
927   case DW_ATE_signed: bt = btInt; break;
928   case DW_ATE_unsigned: bt = btUInt; break;
929   case DW_ATE_signed_char: bt = btChar; break;
930   case DW_ATE_unsigned_char: bt = btChar; break;
931   default:
932     bt = btNoType;
933   }
934   /*TRACE("symt_new_basic(%p, %u, %s, %u)", module, bt, name, size);*/
935   symt = symt_new_basic(module, bt, name, size);
936
937   if (entry->have_child) {
938     FIXME("Unsupported children\n");
939   }
940   return symt;
941 }
942
943 static struct symt_typedef* dwarf2_parse_typedef(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
944 {
945   struct symt_typedef* symt = NULL;
946   struct symt* ref_type = NULL;
947   const char* name = NULL;
948   dwarf2_abbrev_entry_attr_t* attr = NULL;
949
950   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
951
952   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
953     switch (attr->attribute) {
954     case DW_AT_name:
955       name = dwarf2_parse_attr_as_string(attr, ctx);
956       TRACE("found name %s\n", name);
957       break;
958     case DW_AT_type:
959       {
960         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
961         ref_type = dwarf2_find_symt_by_ref(module, ref);
962       }
963       break;
964     case DW_AT_decl_file:
965     case DW_AT_decl_line:
966       dwarf2_parse_attr(attr, ctx);
967       break;
968     default:
969       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
970       dwarf2_parse_attr(attr, ctx);
971     }
972   }
973   if (NULL != name) {
974     symt = symt_new_typedef(module, ref_type, name);
975   }
976
977   if (entry->have_child) {
978     FIXME("Unsupported children\n");
979   }
980   return symt;
981 }
982
983 static struct symt_pointer* dwarf2_parse_pointer_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
984 {
985   struct symt_pointer* symt = NULL;
986   struct symt* ref_type = NULL;
987   unsigned size = 0;
988   dwarf2_abbrev_entry_attr_t* attr = NULL;
989
990   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
991
992   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
993     switch (attr->attribute) {
994     case DW_AT_byte_size:
995       size = dwarf2_parse_byte(ctx);
996       break;
997     case DW_AT_type:
998       {
999         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1000         ref_type = dwarf2_find_symt_by_ref(module, ref);
1001       }
1002       break;
1003     default:
1004       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1005       dwarf2_parse_attr(attr, ctx);
1006     }
1007   }
1008   symt = symt_new_pointer(module, ref_type);
1009
1010   if (entry->have_child) {
1011     FIXME("Unsupported children\n");
1012   }
1013   return symt;
1014 }
1015
1016 static void dwarf2_parse_array_subrange_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_array* parent)
1017 {
1018   unsigned min = 0;
1019   unsigned max = 0;
1020   struct symt* idx_type = NULL;
1021   dwarf2_abbrev_entry_attr_t* attr = NULL;
1022
1023   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1024
1025   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1026     switch (attr->attribute) {
1027     case DW_AT_type:
1028       {
1029         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1030         idx_type = dwarf2_find_symt_by_ref(module, ref);
1031         /** check if idx_type is a basic_type integer */
1032       }
1033       break;
1034     case DW_AT_lower_bound:
1035       TRACE("%s %s, lower_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1036       min = dwarf2_parse_attr_as_data(attr, ctx);
1037       break;
1038     case DW_AT_upper_bound:
1039       TRACE("%s %s, upper_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1040       max = dwarf2_parse_attr_as_data(attr, ctx);
1041       break;
1042     case DW_AT_count:
1043       TRACE("%s %s, count min:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), min); 
1044       max = min + dwarf2_parse_attr_as_data(attr, ctx);
1045       break;
1046     default:
1047       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1048       dwarf2_parse_attr(attr, ctx);
1049     }
1050   }
1051   parent->start = min;
1052   parent->end = max;
1053   parent->index_type = idx_type;
1054
1055   TRACE("found min:%u max:%u\n", min, max);   
1056
1057   if (entry->have_child) {
1058     FIXME("Unsupported children\n");
1059   }
1060 }
1061
1062
1063 static struct symt_array* dwarf2_parse_array_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1064 {
1065   struct symt_array* symt = NULL;
1066   struct symt* ref_type = NULL;
1067   unsigned min = 0;
1068   unsigned max = 0;
1069   dwarf2_abbrev_entry_attr_t* attr = NULL;
1070   unsigned long next_sibling = 0;
1071
1072   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1073
1074   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1075     switch (attr->attribute) {
1076     case DW_AT_sibling:
1077       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1078       break;
1079     case DW_AT_type:
1080       {
1081         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1082         ref_type = dwarf2_find_symt_by_ref(module, ref);
1083       }
1084       break;
1085     default:
1086       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1087       dwarf2_parse_attr(attr, ctx);
1088     }
1089   }
1090
1091   /* FIXME: ugly as hell */
1092   symt = symt_new_array(module, min, max, ref_type, NULL);
1093
1094   if (entry->have_child) { /** any interest to not have child ? */
1095     ++ctx->level;
1096     while (ctx->data < ctx->end_data) {
1097       dwarf2_abbrev_entry_t* entry = NULL;
1098       unsigned long entry_code;
1099       unsigned long entry_ref = 0;
1100
1101       entry_ref = ctx->data - ctx->data_stream;
1102       
1103       entry_code = dwarf2_leb128_as_unsigned(ctx);
1104       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1105       if (0 == entry_code) {
1106         break ;
1107       }
1108
1109       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1110       assert( NULL != entry );
1111
1112       switch (entry->tag) {
1113       case DW_TAG_subrange_type:
1114         dwarf2_parse_array_subrange_type(module, entry, ctx, symt);
1115         break;
1116       default:
1117         {
1118           dwarf2_abbrev_entry_attr_t* attr;
1119           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1120           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1121             dwarf2_parse_attr(attr, ctx);
1122           }
1123         }
1124         break;
1125       }
1126     }
1127     --ctx->level;
1128   }
1129
1130   /** set correct data cursor */
1131   dwarf2_check_sibling(ctx, next_sibling);
1132
1133   return symt;
1134 }
1135
1136 static struct symt_typedef* dwarf2_parse_const_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1137 {
1138   struct symt_typedef* symt = NULL;
1139   struct symt* ref_type = NULL;
1140   dwarf2_abbrev_entry_attr_t* attr = NULL;
1141   unsigned long next_sibling = 0;
1142
1143   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1144
1145   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1146     switch (attr->attribute) {
1147     case DW_AT_type:
1148       {
1149         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1150         ref_type = dwarf2_find_symt_by_ref(module, ref);
1151       }
1152       break;
1153     default:
1154       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1155       dwarf2_parse_attr(attr, ctx);
1156     }
1157   }
1158   FIXME("need to generate a name\n");
1159   symt = symt_new_typedef(module, ref_type, "");
1160
1161   if (entry->have_child) {
1162     FIXME("Unsupported children\n");
1163   }
1164
1165   /** set correct data cursor */
1166   dwarf2_check_sibling(ctx, next_sibling);
1167
1168   return symt;
1169 }
1170
1171 static struct symt_typedef* dwarf2_parse_reference_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1172 {
1173   struct symt_typedef* symt = NULL;
1174   struct symt* ref_type = NULL;
1175   dwarf2_abbrev_entry_attr_t* attr = NULL;
1176   unsigned long next_sibling = 0;
1177
1178   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1179
1180   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1181     switch (attr->attribute) {
1182     case DW_AT_sibling:
1183       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1184       break;
1185     case DW_AT_type:
1186       {
1187         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1188         ref_type = dwarf2_find_symt_by_ref(module, ref);
1189       }
1190       break;
1191     default:
1192       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1193       dwarf2_parse_attr(attr, ctx);
1194     }
1195   }
1196   FIXME("need to generate a name\n");
1197   symt = symt_new_typedef(module, ref_type, "");
1198
1199   if (entry->have_child) {
1200     FIXME("Unsupported children\n");
1201   }
1202
1203   /** set correct data cursor */
1204   dwarf2_check_sibling(ctx, next_sibling);
1205
1206   return symt;
1207 }
1208
1209 static void dwarf2_parse_udt_member(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* parent)
1210 {
1211   struct symt* elt_type = NULL;
1212   const char* name = NULL; 
1213   unsigned long offset = 0;
1214   unsigned size = 0;
1215   dwarf2_abbrev_entry_attr_t* attr = NULL;
1216   unsigned long next_sibling = 0;
1217
1218   assert( NULL != parent );
1219
1220   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1221
1222   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1223     switch (attr->attribute) {
1224     case DW_AT_sibling:
1225       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1226       break;
1227     case DW_AT_name:
1228       name = dwarf2_parse_attr_as_string(attr, ctx);
1229       TRACE("found name %s\n", name);
1230       break;
1231     case DW_AT_type:
1232       {
1233         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1234         elt_type = dwarf2_find_symt_by_ref(module, ref);
1235       }
1236       break;
1237     case DW_AT_data_member_location:
1238       {
1239         unsigned long uvalue = 0;
1240         TRACE("found member_location at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1241         /*offset = dwarf2_parse_attr_as_data(attr, ctx);*/
1242         switch (attr->form) {
1243         case DW_FORM_block:
1244           uvalue = dwarf2_leb128_as_unsigned(ctx);
1245           break;
1246         case DW_FORM_block1:
1247           uvalue = dwarf2_parse_byte(ctx);
1248           break;
1249         case DW_FORM_block2:
1250           uvalue = dwarf2_parse_u2(ctx);
1251           break;
1252         case DW_FORM_block4:
1253           uvalue = dwarf2_parse_u4(ctx);
1254           break;
1255         default:
1256           TRACE("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1257           dwarf2_parse_attr(attr, ctx);
1258         }
1259         if (uvalue) {
1260           unsigned char op = dwarf2_parse_byte(ctx);
1261           --uvalue;
1262           switch (op) {
1263           case DW_OP_plus_uconst:
1264             offset = dwarf2_leb128_as_unsigned(ctx);
1265             break;
1266           default:
1267             TRACE("Unhandled attr op at %s, for %s, op:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), op);
1268             ctx->data += uvalue;
1269           }
1270           TRACE("found offset:%lu\n", offset);            
1271         }
1272       }
1273       break;
1274     case DW_AT_decl_file:
1275     case DW_AT_decl_line:
1276       dwarf2_parse_attr(attr, ctx);
1277       break;
1278     default:
1279       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1280       dwarf2_parse_attr(attr, ctx);
1281     }
1282   }
1283   symt_add_udt_element(module, parent, name, elt_type, offset, size);
1284
1285   if (entry->have_child) {
1286     FIXME("Unsupported children\n");
1287   }
1288
1289   /** set correct data cursor */
1290   dwarf2_check_sibling(ctx, next_sibling);
1291 }
1292
1293 static void dwarf2_parse_udt_members(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* symt)
1294 {
1295   if (entry->have_child) { /** any interest to not have child ? */
1296     ++ctx->level;
1297     while (ctx->data < ctx->end_data) {
1298       dwarf2_abbrev_entry_t* entry = NULL;
1299       unsigned long entry_code;
1300       unsigned long entry_ref = 0;
1301
1302       entry_ref = ctx->data - ctx->data_stream;
1303       
1304       entry_code = dwarf2_leb128_as_unsigned(ctx);
1305       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1306       if (0 == entry_code) {
1307         break ;
1308       }
1309
1310       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1311       assert( NULL != entry );
1312
1313       switch (entry->tag) {
1314       case DW_TAG_member:
1315         dwarf2_parse_udt_member(module, entry, ctx, symt);
1316         break;
1317       default:
1318         {
1319           dwarf2_abbrev_entry_attr_t* attr;
1320           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1321           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1322             dwarf2_parse_attr(attr, ctx);
1323           }
1324         }
1325         break;
1326       }
1327     }
1328     --ctx->level;
1329   }
1330 }
1331
1332 static struct symt_udt* dwarf2_parse_class_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1333 {
1334   struct symt_udt* symt = NULL;
1335   const char* name = NULL;
1336   unsigned size = 0;
1337   dwarf2_abbrev_entry_attr_t* attr = NULL;
1338   unsigned long next_sibling = 0;
1339
1340   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1341
1342   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1343     switch (attr->attribute) {
1344     case DW_AT_sibling:
1345       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1346       break;
1347     case DW_AT_name:
1348       name = dwarf2_parse_attr_as_string(attr, ctx);
1349       TRACE("found name %s\n", name);
1350       break;
1351     case DW_AT_byte_size:
1352       size = dwarf2_parse_byte(ctx);
1353       break;
1354     case DW_AT_decl_file:
1355     case DW_AT_decl_line:
1356       dwarf2_parse_attr(attr, ctx);
1357       break;
1358     default:
1359       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1360       dwarf2_parse_attr(attr, ctx);
1361     }
1362   }
1363   symt = symt_new_udt(module, name, size, UdtClass);
1364   dwarf2_parse_udt_members(module, entry, ctx, symt);
1365
1366   /** set correct data cursor */
1367   dwarf2_check_sibling(ctx, next_sibling);
1368
1369   return symt;
1370 }
1371
1372 static struct symt_udt* dwarf2_parse_struct_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1373 {
1374   struct symt_udt* symt = NULL;
1375   const char* name = NULL;
1376   unsigned size = 0;
1377   dwarf2_abbrev_entry_attr_t* attr = NULL;
1378   unsigned long next_sibling = 0;
1379
1380   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1381
1382   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1383     switch (attr->attribute) {
1384     case DW_AT_sibling:
1385       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1386       break;
1387     case DW_AT_name:
1388       name = dwarf2_parse_attr_as_string(attr, ctx);
1389       TRACE("found name %s\n", name);
1390       break;
1391     case DW_AT_byte_size:
1392       size = dwarf2_parse_byte(ctx);
1393       break;
1394     case DW_AT_decl_file:
1395     case DW_AT_decl_line:
1396       dwarf2_parse_attr(attr, ctx);
1397       break;
1398     default:
1399       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1400       dwarf2_parse_attr(attr, ctx);
1401     }
1402   }
1403   symt = symt_new_udt(module, name, size, UdtStruct);
1404   dwarf2_parse_udt_members(module, entry, ctx, symt);
1405
1406   /** set correct data cursor */
1407   dwarf2_check_sibling(ctx, next_sibling);
1408
1409   return symt;
1410 }
1411
1412 static struct symt_udt* dwarf2_parse_union_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1413 {
1414   struct symt_udt* symt = NULL;
1415   const char* name = NULL;
1416   unsigned size = 0;
1417   dwarf2_abbrev_entry_attr_t* attr = NULL;
1418   unsigned long next_sibling = 0;
1419
1420   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1421
1422   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1423     switch (attr->attribute) {
1424     case DW_AT_sibling:
1425       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1426       break;
1427     case DW_AT_name:
1428       name = dwarf2_parse_attr_as_string(attr, ctx);
1429       TRACE("found name %s\n", name);
1430       break;
1431     case DW_AT_byte_size:
1432       size = dwarf2_parse_byte(ctx);
1433       break;
1434     case DW_AT_decl_file:
1435     case DW_AT_decl_line:
1436       dwarf2_parse_attr(attr, ctx);
1437       break;
1438     default:
1439       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1440       dwarf2_parse_attr(attr, ctx);
1441     }
1442   }
1443   symt = symt_new_udt(module, name, size, UdtUnion);
1444   dwarf2_parse_udt_members(module, entry, ctx, symt);
1445
1446   /** set correct data cursor */
1447   dwarf2_check_sibling(ctx, next_sibling);
1448
1449   return symt;
1450 }
1451
1452 static void dwarf2_parse_enumerator(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_enum* parent)
1453 {
1454   const char* name = NULL;
1455   long value = 0;
1456   dwarf2_abbrev_entry_attr_t* attr = NULL;
1457
1458   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1459
1460   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1461     switch (attr->attribute) {
1462     case DW_AT_name:
1463       name = dwarf2_parse_attr_as_string(attr, ctx);
1464       TRACE("found name %s\n", name);
1465       break;
1466     case DW_AT_const_value:
1467       switch (attr->form) {
1468       case DW_FORM_sdata:
1469         value = dwarf2_leb128_as_signed(ctx);
1470         TRACE("found value %ld\n", value);
1471         break;
1472       case DW_FORM_udata:
1473         value = dwarf2_leb128_as_unsigned(ctx);
1474         TRACE("found value %ld\n", value);
1475         break;
1476       default:
1477         TRACE("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1478         dwarf2_parse_attr(attr, ctx);
1479       }
1480       break;
1481     default:
1482       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1483       dwarf2_parse_attr(attr, ctx);
1484     }
1485   }
1486   symt_add_enum_element(module, parent, name, value);
1487
1488   if (entry->have_child) {
1489     FIXME("Unsupported children\n");
1490   }
1491 }
1492
1493 static struct symt_enum* dwarf2_parse_enumeration_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1494 {
1495   struct symt_enum* symt = NULL;
1496   const char* name = NULL;
1497   unsigned long size = 0;
1498   dwarf2_abbrev_entry_attr_t* attr = NULL;
1499   unsigned long next_sibling = 0;
1500
1501   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1502
1503   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1504     switch (attr->attribute) {
1505     case DW_AT_sibling:
1506       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1507       break;
1508     case DW_AT_name:
1509       name = dwarf2_parse_attr_as_string(attr, ctx);
1510       TRACE("found name %s\n", name);
1511       break;
1512     case DW_AT_byte_size:
1513       size = dwarf2_parse_attr_as_data(attr, ctx);
1514       break;
1515     case DW_AT_decl_file:
1516     case DW_AT_decl_line:
1517       dwarf2_parse_attr(attr, ctx);
1518       break;
1519     default:
1520       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1521       dwarf2_parse_attr(attr, ctx);
1522     }
1523   }
1524   symt = symt_new_enum(module, name);
1525
1526   if (entry->have_child) { /** any interest to not have child ? */
1527     ++ctx->level;
1528     while (ctx->data < ctx->end_data) {
1529       dwarf2_abbrev_entry_t* entry = NULL;
1530       unsigned long entry_code;
1531       unsigned long entry_ref = 0;
1532
1533       entry_ref = ctx->data - ctx->data_stream;
1534       
1535       entry_code = dwarf2_leb128_as_unsigned(ctx);
1536       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1537       if (0 == entry_code) {
1538         break ;
1539       }
1540
1541       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1542       assert( NULL != entry );
1543
1544       switch (entry->tag) {
1545       case DW_TAG_enumerator:
1546         dwarf2_parse_enumerator(module, entry, ctx, symt);
1547         break;
1548       default:
1549         {
1550           dwarf2_abbrev_entry_attr_t* attr;
1551           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1552           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1553             dwarf2_parse_attr(attr, ctx);
1554           }
1555         }
1556         break;
1557       }
1558     }
1559     --ctx->level;
1560   }
1561
1562   /** set correct data cursor */
1563   dwarf2_check_sibling(ctx, next_sibling);
1564
1565   return symt;
1566 }
1567
1568 static void dwarf2_parse_variable(struct module* module, 
1569                                   dwarf2_abbrev_entry_t* entry, 
1570                                   dwarf2_parse_context_t* ctx) 
1571 {
1572   struct symt* var_type = NULL;
1573   dwarf2_abbrev_entry_attr_t* attr = NULL;
1574   const char* name = NULL;
1575   unsigned long next_sibling = 0;
1576
1577   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1578
1579   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1580     switch (attr->attribute) {
1581     case DW_AT_sibling:
1582       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1583       break;
1584     case DW_AT_type:
1585       {
1586         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1587         var_type = dwarf2_find_symt_by_ref(module, ref);
1588       }
1589       break;
1590     case DW_AT_name:
1591       name = dwarf2_parse_attr_as_string(attr, ctx);
1592       TRACE("found name %s\n", name);
1593       break;
1594     case DW_AT_decl_file:
1595     case DW_AT_decl_line:
1596       dwarf2_parse_attr(attr, ctx);
1597       break;
1598     default:
1599       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1600       dwarf2_parse_attr(attr, ctx);
1601     }
1602   }
1603
1604   if (entry->have_child) {
1605     FIXME("Unsupported children\n");
1606   }
1607
1608   /** set correct data cursor */
1609   dwarf2_check_sibling(ctx, next_sibling);  
1610 }
1611
1612 static void dwarf2_parse_subprogram_parameter(struct module* module, 
1613                                               dwarf2_abbrev_entry_t* entry, 
1614                                               dwarf2_parse_context_t* ctx, 
1615                                               struct symt_function_signature* sig_type,
1616                                               struct symt_function* func_type)
1617 {
1618   struct symt* param_type = NULL;
1619   const char* name = NULL;
1620   dwarf2_abbrev_entry_attr_t* attr = NULL;
1621   unsigned long next_sibling = 0;
1622
1623   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1624
1625   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1626     switch (attr->attribute) {
1627     case DW_AT_sibling:
1628       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1629       break;
1630     case DW_AT_type:
1631       {
1632         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1633         param_type = dwarf2_find_symt_by_ref(module, ref);
1634       }
1635       break;
1636     case DW_AT_name:
1637       name = dwarf2_parse_attr_as_string(attr, ctx);
1638       TRACE("found name %s\n", name);
1639       break;
1640     case DW_AT_decl_file:
1641     case DW_AT_decl_line:
1642       dwarf2_parse_attr(attr, ctx);
1643       break;
1644     case DW_AT_location:
1645       dwarf2_parse_attr(attr, ctx);
1646       break;
1647     default:
1648       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1649       dwarf2_parse_attr(attr, ctx);
1650     }
1651   }
1652   if (NULL != sig_type) {
1653     symt_add_function_signature_parameter(module, sig_type, param_type);
1654   }
1655
1656   if (entry->have_child) {
1657     FIXME("Unsupported children\n");
1658   }
1659
1660   /** set correct data cursor */
1661   dwarf2_check_sibling(ctx, next_sibling);  
1662 }
1663
1664 static void dwarf2_parse_inlined_subroutine(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1665 {
1666   const char* name = NULL;
1667   unsigned long addr = 0;
1668   unsigned long low_pc = 0;
1669   unsigned long high_pc = 0;
1670   unsigned size = 0;
1671   dwarf2_abbrev_entry_attr_t* attr = NULL;
1672   unsigned long next_sibling = 0;
1673
1674   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1675
1676   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1677     switch (attr->attribute) {
1678     case DW_AT_sibling:
1679       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1680       break;
1681     case DW_AT_low_pc:
1682       low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1683       addr = module->module.BaseOfImage + low_pc;
1684       break;
1685     case DW_AT_high_pc:
1686       high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1687       size = high_pc - low_pc;
1688       break;
1689     case DW_AT_name:
1690       name = dwarf2_parse_attr_as_string(attr, ctx);
1691       TRACE("found name %s\n", name);
1692       break;
1693     case DW_AT_decl_file:
1694     case DW_AT_decl_line:
1695       dwarf2_parse_attr(attr, ctx);
1696       break;
1697     default:
1698       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1699       dwarf2_parse_attr(attr, ctx);
1700     }
1701   }
1702
1703   if (entry->have_child) { /** any interest to not have child ? */
1704     ++ctx->level;
1705     while (ctx->data < ctx->end_data) {
1706       dwarf2_abbrev_entry_t* entry = NULL;
1707       unsigned long entry_code;
1708       unsigned long entry_ref = 0;
1709
1710       entry_ref = ctx->data - ctx->data_stream;
1711       
1712       entry_code = dwarf2_leb128_as_unsigned(ctx);
1713       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1714       if (0 == entry_code) {
1715         break ;
1716       }
1717
1718       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1719       assert( NULL != entry );
1720
1721       switch (entry->tag) {
1722       case DW_TAG_formal_parameter:
1723         dwarf2_parse_subprogram_parameter(module, entry, ctx, NULL, NULL);
1724         break;
1725       case DW_TAG_variable:
1726         dwarf2_parse_variable(module, entry, ctx);
1727         break;
1728       case DW_TAG_label:
1729       default:
1730         {
1731           dwarf2_abbrev_entry_attr_t* attr;
1732           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1733           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1734             dwarf2_parse_attr(attr, ctx);
1735           }
1736         }
1737         break;
1738       }
1739     }
1740     --ctx->level;
1741   }
1742
1743   /** set correct data cursor */
1744   dwarf2_check_sibling(ctx, next_sibling);
1745 }
1746
1747
1748 static void dwarf2_parse_subprogram_block(struct module* module, 
1749                                           dwarf2_abbrev_entry_t* entry, 
1750                                           dwarf2_parse_context_t* ctx, 
1751                                           struct symt_function_signature* sig_type,
1752                                           struct symt_function* func_type)
1753 {
1754   dwarf2_abbrev_entry_attr_t* attr = NULL;
1755   const char* name = NULL;
1756   unsigned long next_sibling = 0;
1757
1758   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1759
1760   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1761     switch (attr->attribute) {
1762     case DW_AT_sibling:
1763       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1764       break;
1765     case DW_AT_name:
1766       name = dwarf2_parse_attr_as_string(attr, ctx);
1767       TRACE("found name %s\n", name);
1768       break;
1769     case DW_AT_decl_file:
1770     case DW_AT_decl_line:
1771       dwarf2_parse_attr(attr, ctx);
1772       break;
1773     case DW_AT_ranges: /** what to do ? */
1774       dwarf2_parse_attr(attr, ctx);
1775       break;
1776     default:
1777       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1778       dwarf2_parse_attr(attr, ctx);
1779     }
1780   }
1781   
1782   if (entry->have_child) { /** any interest to not have child ? */
1783     ++ctx->level;
1784     while (ctx->data < ctx->end_data) {
1785       dwarf2_abbrev_entry_t* entry = NULL;
1786       unsigned long entry_code;
1787       unsigned long entry_ref = 0;
1788
1789       entry_ref = ctx->data - ctx->data_stream;
1790       
1791       entry_code = dwarf2_leb128_as_unsigned(ctx);
1792       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1793       if (0 == entry_code) {
1794         break ;
1795       }
1796
1797       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1798       assert( NULL != entry );
1799
1800       switch (entry->tag) {
1801       case DW_TAG_inlined_subroutine:
1802         dwarf2_parse_inlined_subroutine(module, entry, ctx);
1803         break;
1804       case DW_TAG_variable:
1805         dwarf2_parse_variable(module, entry, ctx);
1806         break;
1807       case DW_TAG_label:
1808       default:
1809         {
1810           dwarf2_abbrev_entry_attr_t* attr;
1811           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1812           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1813             dwarf2_parse_attr(attr, ctx);
1814           }
1815         }
1816         break;
1817       }
1818     }
1819     --ctx->level;
1820   }
1821
1822   /** set correct data cursor */
1823   dwarf2_check_sibling(ctx, next_sibling);
1824 }
1825
1826 static void dwarf2_parse_subprogram_content(struct module* module, 
1827                                             dwarf2_abbrev_entry_t* entry, 
1828                                             dwarf2_parse_context_t* ctx, 
1829                                             struct symt_function_signature* sig_type,
1830                                             struct symt_function* func_type)
1831 {
1832   if (entry->have_child) { /** any interest to not have child ? */
1833     ++ctx->level;
1834     while (ctx->data < ctx->end_data) {
1835       dwarf2_abbrev_entry_t* entry = NULL;
1836       unsigned long entry_code;
1837       unsigned long entry_ref = 0;
1838
1839       entry_ref = ctx->data - ctx->data_stream;
1840       
1841       entry_code = dwarf2_leb128_as_unsigned(ctx);
1842       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1843       if (0 == entry_code) {
1844         break ;
1845       }
1846
1847       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1848       assert( NULL != entry );
1849
1850       switch (entry->tag) {
1851       case DW_TAG_formal_parameter:
1852         dwarf2_parse_subprogram_parameter(module, entry, ctx, sig_type, func_type);
1853         break;
1854       case DW_TAG_lexical_block:
1855         dwarf2_parse_subprogram_block(module, entry, ctx, sig_type, func_type);
1856         break;
1857       case DW_TAG_variable:
1858         dwarf2_parse_variable(module, entry, ctx);
1859         break;
1860       case DW_TAG_label:
1861       default:
1862         {
1863           dwarf2_abbrev_entry_attr_t* attr;
1864           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1865           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1866             dwarf2_parse_attr(attr, ctx);
1867           }
1868         }
1869         break;
1870       }
1871     }
1872     --ctx->level;
1873   }
1874 }
1875
1876 static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1877 {
1878   struct symt_function* func_type = NULL;
1879   const char* name = NULL;
1880   struct symt* ret_type = NULL;
1881   struct symt_function_signature* sig_type = NULL;
1882   unsigned long addr = 0;
1883   unsigned long low_pc = 0;
1884   unsigned long high_pc = 0;
1885   unsigned size = 0;
1886   unsigned char is_decl = 0;
1887   unsigned char inl_flags = 0;
1888   unsigned char decl_file = 0;
1889   unsigned char decl_line = 0;
1890   dwarf2_abbrev_entry_attr_t* attr = NULL;
1891   unsigned long next_sibling = 0;
1892   enum CV_call_e call_conv = CV_CALL_FAR_C; /* FIXME: assuming C source code */
1893   unsigned cc;
1894
1895   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1896
1897   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1898     switch (attr->attribute) {
1899     case DW_AT_sibling:
1900       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1901       break;
1902     case DW_AT_low_pc:
1903       low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1904       addr = module->module.BaseOfImage + low_pc;
1905       break;
1906     case DW_AT_high_pc:
1907       high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1908       size = high_pc - low_pc;
1909       break;
1910     case DW_AT_name:
1911       name = dwarf2_parse_attr_as_string(attr, ctx);
1912       TRACE("found name %s\n", name);
1913       break;
1914     case DW_AT_type:
1915       {
1916         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1917         ret_type = dwarf2_find_symt_by_ref(module, ref);
1918       }
1919       break;
1920     case DW_AT_declaration:
1921       is_decl = dwarf2_parse_byte(ctx);
1922       break;
1923     case DW_AT_inline:
1924       inl_flags = dwarf2_parse_byte(ctx);
1925       break;
1926     case DW_AT_calling_convention:
1927         switch (cc = dwarf2_parse_byte(ctx))
1928         {
1929         case DW_CC_normal: break;
1930         case DW_CC_nocall: call_conv = -1;
1931         default: FIXME("Unsupported calling convention %d\n", cc);
1932         }
1933         break;
1934     /* not work yet, need parsing .debug_line and using Compil Unit stmt_list
1935     case DW_AT_decl_file:
1936       decl_file =  dwarf2_parse_byte(ctx);
1937       break;
1938     case DW_AT_decl_line:
1939       decl_line =  dwarf2_parse_byte(ctx);
1940       break;
1941     */
1942     default:
1943       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1944       dwarf2_parse_attr(attr, ctx);
1945     }
1946   }
1947   sig_type = symt_new_function_signature(module, ret_type, call_conv);
1948   if (!is_decl) {
1949     func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt);
1950     if (low_pc && high_pc) {
1951       symt_add_function_point(module, func_type, SymTagFuncDebugStart, low_pc, NULL);
1952       symt_add_function_point(module, func_type, SymTagFuncDebugEnd, high_pc, NULL);
1953     }
1954     if (decl_file && decl_line) {
1955       symt_add_func_line(module, func_type, decl_file, decl_line, low_pc);
1956     }
1957   }
1958   dwarf2_parse_subprogram_content(module, entry, ctx, sig_type, func_type);
1959   symt_normalize_function(module, func_type);
1960
1961   /** set correct data cursor */
1962   dwarf2_check_sibling(ctx, next_sibling);
1963
1964   return func_type;
1965 }
1966
1967 static void dwarf2_parse_compiland_content(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1968 {
1969   if (entry->have_child) { /** any interest to not have child ? */
1970     ++ctx->level;
1971     while (ctx->data < ctx->end_data) {
1972       dwarf2_abbrev_entry_t* entry = NULL;
1973       unsigned long entry_code;
1974       unsigned long entry_ref = 0;
1975
1976       entry_ref = ctx->data - ctx->data_stream;
1977       
1978       entry_code = dwarf2_leb128_as_unsigned(ctx);
1979       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1980       if (0 == entry_code) {
1981         break ;
1982       }
1983
1984       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1985       assert( NULL != entry );
1986
1987       switch (entry->tag) {
1988       case DW_TAG_typedef:
1989         {
1990           struct symt_typedef* symt = dwarf2_parse_typedef(module, entry, ctx);
1991           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1992         }
1993         break;
1994       case DW_TAG_base_type:
1995         {
1996           struct symt_basic* symt = dwarf2_parse_base_type(module, entry, ctx);
1997           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1998         }
1999         break;
2000       case DW_TAG_pointer_type:
2001         {
2002           struct symt_pointer* symt = dwarf2_parse_pointer_type(module, entry, ctx);
2003           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2004         }
2005         break;
2006       case DW_TAG_class_type:
2007         {
2008           struct symt_udt* symt = dwarf2_parse_class_type(module, entry, ctx);
2009           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2010         }
2011         break;
2012       case DW_TAG_structure_type:
2013         {
2014           struct symt_udt* symt = dwarf2_parse_struct_type(module, entry, ctx);
2015           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2016         }
2017         break;
2018       case DW_TAG_union_type:
2019         {
2020           struct symt_udt* symt = dwarf2_parse_union_type(module, entry, ctx);
2021           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2022         }
2023         break;
2024       case DW_TAG_array_type:
2025         {
2026           struct symt_array* symt = dwarf2_parse_array_type(module, entry, ctx);
2027           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2028         }
2029         break;
2030       case DW_TAG_const_type:
2031         {
2032           struct symt_typedef* symt = dwarf2_parse_const_type(module, entry, ctx);
2033           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2034         }
2035         break;
2036       case DW_TAG_reference_type:
2037         {
2038           struct symt_typedef* symt = dwarf2_parse_reference_type(module, entry, ctx);
2039           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2040         }
2041         break;
2042       case DW_TAG_enumeration_type:
2043         {
2044           struct symt_enum* symt = dwarf2_parse_enumeration_type(module, entry, ctx);
2045           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2046         }
2047         break;
2048       case DW_TAG_subprogram:
2049         {
2050           struct symt_function* symt = dwarf2_parse_subprogram(module, entry, ctx, compiland);
2051           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2052         }
2053         break;
2054
2055       default:
2056         {
2057           dwarf2_abbrev_entry_attr_t* attr;
2058           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
2059           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
2060             dwarf2_parse_attr(attr, ctx);
2061           }
2062         }
2063         break;
2064       }
2065     }
2066     --ctx->level;
2067   }
2068 }
2069
2070 static struct symt_compiland* dwarf2_parse_compiland(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
2071 {
2072   struct symt_compiland* compiland = NULL;
2073   const char* name = NULL;
2074   unsigned long next_sibling = 0;
2075   dwarf2_abbrev_entry_attr_t* attr = NULL;
2076
2077   TRACE("beginning at Ox%x, for %lu\n", ctx->data - ctx->start_data, entry->entry_code); 
2078
2079   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
2080     switch (attr->attribute) {
2081     case DW_AT_sibling:
2082       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
2083       break;
2084     case DW_AT_name:
2085       name = dwarf2_parse_attr_as_string(attr, ctx);
2086       TRACE("found name %s\n", name);
2087       break;
2088     default:
2089       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
2090       dwarf2_parse_attr(attr, ctx);
2091     }
2092   }
2093   compiland = symt_new_compiland(module, name);
2094   dwarf2_parse_compiland_content(module, entry, ctx, compiland);
2095
2096   dwarf2_check_sibling(ctx, next_sibling);
2097
2098   return compiland;
2099 }
2100
2101 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
2102                   const unsigned char* debug, unsigned int debug_size,
2103                   const unsigned char* abbrev, unsigned int abbrev_size,
2104                   const unsigned char* str, unsigned int str_sz)
2105 {
2106   const unsigned char* comp_unit_cursor = debug;
2107   const unsigned char* end_debug = debug + debug_size;
2108   BOOL bRet = TRUE;
2109
2110   while (comp_unit_cursor < end_debug) {
2111     dwarf2_abbrev_table_t* abbrev_table;
2112     const dwarf2_comp_unit_stream_t* comp_unit_stream;
2113     dwarf2_comp_unit_t comp_unit;
2114     dwarf2_parse_context_t ctx;
2115     dwarf2_parse_context_t abbrev_ctx;
2116     struct symt_compiland* compiland = NULL;
2117     
2118     comp_unit_stream = (const dwarf2_comp_unit_stream_t*) comp_unit_cursor;
2119
2120     comp_unit.length = *(unsigned long*)  comp_unit_stream->length;
2121     comp_unit.version = *(unsigned short*) comp_unit_stream->version;
2122     comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset;
2123     comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size;
2124
2125     TRACE("Compilation Unit Herder found at 0x%x:\n", comp_unit_cursor - debug);
2126     TRACE("- length:        %lu\n", comp_unit.length);
2127     TRACE("- version:       %u\n",  comp_unit.version);
2128     TRACE("- abbrev_offset: %lu\n", comp_unit.abbrev_offset);
2129     TRACE("- word_size:     %u\n",  comp_unit.word_size);
2130
2131     ctx.data_stream = debug;
2132     ctx.data = ctx.start_data = comp_unit_cursor + sizeof(dwarf2_comp_unit_stream_t);
2133     ctx.offset = comp_unit_cursor - debug;
2134     ctx.word_size = comp_unit.word_size;
2135     ctx.str_section = str;
2136     ctx.level = 0;
2137
2138     comp_unit_cursor += comp_unit.length + sizeof(unsigned);
2139     ctx.end_data = comp_unit_cursor;
2140
2141     if (2 != comp_unit.version) {
2142       WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", comp_unit.version);
2143       continue ;
2144     }
2145
2146     abbrev_ctx.abbrev_table = NULL;
2147     abbrev_ctx.data_stream = abbrev;
2148     abbrev_ctx.data = abbrev_ctx.start_data = abbrev + comp_unit.abbrev_offset;
2149     abbrev_ctx.end_data = abbrev + abbrev_size;
2150     abbrev_ctx.offset = comp_unit.abbrev_offset;
2151     abbrev_ctx.str_section = str;
2152     abbrev_table = dwarf2_parse_abbrev_set(&abbrev_ctx);    
2153
2154     ctx.abbrev_table = abbrev_table;
2155
2156     while (ctx.data < ctx.end_data) {
2157       const dwarf2_abbrev_entry_t* entry = NULL;
2158       unsigned long entry_code;
2159       unsigned long entry_ref = 0;
2160
2161       entry_ref = ctx.data - ctx.data_stream;
2162       
2163       entry_code = dwarf2_leb128_as_unsigned(&ctx);
2164       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
2165       if (0 == entry_code) {
2166         continue ;
2167       }
2168       entry = dwarf2_abbrev_table_find_entry(abbrev_table, entry_code);
2169       if (NULL == entry) {
2170         WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, entry_ref);
2171         dwarf2_abbrev_table_free(abbrev_table);
2172         return FALSE;
2173       }
2174
2175       switch (entry->tag) {
2176       case DW_TAG_compile_unit:
2177         {
2178           struct symt_compiland* symt = dwarf2_parse_compiland(module, entry, &ctx);
2179           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2180           compiland = symt;
2181         }
2182         break;
2183       default:
2184         {
2185           dwarf2_abbrev_entry_attr_t* attr;
2186           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(&ctx), entry->entry_code); 
2187           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
2188             dwarf2_parse_attr(attr, &ctx);
2189           }
2190         }
2191         break;
2192       }
2193     }
2194     dwarf2_abbrev_table_free(abbrev_table);
2195   }
2196   return bRet;
2197 }