Fix gcc 4.0 warnings.
[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 /**
447  * Parsers
448  */
449
450 typedef struct dwarf2_abbrev_entry_attr_s {
451   unsigned long attribute;
452   unsigned long form;
453   struct dwarf2_abbrev_entry_attr_s* next;
454 } dwarf2_abbrev_entry_attr_t;
455
456 typedef struct dwarf2_abbrev_entry_s {
457   unsigned long entry_code;
458   unsigned long tag;
459   unsigned char have_child;
460   dwarf2_abbrev_entry_attr_t* attrs;
461   struct dwarf2_abbrev_entry_s* next;
462 } dwarf2_abbrev_entry_t;
463
464 typedef struct dwarf2_abbrev_table_s {
465   dwarf2_abbrev_entry_t* first;
466   unsigned n_entries;
467 } dwarf2_abbrev_table_t;
468
469 typedef struct dwarf2_parse_context_s {
470   dwarf2_abbrev_table_t* abbrev_table;
471   const unsigned char* data_stream;
472   const unsigned char* data;
473   const unsigned char* start_data;
474   const unsigned char* end_data;
475   const unsigned char* str_section;
476   unsigned long offset;
477   unsigned char word_size;
478   unsigned char level;
479 } dwarf2_parse_context_t;
480
481 static unsigned char dwarf2_parse_byte(dwarf2_parse_context_t* ctx)
482 {
483   unsigned char uvalue = *(const unsigned char*) ctx->data;
484   ctx->data += 1;
485   return uvalue;
486 }
487
488 static unsigned short dwarf2_parse_u2(dwarf2_parse_context_t* ctx)
489 {
490   unsigned short uvalue = *(const unsigned short*) ctx->data;
491   ctx->data += 2;
492   return uvalue;
493 }
494
495 static unsigned long dwarf2_parse_u4(dwarf2_parse_context_t* ctx)
496 {
497   unsigned long uvalue = *(const unsigned int*) ctx->data;
498   ctx->data += 4;
499   return uvalue;
500 }
501
502 static unsigned long dwarf2_leb128_as_unsigned(dwarf2_parse_context_t* ctx)
503 {
504   unsigned long ret = 0;
505   unsigned char byte;
506   unsigned shift = 0;
507
508   assert( NULL != ctx );
509
510   while (1) {
511     byte = dwarf2_parse_byte(ctx);
512     ret |= (byte & 0x7f) << shift;
513     shift += 7;
514     if (0 == (byte & 0x80)) { break ; }
515   }
516
517   return ret;
518 }
519
520 static long dwarf2_leb128_as_signed(dwarf2_parse_context_t* ctx)
521 {
522   long ret = 0;
523   unsigned char byte;
524   unsigned shift = 0;
525   const unsigned size = sizeof(int) * 8;
526
527   assert( NULL != ctx );
528
529   while (1) {
530     byte = dwarf2_parse_byte(ctx);
531     ret |= (byte & 0x7f) << shift;
532     shift += 7;
533     if (0 == (byte & 0x80)) { break ; }
534   }
535   /* as spec: sign bit of byte is 2nd high order bit (80x40)
536    *  -> 0x80 is used as flag.
537    */
538   if ((shift < size) && (byte & 0x40)) {
539     ret |= - (1 << shift);
540   }
541   return ret;
542 }
543
544 static const char* dwarf2_debug_ctx(dwarf2_parse_context_t* ctx) 
545 {
546   /*return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->start_data, ctx->level); */
547   return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->data_stream, ctx->level); 
548 }
549 static const char* dwarf2_debug_attr(dwarf2_abbrev_entry_attr_t* attr) 
550 {
551   return wine_dbg_sprintf("attr(attr:0x%lx,form:0x%lx)", attr->attribute, attr->form);
552 }
553
554 static void dwarf2_check_sibling(dwarf2_parse_context_t* ctx, unsigned long next_sibling)
555
556   if (0 < next_sibling && ctx->data != ctx->data_stream + next_sibling) {
557     if ((ctx->data + 1) != ctx->data_stream + next_sibling) {
558       /** padding check */
559       WARN("cursor error for %s should be sibling<0x%lx>\n", dwarf2_debug_ctx(ctx), next_sibling);
560     }
561     ctx->data = ctx->data_stream + next_sibling;
562   }
563 }
564
565
566 static dwarf2_abbrev_entry_attr_t* dwarf2_abbrev_entry_add_attr(dwarf2_abbrev_entry_t* abbrev_entry, unsigned long attribute, unsigned long form)
567 {
568   dwarf2_abbrev_entry_attr_t* ret = NULL;
569   dwarf2_abbrev_entry_attr_t* it = NULL;
570
571   assert( NULL != abbrev_entry );
572   ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_entry_attr_t));
573   assert( NULL != ret );
574
575   ret->attribute = attribute;
576   ret->form      = form;
577
578   ret->next = NULL;
579   if (NULL == abbrev_entry->attrs) {
580     abbrev_entry->attrs = ret;
581   } else {
582     for (it = abbrev_entry->attrs; NULL != it->next; it = it->next) ;
583     it->next = ret;
584   }
585   return ret;
586 }
587
588 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)
589 {
590   dwarf2_abbrev_entry_t* ret = NULL;
591
592   assert( NULL != abbrev_table );
593   ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_entry_t));
594   assert( NULL != ret );
595
596   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);
597
598   ret->entry_code = entry_code;
599   ret->tag        = tag;
600   ret->have_child = have_child;
601   ret->attrs      = NULL;
602
603   ret->next       = abbrev_table->first;
604   abbrev_table->first = ret;
605   abbrev_table->n_entries++;
606   return ret;
607 }
608
609 static dwarf2_abbrev_entry_t* dwarf2_abbrev_table_find_entry(dwarf2_abbrev_table_t* abbrev_table, unsigned long entry_code)
610 {
611   dwarf2_abbrev_entry_t* ret = NULL;
612
613   assert( NULL != abbrev_table );
614   for (ret = abbrev_table->first; ret; ret = ret->next) {
615     if (ret->entry_code == entry_code) { break ; }
616   }
617   return ret;
618 }
619
620 static void dwarf2_abbrev_table_free(dwarf2_abbrev_table_t* abbrev_table)
621 {
622   dwarf2_abbrev_entry_t* entry = NULL;
623   dwarf2_abbrev_entry_t* next_entry = NULL;
624   assert( NULL != abbrev_table );
625   for (entry = abbrev_table->first; NULL != entry; entry = next_entry) {
626     dwarf2_abbrev_entry_attr_t* attr = NULL;
627     dwarf2_abbrev_entry_attr_t* next_attr = NULL;
628     for (attr = entry->attrs; NULL != attr; attr = next_attr) {
629       next_attr = attr->next;
630       HeapFree(GetProcessHeap(), 0, attr);
631     }
632     next_entry = entry->next;
633     HeapFree(GetProcessHeap(), 0, entry);
634   }
635   abbrev_table->first = NULL;
636   abbrev_table->n_entries = 0;
637 }
638
639 static dwarf2_abbrev_table_t* dwarf2_parse_abbrev_set(dwarf2_parse_context_t* abbrev_ctx)
640 {
641   dwarf2_abbrev_table_t* abbrev_table = NULL;
642
643   TRACE("%s, end at %p\n", dwarf2_debug_ctx(abbrev_ctx), abbrev_ctx->end_data); 
644
645   assert( NULL != abbrev_ctx );
646   abbrev_table = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_table_t));
647   assert( NULL != abbrev_table );
648
649   while (abbrev_ctx->data < abbrev_ctx->end_data) {
650     unsigned long entry_code;
651     unsigned long tag;
652     unsigned char have_child;
653     dwarf2_abbrev_entry_t* abbrev_entry;
654
655     TRACE("now at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
656     entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx);
657     TRACE("found entry_code %lu\n", entry_code);
658     if (0 == entry_code) {
659       TRACE("NULL entry code at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
660       break ;
661     }
662     tag = dwarf2_leb128_as_unsigned(abbrev_ctx);
663     have_child = dwarf2_parse_byte(abbrev_ctx);
664
665     abbrev_entry = dwarf2_abbrev_table_add_entry(abbrev_table, entry_code, tag, have_child);
666     assert( NULL != abbrev_entry );
667     while (1) {
668       unsigned long attribute;
669       unsigned long form;
670       attribute = dwarf2_leb128_as_unsigned(abbrev_ctx);
671       form = dwarf2_leb128_as_unsigned(abbrev_ctx);
672       if (0 == attribute) break;
673       dwarf2_abbrev_entry_add_attr(abbrev_entry, attribute, form);
674     }
675   }
676
677   TRACE("found %u entries\n", abbrev_table->n_entries);
678   return abbrev_table;
679 }
680
681 static const char* dwarf2_parse_attr_as_string(dwarf2_abbrev_entry_attr_t* attr,
682                                                dwarf2_parse_context_t* ctx)
683 {
684   const char* ret = NULL;
685   switch (attr->form) {
686   case DW_FORM_string:
687     ret = (const char*) ctx->data;
688     ctx->data += strlen(ret) + 1;
689     break;
690   case DW_FORM_strp:
691     {
692       unsigned long offset = dwarf2_parse_u4(ctx);
693       ret = (const char*) ctx->str_section + offset;
694       /*FIXME("Unsupported indirect string format offset 0x%lx (in .debug_str)\n", offset);*/
695     }
696     break;
697   default:
698     ERR("Unsupported string format 0x%lx for attr 0x%lx\n", attr->form, attr->attribute);
699   }
700   return ret;
701 }
702
703 static unsigned long dwarf2_parse_attr_as_addr(dwarf2_abbrev_entry_attr_t* attr,
704                                                dwarf2_parse_context_t* ctx)
705 {
706   unsigned long offset = 0;
707   switch (ctx->word_size) {
708   case 4:
709     offset = *(const unsigned int*) ctx->data;
710     break;
711   case 8:
712   default:
713     FIXME("Unsupported Word Size %u\n", ctx->word_size);
714   }
715   ctx->data += ctx->word_size;
716   return offset;  
717 }
718
719 static unsigned long dwarf2_parse_attr_as_ref(dwarf2_abbrev_entry_attr_t* attr,
720                                               dwarf2_parse_context_t* ctx)
721 {
722   unsigned long uvalue = 0;
723   switch (attr->form) {
724   case DW_FORM_ref1:
725     uvalue = ctx->offset + dwarf2_parse_byte(ctx);
726     TRACE("ref1<0x%lx>\n", uvalue);
727     break;
728
729   case DW_FORM_ref2:
730     uvalue = ctx->offset + dwarf2_parse_u2(ctx);
731     TRACE("ref2<0x%lx>\n", uvalue);
732     break;
733
734   case DW_FORM_ref4:
735     uvalue = ctx->offset + dwarf2_parse_u4(ctx);
736     TRACE("ref4<0x%lx>\n", uvalue);
737     break;
738
739   case DW_FORM_ref8:
740     /* FIXME: 64bits support */
741     /*
742     uvalue = ctx->offset + dwarf2_parse_u8(ctx);
743     TRACE("ref8<0x%lx>\n", uvalue);
744     */
745     ctx->data += 8;
746     break;
747   }
748   return uvalue;
749 }
750
751
752 static unsigned long dwarf2_parse_attr_as_data(dwarf2_abbrev_entry_attr_t* attr,
753                                                dwarf2_parse_context_t* ctx)
754 {
755   unsigned long uvalue = 0;
756   switch (attr->form) {
757   case DW_FORM_data1:
758     uvalue = dwarf2_parse_byte(ctx);
759     TRACE("data1<%lu>\n", uvalue);
760     break;
761
762   case DW_FORM_data2:
763     uvalue = dwarf2_parse_u2(ctx);
764     TRACE("data2<%lu>\n", uvalue);
765     break;
766
767   case DW_FORM_data4:
768     uvalue = dwarf2_parse_u4(ctx);
769     TRACE("data4<%lu>\n", uvalue);
770     break;
771
772   case DW_FORM_data8:
773     FIXME("Unsupported 64bits support\n");
774     ctx->data += 8;
775     break;
776   }
777   return uvalue;
778 }
779
780 static void dwarf2_parse_attr(dwarf2_abbrev_entry_attr_t* attr,
781                               dwarf2_parse_context_t* ctx)
782 {
783   const unsigned long attribute = attr->attribute;
784   const unsigned long form = attr->form;
785   unsigned long uvalue = 0;
786   long svalue = 0;
787   const char* str = NULL;
788
789   TRACE("(attr:0x%lx,form:0x%lx)\n", attribute, form);
790
791   switch (form) {
792   case DW_FORM_ref_addr:
793   case DW_FORM_addr:
794     uvalue = dwarf2_parse_attr_as_addr(attr, ctx);
795     break;
796
797   case DW_FORM_flag:
798     uvalue = dwarf2_parse_byte(ctx);
799     TRACE("flag<0x%lx>\n", uvalue);
800     break;
801
802   case DW_FORM_data1:
803     uvalue = dwarf2_parse_byte(ctx);
804     TRACE("data1<%lu>\n", uvalue);
805     break;
806
807   case DW_FORM_data2:
808     uvalue = dwarf2_parse_u2(ctx);
809     TRACE("data2<%lu>\n", uvalue);
810     break;
811
812   case DW_FORM_data4:
813     uvalue = dwarf2_parse_u4(ctx);
814     TRACE("data4<%lu>\n", uvalue);
815     break;
816
817   case DW_FORM_ref1:
818   case DW_FORM_ref2:
819   case DW_FORM_ref4:
820   case DW_FORM_ref8:
821     uvalue = dwarf2_parse_attr_as_ref(attr, ctx);
822     /*TRACE("ref<0x%lx>\n", ctx->offset + uvalue);*/
823     break;
824
825   case DW_FORM_data8:
826     FIXME("Unsupported 64bits support\n");
827     ctx->data += 8;
828     break;
829
830   case DW_FORM_sdata:
831     svalue = dwarf2_leb128_as_signed(ctx);
832     break;
833
834   case DW_FORM_ref_udata:
835   case DW_FORM_udata:
836     uvalue = dwarf2_leb128_as_unsigned(ctx);
837     break;
838
839   case DW_FORM_string:
840   case DW_FORM_strp:
841     str = dwarf2_parse_attr_as_string(attr, ctx);
842     TRACE("string<%s>\n", str);
843     break;
844
845   case DW_FORM_block:
846     uvalue = dwarf2_leb128_as_unsigned(ctx);
847     ctx->data += uvalue;
848     break;
849
850   case DW_FORM_block1:
851     uvalue = dwarf2_parse_byte(ctx);
852     ctx->data += uvalue;
853     break;
854
855   case DW_FORM_block2:
856     uvalue = dwarf2_parse_u2(ctx);
857     ctx->data += uvalue;
858     break;
859
860   case DW_FORM_block4:
861     uvalue = dwarf2_parse_u4(ctx);
862     ctx->data += uvalue;
863     break;
864
865   default:
866     break;
867   }
868 }
869
870 static struct symt* dwarf2_find_symt_by_ref(struct module* module, unsigned long ref)
871 {
872   TRACE("want ref<0x%lx>\n", ref); 
873   return NULL;
874 }
875
876 static struct symt* dwarf2_add_symt_ref(struct module* module, unsigned long ref, struct symt* symt)
877 {
878   if (NULL != symt) return NULL;
879   return NULL;
880 }
881
882 static struct symt_basic* dwarf2_parse_base_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
883 {
884   struct symt_basic* symt = NULL;
885   const char* name = NULL;
886   unsigned size = 0;
887   unsigned encoding = 0;
888   enum BasicType bt;
889   dwarf2_abbrev_entry_attr_t* attr = NULL;
890
891   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
892
893   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
894     switch (attr->attribute) {
895     case DW_AT_name:
896       name = dwarf2_parse_attr_as_string(attr, ctx);
897       TRACE("found name %s\n", name);
898       break;
899     case DW_AT_byte_size:
900       size = dwarf2_parse_byte(ctx);
901       break;
902     case DW_AT_encoding:
903       encoding = dwarf2_parse_byte(ctx);
904       break;
905     default:
906       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
907       dwarf2_parse_attr(attr, ctx);
908     }
909   }
910   switch (encoding) {
911   case DW_ATE_void: bt = btVoid; break;
912   case DW_ATE_address: bt = btULong; break;
913   case DW_ATE_boolean: bt = btBool; break;
914   case DW_ATE_complex_float: bt = btComplex; break;
915   case DW_ATE_float: bt = btFloat; break;
916   case DW_ATE_signed: bt = btInt; break;
917   case DW_ATE_unsigned: bt = btUInt; break;
918   case DW_ATE_signed_char: bt = btChar; break;
919   case DW_ATE_unsigned_char: bt = btChar; break;
920   default:
921     bt = btNoType;
922   }
923   /*TRACE("symt_new_basic(%p, %u, %s, %u)", module, bt, name, size);*/
924   symt = symt_new_basic(module, bt, name, size);
925
926   if (entry->have_child) {
927     FIXME("Unsupported children\n");
928   }
929   return symt;
930 }
931
932 static struct symt_typedef* dwarf2_parse_typedef(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
933 {
934   struct symt_typedef* symt = NULL;
935   struct symt* ref_type = NULL;
936   const char* name = NULL;
937   dwarf2_abbrev_entry_attr_t* attr = NULL;
938
939   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
940
941   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
942     switch (attr->attribute) {
943     case DW_AT_name:
944       name = dwarf2_parse_attr_as_string(attr, ctx);
945       TRACE("found name %s\n", name);
946       break;
947     case DW_AT_type:
948       {
949         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
950         ref_type = dwarf2_find_symt_by_ref(module, ref);
951       }
952       break;
953     case DW_AT_decl_file:
954     case DW_AT_decl_line:
955       dwarf2_parse_attr(attr, ctx);
956       break;
957     default:
958       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
959       dwarf2_parse_attr(attr, ctx);
960     }
961   }
962   if (NULL != name) {
963     symt = symt_new_typedef(module, ref_type, name);
964   }
965
966   if (entry->have_child) {
967     FIXME("Unsupported children\n");
968   }
969   return symt;
970 }
971
972 static struct symt_pointer* dwarf2_parse_pointer_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
973 {
974   struct symt_pointer* symt = NULL;
975   struct symt* ref_type = NULL;
976   unsigned size = 0;
977   dwarf2_abbrev_entry_attr_t* attr = NULL;
978
979   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
980
981   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
982     switch (attr->attribute) {
983     case DW_AT_byte_size:
984       size = dwarf2_parse_byte(ctx);
985       break;
986     case DW_AT_type:
987       {
988         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
989         ref_type = dwarf2_find_symt_by_ref(module, ref);
990       }
991       break;
992     default:
993       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
994       dwarf2_parse_attr(attr, ctx);
995     }
996   }
997   symt = symt_new_pointer(module, ref_type);
998
999   if (entry->have_child) {
1000     FIXME("Unsupported children\n");
1001   }
1002   return symt;
1003 }
1004
1005 static void dwarf2_parse_array_subrange_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_array* parent)
1006 {
1007   unsigned min = 0;
1008   unsigned max = 0;
1009   struct symt* idx_type = NULL;
1010   dwarf2_abbrev_entry_attr_t* attr = NULL;
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_type:
1017       {
1018         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1019         idx_type = dwarf2_find_symt_by_ref(module, ref);
1020         /** check if idx_type is a basic_type integer */
1021       }
1022       break;
1023     case DW_AT_lower_bound:
1024       TRACE("%s %s, lower_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1025       min = dwarf2_parse_attr_as_data(attr, ctx);
1026       break;
1027     case DW_AT_upper_bound:
1028       TRACE("%s %s, upper_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1029       max = dwarf2_parse_attr_as_data(attr, ctx);
1030       break;
1031     case DW_AT_count:
1032       TRACE("%s %s, count min:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), min); 
1033       max = min + dwarf2_parse_attr_as_data(attr, ctx);
1034       break;
1035     default:
1036       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1037       dwarf2_parse_attr(attr, ctx);
1038     }
1039   }
1040   parent->start = min;
1041   parent->end = max;
1042
1043   TRACE("found min:%u max:%u\n", min, max);   
1044
1045   if (entry->have_child) {
1046     FIXME("Unsupported children\n");
1047   }
1048 }
1049
1050
1051 static struct symt_array* dwarf2_parse_array_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1052 {
1053   struct symt_array* symt = NULL;
1054   struct symt* ref_type = NULL;
1055   unsigned min = 0;
1056   unsigned max = 0;
1057   dwarf2_abbrev_entry_attr_t* attr = NULL;
1058   unsigned long next_sibling = 0;
1059
1060   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1061
1062   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1063     switch (attr->attribute) {
1064     case DW_AT_sibling:
1065       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1066       break;
1067     case DW_AT_type:
1068       {
1069         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1070         ref_type = dwarf2_find_symt_by_ref(module, ref);
1071       }
1072       break;
1073     default:
1074       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1075       dwarf2_parse_attr(attr, ctx);
1076     }
1077   }
1078
1079   symt = symt_new_array(module, min, max, ref_type);
1080
1081   if (entry->have_child) { /** any interest to not have child ? */
1082     ++ctx->level;
1083     while (ctx->data < ctx->end_data) {
1084       dwarf2_abbrev_entry_t* entry = NULL;
1085       unsigned long entry_code;
1086       unsigned long entry_ref = 0;
1087
1088       entry_ref = ctx->data - ctx->data_stream;
1089       
1090       entry_code = dwarf2_leb128_as_unsigned(ctx);
1091       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1092       if (0 == entry_code) {
1093         break ;
1094       }
1095
1096       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1097       assert( NULL != entry );
1098
1099       switch (entry->tag) {
1100       case DW_TAG_subrange_type:
1101         dwarf2_parse_array_subrange_type(module, entry, ctx, symt);
1102         break;
1103       default:
1104         {
1105           dwarf2_abbrev_entry_attr_t* attr;
1106           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1107           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1108             dwarf2_parse_attr(attr, ctx);
1109           }
1110         }
1111         break;
1112       }
1113     }
1114     --ctx->level;
1115   }
1116
1117   /** set correct data cursor */
1118   dwarf2_check_sibling(ctx, next_sibling);
1119
1120   return symt;
1121 }
1122
1123 static struct symt_typedef* dwarf2_parse_const_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1124 {
1125   struct symt_typedef* symt = NULL;
1126   struct symt* ref_type = NULL;
1127   dwarf2_abbrev_entry_attr_t* attr = NULL;
1128   unsigned long next_sibling = 0;
1129
1130   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1131
1132   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1133     switch (attr->attribute) {
1134     case DW_AT_type:
1135       {
1136         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1137         ref_type = dwarf2_find_symt_by_ref(module, ref);
1138       }
1139       break;
1140     default:
1141       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1142       dwarf2_parse_attr(attr, ctx);
1143     }
1144   }
1145   FIXME("need to generate a name\n");
1146   symt = symt_new_typedef(module, ref_type, "");
1147
1148   if (entry->have_child) {
1149     FIXME("Unsupported children\n");
1150   }
1151
1152   /** set correct data cursor */
1153   dwarf2_check_sibling(ctx, next_sibling);
1154
1155   return symt;
1156 }
1157
1158 static struct symt_typedef* dwarf2_parse_reference_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1159 {
1160   struct symt_typedef* symt = NULL;
1161   struct symt* ref_type = NULL;
1162   dwarf2_abbrev_entry_attr_t* attr = NULL;
1163   unsigned long next_sibling = 0;
1164
1165   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1166
1167   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1168     switch (attr->attribute) {
1169     case DW_AT_sibling:
1170       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1171       break;
1172     case DW_AT_type:
1173       {
1174         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1175         ref_type = dwarf2_find_symt_by_ref(module, ref);
1176       }
1177       break;
1178     default:
1179       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1180       dwarf2_parse_attr(attr, ctx);
1181     }
1182   }
1183   FIXME("need to generate a name\n");
1184   symt = symt_new_typedef(module, ref_type, "");
1185
1186   if (entry->have_child) {
1187     FIXME("Unsupported children\n");
1188   }
1189
1190   /** set correct data cursor */
1191   dwarf2_check_sibling(ctx, next_sibling);
1192
1193   return symt;
1194 }
1195
1196 static void dwarf2_parse_udt_member(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* parent)
1197 {
1198   struct symt* elt_type = NULL;
1199   const char* name = NULL; 
1200   unsigned long offset = 0;
1201   unsigned size = 0;
1202   dwarf2_abbrev_entry_attr_t* attr = NULL;
1203   unsigned long next_sibling = 0;
1204
1205   assert( NULL != parent );
1206
1207   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1208
1209   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1210     switch (attr->attribute) {
1211     case DW_AT_sibling:
1212       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1213       break;
1214     case DW_AT_name:
1215       name = dwarf2_parse_attr_as_string(attr, ctx);
1216       TRACE("found name %s\n", name);
1217       break;
1218     case DW_AT_type:
1219       {
1220         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1221         elt_type = dwarf2_find_symt_by_ref(module, ref);
1222       }
1223       break;
1224     case DW_AT_data_member_location:
1225       {
1226         unsigned long uvalue = 0;
1227         TRACE("found member_location at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1228         /*offset = dwarf2_parse_attr_as_data(attr, ctx);*/
1229         switch (attr->form) {
1230         case DW_FORM_block:
1231           uvalue = dwarf2_leb128_as_unsigned(ctx);
1232           break;
1233         case DW_FORM_block1:
1234           uvalue = dwarf2_parse_byte(ctx);
1235           break;
1236         case DW_FORM_block2:
1237           uvalue = dwarf2_parse_u2(ctx);
1238           break;
1239         case DW_FORM_block4:
1240           uvalue = dwarf2_parse_u4(ctx);
1241           break;
1242         default:
1243           TRACE("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1244           dwarf2_parse_attr(attr, ctx);
1245         }
1246         if (uvalue) {
1247           unsigned char op = dwarf2_parse_byte(ctx);
1248           --uvalue;
1249           switch (op) {
1250           case DW_OP_plus_uconst:
1251             offset = dwarf2_leb128_as_unsigned(ctx);
1252             break;
1253           default:
1254             TRACE("Unhandled attr op at %s, for %s, op:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), op);
1255             ctx->data += uvalue;
1256           }
1257           TRACE("found offset:%lu\n", offset);            
1258         }
1259       }
1260       break;
1261     case DW_AT_decl_file:
1262     case DW_AT_decl_line:
1263       dwarf2_parse_attr(attr, ctx);
1264       break;
1265     default:
1266       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1267       dwarf2_parse_attr(attr, ctx);
1268     }
1269   }
1270   symt_add_udt_element(module, parent, name, elt_type, offset, size);
1271
1272   if (entry->have_child) {
1273     FIXME("Unsupported children\n");
1274   }
1275
1276   /** set correct data cursor */
1277   dwarf2_check_sibling(ctx, next_sibling);
1278 }
1279
1280 static void dwarf2_parse_udt_members(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* symt)
1281 {
1282   if (entry->have_child) { /** any interest to not have child ? */
1283     ++ctx->level;
1284     while (ctx->data < ctx->end_data) {
1285       dwarf2_abbrev_entry_t* entry = NULL;
1286       unsigned long entry_code;
1287       unsigned long entry_ref = 0;
1288
1289       entry_ref = ctx->data - ctx->data_stream;
1290       
1291       entry_code = dwarf2_leb128_as_unsigned(ctx);
1292       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1293       if (0 == entry_code) {
1294         break ;
1295       }
1296
1297       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1298       assert( NULL != entry );
1299
1300       switch (entry->tag) {
1301       case DW_TAG_member:
1302         dwarf2_parse_udt_member(module, entry, ctx, symt);
1303         break;
1304       default:
1305         {
1306           dwarf2_abbrev_entry_attr_t* attr;
1307           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1308           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1309             dwarf2_parse_attr(attr, ctx);
1310           }
1311         }
1312         break;
1313       }
1314     }
1315     --ctx->level;
1316   }
1317 }
1318
1319 static struct symt_udt* dwarf2_parse_class_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1320 {
1321   struct symt_udt* symt = NULL;
1322   const char* name = NULL;
1323   unsigned size = 0;
1324   dwarf2_abbrev_entry_attr_t* attr = NULL;
1325   unsigned long next_sibling = 0;
1326
1327   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1328
1329   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1330     switch (attr->attribute) {
1331     case DW_AT_sibling:
1332       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1333       break;
1334     case DW_AT_name:
1335       name = dwarf2_parse_attr_as_string(attr, ctx);
1336       TRACE("found name %s\n", name);
1337       break;
1338     case DW_AT_byte_size:
1339       size = dwarf2_parse_byte(ctx);
1340       break;
1341     case DW_AT_decl_file:
1342     case DW_AT_decl_line:
1343       dwarf2_parse_attr(attr, ctx);
1344       break;
1345     default:
1346       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1347       dwarf2_parse_attr(attr, ctx);
1348     }
1349   }
1350   symt = symt_new_udt(module, name, size, UdtClass);
1351   dwarf2_parse_udt_members(module, entry, ctx, symt);
1352
1353   /** set correct data cursor */
1354   dwarf2_check_sibling(ctx, next_sibling);
1355
1356   return symt;
1357 }
1358
1359 static struct symt_udt* dwarf2_parse_struct_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1360 {
1361   struct symt_udt* symt = NULL;
1362   const char* name = NULL;
1363   unsigned size = 0;
1364   dwarf2_abbrev_entry_attr_t* attr = NULL;
1365   unsigned long next_sibling = 0;
1366
1367   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1368
1369   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1370     switch (attr->attribute) {
1371     case DW_AT_sibling:
1372       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1373       break;
1374     case DW_AT_name:
1375       name = dwarf2_parse_attr_as_string(attr, ctx);
1376       TRACE("found name %s\n", name);
1377       break;
1378     case DW_AT_byte_size:
1379       size = dwarf2_parse_byte(ctx);
1380       break;
1381     case DW_AT_decl_file:
1382     case DW_AT_decl_line:
1383       dwarf2_parse_attr(attr, ctx);
1384       break;
1385     default:
1386       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1387       dwarf2_parse_attr(attr, ctx);
1388     }
1389   }
1390   symt = symt_new_udt(module, name, size, UdtStruct);
1391   dwarf2_parse_udt_members(module, entry, ctx, symt);
1392
1393   /** set correct data cursor */
1394   dwarf2_check_sibling(ctx, next_sibling);
1395
1396   return symt;
1397 }
1398
1399 static struct symt_udt* dwarf2_parse_union_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1400 {
1401   struct symt_udt* symt = NULL;
1402   const char* name = NULL;
1403   unsigned size = 0;
1404   dwarf2_abbrev_entry_attr_t* attr = NULL;
1405   unsigned long next_sibling = 0;
1406
1407   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1408
1409   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1410     switch (attr->attribute) {
1411     case DW_AT_sibling:
1412       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1413       break;
1414     case DW_AT_name:
1415       name = dwarf2_parse_attr_as_string(attr, ctx);
1416       TRACE("found name %s\n", name);
1417       break;
1418     case DW_AT_byte_size:
1419       size = dwarf2_parse_byte(ctx);
1420       break;
1421     case DW_AT_decl_file:
1422     case DW_AT_decl_line:
1423       dwarf2_parse_attr(attr, ctx);
1424       break;
1425     default:
1426       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1427       dwarf2_parse_attr(attr, ctx);
1428     }
1429   }
1430   symt = symt_new_udt(module, name, size, UdtUnion);
1431   dwarf2_parse_udt_members(module, entry, ctx, symt);
1432
1433   /** set correct data cursor */
1434   dwarf2_check_sibling(ctx, next_sibling);
1435
1436   return symt;
1437 }
1438
1439 static void dwarf2_parse_enumerator(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_enum* parent)
1440 {
1441   const char* name = NULL;
1442   long value = 0;
1443   dwarf2_abbrev_entry_attr_t* attr = NULL;
1444
1445   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1446
1447   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1448     switch (attr->attribute) {
1449     case DW_AT_name:
1450       name = dwarf2_parse_attr_as_string(attr, ctx);
1451       TRACE("found name %s\n", name);
1452       break;
1453     case DW_AT_const_value:
1454       switch (attr->form) {
1455       case DW_FORM_sdata:
1456         value = dwarf2_leb128_as_signed(ctx);
1457         TRACE("found value %ld\n", value);
1458         break;
1459       case DW_FORM_udata:
1460         value = dwarf2_leb128_as_unsigned(ctx);
1461         TRACE("found value %ld\n", value);
1462         break;
1463       default:
1464         TRACE("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1465         dwarf2_parse_attr(attr, ctx);
1466       }
1467       break;
1468     default:
1469       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
1470       dwarf2_parse_attr(attr, ctx);
1471     }
1472   }
1473   symt_add_enum_element(module, parent, name, value);
1474
1475   if (entry->have_child) {
1476     FIXME("Unsupported children\n");
1477   }
1478 }
1479
1480 static struct symt_enum* dwarf2_parse_enumeration_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1481 {
1482   struct symt_enum* symt = NULL;
1483   const char* name = NULL;
1484   unsigned long size = 0;
1485   dwarf2_abbrev_entry_attr_t* attr = NULL;
1486   unsigned long next_sibling = 0;
1487
1488   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1489
1490   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1491     switch (attr->attribute) {
1492     case DW_AT_sibling:
1493       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1494       break;
1495     case DW_AT_name:
1496       name = dwarf2_parse_attr_as_string(attr, ctx);
1497       TRACE("found name %s\n", name);
1498       break;
1499     case DW_AT_byte_size:
1500       size = dwarf2_parse_attr_as_data(attr, ctx);
1501       break;
1502     case DW_AT_decl_file:
1503     case DW_AT_decl_line:
1504       dwarf2_parse_attr(attr, ctx);
1505       break;
1506     default:
1507       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1508       dwarf2_parse_attr(attr, ctx);
1509     }
1510   }
1511   symt = symt_new_enum(module, name);
1512
1513   if (entry->have_child) { /** any interest to not have child ? */
1514     ++ctx->level;
1515     while (ctx->data < ctx->end_data) {
1516       dwarf2_abbrev_entry_t* entry = NULL;
1517       unsigned long entry_code;
1518       unsigned long entry_ref = 0;
1519
1520       entry_ref = ctx->data - ctx->data_stream;
1521       
1522       entry_code = dwarf2_leb128_as_unsigned(ctx);
1523       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1524       if (0 == entry_code) {
1525         break ;
1526       }
1527
1528       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1529       assert( NULL != entry );
1530
1531       switch (entry->tag) {
1532       case DW_TAG_enumerator:
1533         dwarf2_parse_enumerator(module, entry, ctx, symt);
1534         break;
1535       default:
1536         {
1537           dwarf2_abbrev_entry_attr_t* attr;
1538           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1539           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1540             dwarf2_parse_attr(attr, ctx);
1541           }
1542         }
1543         break;
1544       }
1545     }
1546     --ctx->level;
1547   }
1548
1549   /** set correct data cursor */
1550   dwarf2_check_sibling(ctx, next_sibling);
1551
1552   return symt;
1553 }
1554
1555 static void dwarf2_parse_variable(struct module* module, 
1556                                   dwarf2_abbrev_entry_t* entry, 
1557                                   dwarf2_parse_context_t* ctx) 
1558 {
1559   struct symt* var_type = NULL;
1560   dwarf2_abbrev_entry_attr_t* attr = NULL;
1561   const char* name = NULL;
1562   unsigned long next_sibling = 0;
1563
1564   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1565
1566   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1567     switch (attr->attribute) {
1568     case DW_AT_sibling:
1569       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1570       break;
1571     case DW_AT_type:
1572       {
1573         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1574         var_type = dwarf2_find_symt_by_ref(module, ref);
1575       }
1576       break;
1577     case DW_AT_name:
1578       name = dwarf2_parse_attr_as_string(attr, ctx);
1579       TRACE("found name %s\n", name);
1580       break;
1581     case DW_AT_decl_file:
1582     case DW_AT_decl_line:
1583       dwarf2_parse_attr(attr, ctx);
1584       break;
1585     default:
1586       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1587       dwarf2_parse_attr(attr, ctx);
1588     }
1589   }
1590
1591   if (entry->have_child) {
1592     FIXME("Unsupported children\n");
1593   }
1594
1595   /** set correct data cursor */
1596   dwarf2_check_sibling(ctx, next_sibling);  
1597 }
1598
1599 static void dwarf2_parse_subprogram_parameter(struct module* module, 
1600                                               dwarf2_abbrev_entry_t* entry, 
1601                                               dwarf2_parse_context_t* ctx, 
1602                                               struct symt_function_signature* sig_type,
1603                                               struct symt_function* func_type)
1604 {
1605   struct symt* param_type = NULL;
1606   const char* name = NULL;
1607   dwarf2_abbrev_entry_attr_t* attr = NULL;
1608   unsigned long next_sibling = 0;
1609
1610   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1611
1612   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1613     switch (attr->attribute) {
1614     case DW_AT_sibling:
1615       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1616       break;
1617     case DW_AT_type:
1618       {
1619         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1620         param_type = dwarf2_find_symt_by_ref(module, ref);
1621       }
1622       break;
1623     case DW_AT_name:
1624       name = dwarf2_parse_attr_as_string(attr, ctx);
1625       TRACE("found name %s\n", name);
1626       break;
1627     case DW_AT_decl_file:
1628     case DW_AT_decl_line:
1629       dwarf2_parse_attr(attr, ctx);
1630       break;
1631     case DW_AT_location:
1632       dwarf2_parse_attr(attr, ctx);
1633       break;
1634     default:
1635       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1636       dwarf2_parse_attr(attr, ctx);
1637     }
1638   }
1639   if (NULL != sig_type) {
1640     symt_add_function_signature_parameter(module, sig_type, param_type);
1641   }
1642
1643   if (entry->have_child) {
1644     FIXME("Unsupported children\n");
1645   }
1646
1647   /** set correct data cursor */
1648   dwarf2_check_sibling(ctx, next_sibling);  
1649 }
1650
1651 static void dwarf2_parse_inlined_subroutine(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
1652 {
1653   const char* name = NULL;
1654   unsigned long addr = 0;
1655   unsigned long low_pc = 0;
1656   unsigned long high_pc = 0;
1657   unsigned size = 0;
1658   dwarf2_abbrev_entry_attr_t* attr = NULL;
1659   unsigned long next_sibling = 0;
1660
1661   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1662
1663   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1664     switch (attr->attribute) {
1665     case DW_AT_sibling:
1666       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1667       break;
1668     case DW_AT_low_pc:
1669       low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1670       addr = module->module.BaseOfImage + low_pc;
1671       break;
1672     case DW_AT_high_pc:
1673       high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1674       size = high_pc - low_pc;
1675       break;
1676     case DW_AT_name:
1677       name = dwarf2_parse_attr_as_string(attr, ctx);
1678       TRACE("found name %s\n", name);
1679       break;
1680     case DW_AT_decl_file:
1681     case DW_AT_decl_line:
1682       dwarf2_parse_attr(attr, ctx);
1683       break;
1684     default:
1685       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1686       dwarf2_parse_attr(attr, ctx);
1687     }
1688   }
1689
1690   if (entry->have_child) { /** any interest to not have child ? */
1691     ++ctx->level;
1692     while (ctx->data < ctx->end_data) {
1693       dwarf2_abbrev_entry_t* entry = NULL;
1694       unsigned long entry_code;
1695       unsigned long entry_ref = 0;
1696
1697       entry_ref = ctx->data - ctx->data_stream;
1698       
1699       entry_code = dwarf2_leb128_as_unsigned(ctx);
1700       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1701       if (0 == entry_code) {
1702         break ;
1703       }
1704
1705       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1706       assert( NULL != entry );
1707
1708       switch (entry->tag) {
1709       case DW_TAG_formal_parameter:
1710         dwarf2_parse_subprogram_parameter(module, entry, ctx, NULL, NULL);
1711         break;
1712       case DW_TAG_variable:
1713         dwarf2_parse_variable(module, entry, ctx);
1714         break;
1715       case DW_TAG_label:
1716       default:
1717         {
1718           dwarf2_abbrev_entry_attr_t* attr;
1719           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1720           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1721             dwarf2_parse_attr(attr, ctx);
1722           }
1723         }
1724         break;
1725       }
1726     }
1727     --ctx->level;
1728   }
1729
1730   /** set correct data cursor */
1731   dwarf2_check_sibling(ctx, next_sibling);
1732 }
1733
1734
1735 static void dwarf2_parse_subprogram_block(struct module* module, 
1736                                           dwarf2_abbrev_entry_t* entry, 
1737                                           dwarf2_parse_context_t* ctx, 
1738                                           struct symt_function_signature* sig_type,
1739                                           struct symt_function* func_type)
1740 {
1741   dwarf2_abbrev_entry_attr_t* attr = NULL;
1742   const char* name = NULL;
1743   unsigned long next_sibling = 0;
1744
1745   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1746
1747   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1748     switch (attr->attribute) {
1749     case DW_AT_sibling:
1750       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1751       break;
1752     case DW_AT_name:
1753       name = dwarf2_parse_attr_as_string(attr, ctx);
1754       TRACE("found name %s\n", name);
1755       break;
1756     case DW_AT_decl_file:
1757     case DW_AT_decl_line:
1758       dwarf2_parse_attr(attr, ctx);
1759       break;
1760     case DW_AT_ranges: /** what to do ? */
1761       dwarf2_parse_attr(attr, ctx);
1762       break;
1763     default:
1764       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1765       dwarf2_parse_attr(attr, ctx);
1766     }
1767   }
1768   
1769   if (entry->have_child) { /** any interest to not have child ? */
1770     ++ctx->level;
1771     while (ctx->data < ctx->end_data) {
1772       dwarf2_abbrev_entry_t* entry = NULL;
1773       unsigned long entry_code;
1774       unsigned long entry_ref = 0;
1775
1776       entry_ref = ctx->data - ctx->data_stream;
1777       
1778       entry_code = dwarf2_leb128_as_unsigned(ctx);
1779       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1780       if (0 == entry_code) {
1781         break ;
1782       }
1783
1784       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1785       assert( NULL != entry );
1786
1787       switch (entry->tag) {
1788       case DW_TAG_inlined_subroutine:
1789         dwarf2_parse_inlined_subroutine(module, entry, ctx);
1790         break;
1791       case DW_TAG_variable:
1792         dwarf2_parse_variable(module, entry, ctx);
1793         break;
1794       case DW_TAG_label:
1795       default:
1796         {
1797           dwarf2_abbrev_entry_attr_t* attr;
1798           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1799           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1800             dwarf2_parse_attr(attr, ctx);
1801           }
1802         }
1803         break;
1804       }
1805     }
1806     --ctx->level;
1807   }
1808
1809   /** set correct data cursor */
1810   dwarf2_check_sibling(ctx, next_sibling);
1811 }
1812
1813 static void dwarf2_parse_subprogram_content(struct module* module, 
1814                                             dwarf2_abbrev_entry_t* entry, 
1815                                             dwarf2_parse_context_t* ctx, 
1816                                             struct symt_function_signature* sig_type,
1817                                             struct symt_function* func_type)
1818 {
1819   if (entry->have_child) { /** any interest to not have child ? */
1820     ++ctx->level;
1821     while (ctx->data < ctx->end_data) {
1822       dwarf2_abbrev_entry_t* entry = NULL;
1823       unsigned long entry_code;
1824       unsigned long entry_ref = 0;
1825
1826       entry_ref = ctx->data - ctx->data_stream;
1827       
1828       entry_code = dwarf2_leb128_as_unsigned(ctx);
1829       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1830       if (0 == entry_code) {
1831         break ;
1832       }
1833
1834       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1835       assert( NULL != entry );
1836
1837       switch (entry->tag) {
1838       case DW_TAG_formal_parameter:
1839         dwarf2_parse_subprogram_parameter(module, entry, ctx, sig_type, func_type);
1840         break;
1841       case DW_TAG_lexical_block:
1842         dwarf2_parse_subprogram_block(module, entry, ctx, sig_type, func_type);
1843         break;
1844       case DW_TAG_variable:
1845         dwarf2_parse_variable(module, entry, ctx);
1846         break;
1847       case DW_TAG_label:
1848       default:
1849         {
1850           dwarf2_abbrev_entry_attr_t* attr;
1851           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
1852           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1853             dwarf2_parse_attr(attr, ctx);
1854           }
1855         }
1856         break;
1857       }
1858     }
1859     --ctx->level;
1860   }
1861 }
1862
1863 static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1864 {
1865   struct symt_function* func_type = NULL;
1866   const char* name = NULL;
1867   struct symt* ret_type = NULL;
1868   struct symt_function_signature* sig_type = NULL;
1869   unsigned long addr = 0;
1870   unsigned long low_pc = 0;
1871   unsigned long high_pc = 0;
1872   unsigned size = 0;
1873   unsigned char is_decl = 0;
1874   unsigned char inl_flags = 0;
1875   unsigned char decl_file = 0;
1876   unsigned char decl_line = 0;
1877   dwarf2_abbrev_entry_attr_t* attr = NULL;
1878   unsigned long next_sibling = 0;
1879
1880   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
1881
1882   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
1883     switch (attr->attribute) {
1884     case DW_AT_sibling:
1885       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
1886       break;
1887     case DW_AT_low_pc:
1888       low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1889       addr = module->module.BaseOfImage + low_pc;
1890       break;
1891     case DW_AT_high_pc:
1892       high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
1893       size = high_pc - low_pc;
1894       break;
1895     case DW_AT_name:
1896       name = dwarf2_parse_attr_as_string(attr, ctx);
1897       TRACE("found name %s\n", name);
1898       break;
1899     case DW_AT_type:
1900       {
1901         unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
1902         ret_type = dwarf2_find_symt_by_ref(module, ref);
1903       }
1904       break;
1905     case DW_AT_declaration:
1906       is_decl = dwarf2_parse_byte(ctx);
1907       break;
1908     case DW_AT_inline:
1909       inl_flags = dwarf2_parse_byte(ctx);
1910       break;
1911     /* not work yet, need parsing .debug_line and using Compil Unit stmt_list
1912     case DW_AT_decl_file:
1913       decl_file =  dwarf2_parse_byte(ctx);
1914       break;
1915     case DW_AT_decl_line:
1916       decl_line =  dwarf2_parse_byte(ctx);
1917       break;
1918     */
1919     default:
1920       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
1921       dwarf2_parse_attr(attr, ctx);
1922     }
1923   }
1924   sig_type = symt_new_function_signature(module, ret_type);
1925   if (!is_decl) {
1926     func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt);
1927     if (low_pc && high_pc) {
1928       symt_add_function_point(module, func_type, SymTagFuncDebugStart, low_pc, NULL);
1929       symt_add_function_point(module, func_type, SymTagFuncDebugEnd, high_pc, NULL);
1930     }
1931     if (decl_file && decl_line) {
1932       symt_add_func_line(module, func_type, decl_file, decl_line, low_pc);
1933     }
1934   }
1935   dwarf2_parse_subprogram_content(module, entry, ctx, sig_type, func_type);
1936   symt_normalize_function(module, func_type);
1937
1938   /** set correct data cursor */
1939   dwarf2_check_sibling(ctx, next_sibling);
1940
1941   return func_type;
1942 }
1943
1944 static void dwarf2_parse_compiland_content(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_compiland* compiland)
1945 {
1946   if (entry->have_child) { /** any interest to not have child ? */
1947     ++ctx->level;
1948     while (ctx->data < ctx->end_data) {
1949       dwarf2_abbrev_entry_t* entry = NULL;
1950       unsigned long entry_code;
1951       unsigned long entry_ref = 0;
1952
1953       entry_ref = ctx->data - ctx->data_stream;
1954       
1955       entry_code = dwarf2_leb128_as_unsigned(ctx);
1956       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
1957       if (0 == entry_code) {
1958         break ;
1959       }
1960
1961       entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
1962       assert( NULL != entry );
1963
1964       switch (entry->tag) {
1965       case DW_TAG_typedef:
1966         {
1967           struct symt_typedef* symt = dwarf2_parse_typedef(module, entry, ctx);
1968           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1969         }
1970         break;
1971       case DW_TAG_base_type:
1972         {
1973           struct symt_basic* symt = dwarf2_parse_base_type(module, entry, ctx);
1974           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1975         }
1976         break;
1977       case DW_TAG_pointer_type:
1978         {
1979           struct symt_pointer* symt = dwarf2_parse_pointer_type(module, entry, ctx);
1980           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1981         }
1982         break;
1983       case DW_TAG_class_type:
1984         {
1985           struct symt_udt* symt = dwarf2_parse_class_type(module, entry, ctx);
1986           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1987         }
1988         break;
1989       case DW_TAG_structure_type:
1990         {
1991           struct symt_udt* symt = dwarf2_parse_struct_type(module, entry, ctx);
1992           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1993         }
1994         break;
1995       case DW_TAG_union_type:
1996         {
1997           struct symt_udt* symt = dwarf2_parse_union_type(module, entry, ctx);
1998           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
1999         }
2000         break;
2001       case DW_TAG_array_type:
2002         {
2003           struct symt_array* symt = dwarf2_parse_array_type(module, entry, ctx);
2004           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2005         }
2006         break;
2007       case DW_TAG_const_type:
2008         {
2009           struct symt_typedef* symt = dwarf2_parse_const_type(module, entry, ctx);
2010           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2011         }
2012         break;
2013       case DW_TAG_reference_type:
2014         {
2015           struct symt_typedef* symt = dwarf2_parse_reference_type(module, entry, ctx);
2016           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2017         }
2018         break;
2019       case DW_TAG_enumeration_type:
2020         {
2021           struct symt_enum* symt = dwarf2_parse_enumeration_type(module, entry, ctx);
2022           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2023         }
2024         break;
2025       case DW_TAG_subprogram:
2026         {
2027           struct symt_function* symt = dwarf2_parse_subprogram(module, entry, ctx, compiland);
2028           if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2029         }
2030         break;
2031
2032       default:
2033         {
2034           dwarf2_abbrev_entry_attr_t* attr;
2035           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code); 
2036           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
2037             dwarf2_parse_attr(attr, ctx);
2038           }
2039         }
2040         break;
2041       }
2042     }
2043     --ctx->level;
2044   }
2045 }
2046
2047 static struct symt_compiland* dwarf2_parse_compiland(struct module* module, const dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
2048 {
2049   struct symt_compiland* compiland = NULL;
2050   const char* name = NULL;
2051   unsigned long next_sibling = 0;
2052   dwarf2_abbrev_entry_attr_t* attr = NULL;
2053
2054   TRACE("beginning at Ox%x, for %lu\n", ctx->data - ctx->start_data, entry->entry_code); 
2055
2056   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
2057     switch (attr->attribute) {
2058     case DW_AT_sibling:
2059       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
2060       break;
2061     case DW_AT_name:
2062       name = dwarf2_parse_attr_as_string(attr, ctx);
2063       TRACE("found name %s\n", name);
2064       break;
2065     default:
2066       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
2067       dwarf2_parse_attr(attr, ctx);
2068     }
2069   }
2070   compiland = symt_new_compiland(module, name);
2071   dwarf2_parse_compiland_content(module, entry, ctx, compiland);
2072
2073   dwarf2_check_sibling(ctx, next_sibling);
2074
2075   return compiland;
2076 }
2077
2078 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
2079                   const unsigned char* debug, unsigned int debug_size,
2080                   const unsigned char* abbrev, unsigned int abbrev_size,
2081                   const unsigned char* str, unsigned int str_sz)
2082 {
2083   const unsigned char* comp_unit_cursor = debug;
2084   const unsigned char* end_debug = debug + debug_size;
2085   BOOL bRet = TRUE;
2086
2087   while (comp_unit_cursor < end_debug) {
2088     dwarf2_abbrev_table_t* abbrev_table;
2089     const dwarf2_comp_unit_stream_t* comp_unit_stream;
2090     dwarf2_comp_unit_t comp_unit;
2091     dwarf2_parse_context_t ctx;
2092     dwarf2_parse_context_t abbrev_ctx;
2093     struct symt_compiland* compiland = NULL;
2094     
2095     comp_unit_stream = (const dwarf2_comp_unit_stream_t*) comp_unit_cursor;
2096
2097     comp_unit.length = *(unsigned long*)  comp_unit_stream->length;
2098     comp_unit.version = *(unsigned short*) comp_unit_stream->version;
2099     comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset;
2100     comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size;
2101
2102     TRACE("Compilation Unit Herder found at 0x%x:\n", comp_unit_cursor - debug);
2103     TRACE("- length:        %lu\n", comp_unit.length);
2104     TRACE("- version:       %u\n",  comp_unit.version);
2105     TRACE("- abbrev_offset: %lu\n", comp_unit.abbrev_offset);
2106     TRACE("- word_size:     %u\n",  comp_unit.word_size);
2107
2108     ctx.data_stream = debug;
2109     ctx.data = ctx.start_data = comp_unit_cursor + sizeof(dwarf2_comp_unit_stream_t);
2110     ctx.offset = comp_unit_cursor - debug;
2111     ctx.word_size = comp_unit.word_size;
2112     ctx.str_section = str;
2113     ctx.level = 0;
2114
2115     comp_unit_cursor += comp_unit.length + sizeof(unsigned);
2116     ctx.end_data = comp_unit_cursor;
2117
2118     if (2 != comp_unit.version) {
2119       WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", comp_unit.version);
2120       continue ;
2121     }
2122
2123     abbrev_ctx.abbrev_table = NULL;
2124     abbrev_ctx.data_stream = abbrev;
2125     abbrev_ctx.data = abbrev_ctx.start_data = abbrev + comp_unit.abbrev_offset;
2126     abbrev_ctx.end_data = abbrev + abbrev_size;
2127     abbrev_ctx.offset = comp_unit.abbrev_offset;
2128     abbrev_ctx.str_section = str;
2129     abbrev_table = dwarf2_parse_abbrev_set(&abbrev_ctx);    
2130
2131     ctx.abbrev_table = abbrev_table;
2132
2133     while (ctx.data < ctx.end_data) {
2134       const dwarf2_abbrev_entry_t* entry = NULL;
2135       unsigned long entry_code;
2136       unsigned long entry_ref = 0;
2137
2138       entry_ref = ctx.data - ctx.data_stream;
2139       
2140       entry_code = dwarf2_leb128_as_unsigned(&ctx);
2141       TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
2142       if (0 == entry_code) {
2143         continue ;
2144       }
2145       entry = dwarf2_abbrev_table_find_entry(abbrev_table, entry_code);
2146       if (NULL == entry) {
2147         WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, entry_ref);
2148         dwarf2_abbrev_table_free(abbrev_table);
2149         return FALSE;
2150       }
2151
2152       switch (entry->tag) {
2153       case DW_TAG_compile_unit:
2154         {
2155           struct symt_compiland* symt = dwarf2_parse_compiland(module, entry, &ctx);
2156           dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
2157           compiland = symt;
2158         }
2159         break;
2160       default:
2161         {
2162           dwarf2_abbrev_entry_attr_t* attr;
2163           TRACE("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(&ctx), entry->entry_code); 
2164           for (attr = entry->attrs; NULL != attr; attr = attr->next) {
2165             dwarf2_parse_attr(attr, &ctx);
2166           }
2167         }
2168         break;
2169       }
2170     }
2171     dwarf2_abbrev_table_free(abbrev_table);
2172   }
2173   return bRet;
2174 }