dbghelp: Dwarf & function blocks.
[wine/multimedia.git] / dlls / dbghelp / dwarf.c
blob6618513a965455c67b8b123626ffe99b138980d2
1 /*
2 * File dwarf.c - read dwarf2 information from the ELF modules
4 * Copyright (C) 2005, Raphael Junqueira
5 * Copyright (C) 2006, Eric Pouech
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include <sys/types.h>
25 #include <fcntl.h>
26 #ifdef HAVE_SYS_STAT_H
27 # include <sys/stat.h>
28 #endif
29 #ifdef HAVE_SYS_MMAN_H
30 #include <sys/mman.h>
31 #endif
32 #include <limits.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #ifdef HAVE_UNISTD_H
36 # include <unistd.h>
37 #endif
38 #include <stdio.h>
39 #ifndef PATH_MAX
40 #define PATH_MAX MAX_PATH
41 #endif
42 #include <assert.h>
43 #include <stdarg.h>
45 #include "windef.h"
46 #include "winbase.h"
47 #include "winreg.h"
48 #include "winnls.h"
50 #include "dbghelp_private.h"
52 #include "wine/debug.h"
54 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_dwarf);
56 /* FIXME:
57 * - Functions:
58 * o unspecified parameters
59 * o inlined functions
60 * o line numbers
61 * o Debug{Start|End}Point
62 * o CFA
63 * - Udt
64 * o proper types loading (addresses, bitfield, nesting)
67 #if 0
68 static void dump(const void* ptr, unsigned len)
70 int i, j;
71 BYTE msg[128];
72 static const char hexof[] = "0123456789abcdef";
73 const BYTE* x = (const BYTE*)ptr;
75 for (i = 0; i < len; i += 16)
77 sprintf(msg, "%08x: ", i);
78 memset(msg + 10, ' ', 3 * 16 + 1 + 16);
79 for (j = 0; j < min(16, len - i); j++)
81 msg[10 + 3 * j + 0] = hexof[x[i + j] >> 4];
82 msg[10 + 3 * j + 1] = hexof[x[i + j] & 15];
83 msg[10 + 3 * j + 2] = ' ';
84 msg[10 + 3 * 16 + 1 + j] = (x[i + j] >= 0x20 && x[i + j] < 0x7f) ?
85 x[i + j] : '.';
87 msg[10 + 3 * 16] = ' ';
88 msg[10 + 3 * 16 + 1 + 16] = '\0';
89 TRACE("%s\n", msg);
92 #endif
94 /**
96 * Main Specs:
97 * http://www.eagercon.com/dwarf/dwarf3std.htm
98 * http://www.eagercon.com/dwarf/dwarf-2.0.0.pdf
100 * dwarf2.h: http://www.hakpetzna.com/b/binutils/dwarf2_8h-source.html
102 * example of projects who do dwarf2 parsing:
103 * http://www.x86-64.org/cgi-bin/cvsweb.cgi/binutils.dead/binutils/readelf.c?rev=1.1.1.2
104 * http://elis.ugent.be/diota/log/ltrace_elf.c
106 #include "dwarf.h"
109 * Parsers
112 typedef struct dwarf2_abbrev_entry_attr_s {
113 unsigned long attribute;
114 unsigned long form;
115 struct dwarf2_abbrev_entry_attr_s* next;
116 } dwarf2_abbrev_entry_attr_t;
118 typedef struct dwarf2_abbrev_entry_s
120 unsigned long entry_code;
121 unsigned long tag;
122 unsigned char have_child;
123 unsigned num_attr;
124 dwarf2_abbrev_entry_attr_t* attrs;
125 } dwarf2_abbrev_entry_t;
127 struct dwarf2_block
129 unsigned size;
130 const unsigned char* ptr;
133 union attribute
135 unsigned long uvalue;
136 long svalue;
137 const char* string;
138 struct dwarf2_block* block;
141 typedef struct dwarf2_debug_info_s
143 unsigned long offset;
144 const dwarf2_abbrev_entry_t*abbrev;
145 struct symt* symt;
146 union attribute* attributes;
147 struct vector children;
148 } dwarf2_debug_info_t;
150 typedef struct dwarf2_parse_context_s {
151 struct pool pool;
152 struct module* module;
153 struct sparse_array abbrev_table;
154 struct sparse_array debug_info_table;
155 const unsigned char* data_stream;
156 const unsigned char* data;
157 const unsigned char* start_data;
158 const unsigned char* end_data;
159 const unsigned char* str_section;
160 unsigned long offset;
161 unsigned char word_size;
162 } dwarf2_parse_context_t;
164 /* forward declarations */
165 static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_debug_info_t* entry);
167 static unsigned char dwarf2_parse_byte(dwarf2_parse_context_t* ctx)
169 unsigned char uvalue = *(const unsigned char*) ctx->data;
170 ctx->data += 1;
171 return uvalue;
174 static unsigned short dwarf2_parse_u2(dwarf2_parse_context_t* ctx)
176 unsigned short uvalue = *(const unsigned short*) ctx->data;
177 ctx->data += 2;
178 return uvalue;
181 static unsigned long dwarf2_parse_u4(dwarf2_parse_context_t* ctx)
183 unsigned long uvalue = *(const unsigned int*) ctx->data;
184 ctx->data += 4;
185 return uvalue;
188 static unsigned long dwarf2_leb128_as_unsigned(dwarf2_parse_context_t* ctx)
190 unsigned long ret = 0;
191 unsigned char byte;
192 unsigned shift = 0;
194 assert( NULL != ctx );
196 while (1) {
197 byte = dwarf2_parse_byte(ctx);
198 ret |= (byte & 0x7f) << shift;
199 shift += 7;
200 if (0 == (byte & 0x80)) { break ; }
203 return ret;
206 static long dwarf2_leb128_as_signed(dwarf2_parse_context_t* ctx)
208 long ret = 0;
209 unsigned char byte;
210 unsigned shift = 0;
211 const unsigned size = sizeof(int) * 8;
213 assert( NULL != ctx );
215 while (1) {
216 byte = dwarf2_parse_byte(ctx);
217 ret |= (byte & 0x7f) << shift;
218 shift += 7;
219 if (0 == (byte & 0x80)) { break ; }
221 /* as spec: sign bit of byte is 2nd high order bit (80x40)
222 * -> 0x80 is used as flag.
224 if ((shift < size) && (byte & 0x40)) {
225 ret |= - (1 << shift);
227 return ret;
230 static unsigned long dwarf2_parse_addr(dwarf2_parse_context_t* ctx)
232 unsigned long ret;
234 switch (ctx->word_size)
236 case 4:
237 ret = dwarf2_parse_u4(ctx);
238 break;
239 default:
240 FIXME("Unsupported Word Size %u\n", ctx->word_size);
241 ret = 0;
243 return ret;
246 static const char* dwarf2_debug_ctx(const dwarf2_parse_context_t* ctx)
248 /*return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->start_data, ctx->level); */
249 return wine_dbg_sprintf("ctx(0x%x)", ctx->data - ctx->data_stream);
252 static const char* dwarf2_debug_di(dwarf2_debug_info_t* di)
254 return wine_dbg_sprintf("debug_info(offset:0x%lx,abbrev:%p,symt:%p)",
255 di->offset, di->abbrev, di->symt);
258 static dwarf2_abbrev_entry_t*
259 dwarf2_abbrev_table_find_entry(struct sparse_array* abbrev_table,
260 unsigned long entry_code)
262 assert( NULL != abbrev_table );
263 return sparse_array_find(abbrev_table, entry_code);
266 static void dwarf2_parse_abbrev_set(dwarf2_parse_context_t* abbrev_ctx,
267 struct sparse_array* abbrev_table,
268 struct pool* pool)
270 unsigned long entry_code;
271 dwarf2_abbrev_entry_t* abbrev_entry;
272 dwarf2_abbrev_entry_attr_t* new = NULL;
273 dwarf2_abbrev_entry_attr_t* last = NULL;
274 unsigned long attribute;
275 unsigned long form;
277 TRACE("%s, end at %p\n", dwarf2_debug_ctx(abbrev_ctx), abbrev_ctx->end_data);
279 assert( NULL != abbrev_ctx );
281 sparse_array_init(abbrev_table, sizeof(dwarf2_abbrev_entry_t), 32);
282 while (abbrev_ctx->data < abbrev_ctx->end_data)
284 TRACE("now at %s\n", dwarf2_debug_ctx(abbrev_ctx));
285 entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx);
286 TRACE("found entry_code %lu\n", entry_code);
287 if (!entry_code)
289 TRACE("NULL entry code at %s\n", dwarf2_debug_ctx(abbrev_ctx));
290 break;
292 abbrev_entry = sparse_array_add(abbrev_table, entry_code, pool);
293 assert( NULL != abbrev_entry );
295 abbrev_entry->entry_code = entry_code;
296 abbrev_entry->tag = dwarf2_leb128_as_unsigned(abbrev_ctx);
297 abbrev_entry->have_child = dwarf2_parse_byte(abbrev_ctx);
298 abbrev_entry->attrs = NULL;
299 abbrev_entry->num_attr = 0;
301 TRACE("table:(%p,#%u) entry_code(%lu) tag(0x%lx) have_child(%u) -> %p\n",
302 abbrev_table, sparse_array_length(abbrev_table),
303 entry_code, abbrev_entry->tag, abbrev_entry->have_child, abbrev_entry);
305 last = NULL;
306 while (1)
308 attribute = dwarf2_leb128_as_unsigned(abbrev_ctx);
309 form = dwarf2_leb128_as_unsigned(abbrev_ctx);
310 if (!attribute) break;
312 new = pool_alloc(pool, sizeof(dwarf2_abbrev_entry_attr_t));
313 assert(new);
315 new->attribute = attribute;
316 new->form = form;
317 new->next = NULL;
318 if (abbrev_entry->attrs) last->next = new;
319 else abbrev_entry->attrs = new;
320 last = new;
321 abbrev_entry->num_attr++;
324 TRACE("found %u entries\n", sparse_array_length(abbrev_table));
327 static void dwarf2_parse_attr_into_di(dwarf2_parse_context_t* ctx,
328 const dwarf2_abbrev_entry_attr_t* abbrev_attr,
329 union attribute* attr)
332 TRACE("(attr:0x%lx,form:0x%lx)\n", abbrev_attr->attribute, abbrev_attr->form);
334 switch (abbrev_attr->form) {
335 case DW_FORM_ref_addr:
336 case DW_FORM_addr:
337 attr->uvalue = dwarf2_parse_addr(ctx);
338 TRACE("addr<0x%lx>\n", attr->uvalue);
339 break;
341 case DW_FORM_flag:
342 attr->uvalue = dwarf2_parse_byte(ctx);
343 TRACE("flag<0x%lx>\n", attr->uvalue);
344 break;
346 case DW_FORM_data1:
347 attr->uvalue = dwarf2_parse_byte(ctx);
348 TRACE("data1<%lu>\n", attr->uvalue);
349 break;
351 case DW_FORM_data2:
352 attr->uvalue = dwarf2_parse_u2(ctx);
353 TRACE("data2<%lu>\n", attr->uvalue);
354 break;
356 case DW_FORM_data4:
357 attr->uvalue = dwarf2_parse_u4(ctx);
358 TRACE("data4<%lu>\n", attr->uvalue);
359 break;
361 case DW_FORM_data8:
362 FIXME("Unhandled 64bits support\n");
363 ctx->data += 8;
364 break;
366 case DW_FORM_ref1:
367 attr->uvalue = ctx->offset + dwarf2_parse_byte(ctx);
368 TRACE("ref1<0x%lx>\n", attr->uvalue);
369 break;
371 case DW_FORM_ref2:
372 attr->uvalue = ctx->offset + dwarf2_parse_u2(ctx);
373 TRACE("ref2<0x%lx>\n", attr->uvalue);
374 break;
376 case DW_FORM_ref4:
377 attr->uvalue = ctx->offset + dwarf2_parse_u4(ctx);
378 TRACE("ref4<0x%lx>\n", attr->uvalue);
379 break;
381 case DW_FORM_ref8:
382 FIXME("Unhandled 64 bit support\n");
383 ctx->data += 8;
384 break;
386 case DW_FORM_sdata:
387 attr->svalue = dwarf2_leb128_as_signed(ctx);
388 break;
390 case DW_FORM_ref_udata:
391 attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
392 break;
394 case DW_FORM_udata:
395 attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
396 break;
398 case DW_FORM_string:
399 attr->string = (const char*)ctx->data;
400 ctx->data += strlen(attr->string) + 1;
401 TRACE("string<%s>\n", attr->string);
402 break;
404 case DW_FORM_strp:
406 unsigned long offset = dwarf2_parse_u4(ctx);
407 attr->string = (const char*)ctx->str_section + offset;
409 TRACE("strp<%s>\n", attr->string);
410 break;
411 case DW_FORM_block:
412 attr->block = pool_alloc(&ctx->pool, sizeof(struct dwarf2_block));
413 attr->block->size = dwarf2_leb128_as_unsigned(ctx);
414 attr->block->ptr = ctx->data;
415 ctx->data += attr->block->size;
416 break;
418 case DW_FORM_block1:
419 attr->block = pool_alloc(&ctx->pool, sizeof(struct dwarf2_block));
420 attr->block->size = dwarf2_parse_byte(ctx);
421 attr->block->ptr = ctx->data;
422 ctx->data += attr->block->size;
423 break;
425 case DW_FORM_block2:
426 attr->block = pool_alloc(&ctx->pool, sizeof(struct dwarf2_block));
427 attr->block->size = dwarf2_parse_u2(ctx);
428 attr->block->ptr = ctx->data;
429 ctx->data += attr->block->size;
430 break;
432 case DW_FORM_block4:
433 attr->block = pool_alloc(&ctx->pool, sizeof(struct dwarf2_block));
434 attr->block->size = dwarf2_parse_u4(ctx);
435 attr->block->ptr = ctx->data;
436 ctx->data += attr->block->size;
437 break;
439 default:
440 FIXME("Unhandled attribute form %lx\n", abbrev_attr->form);
441 break;
445 static BOOL dwarf2_find_attribute(const dwarf2_debug_info_t* di,
446 unsigned at, union attribute* attr)
448 unsigned i;
449 dwarf2_abbrev_entry_attr_t* abbrev_attr;
451 for (i = 0, abbrev_attr = di->abbrev->attrs; abbrev_attr; i++, abbrev_attr = abbrev_attr->next)
453 if (abbrev_attr->attribute == at)
455 *attr = di->attributes[i];
456 return TRUE;
459 return FALSE;
462 static void dwarf2_find_name(dwarf2_parse_context_t* ctx,
463 const dwarf2_debug_info_t* di,
464 union attribute* attr, const char* pfx)
466 static int index;
468 if (!dwarf2_find_attribute(di, DW_AT_name, attr))
470 char* tmp = pool_alloc(&ctx->pool, strlen(pfx) + 16);
471 if (tmp) sprintf(tmp, "%s_%d", pfx, index++);
472 attr->string = tmp;
476 static void dwarf2_load_one_entry(dwarf2_parse_context_t*, dwarf2_debug_info_t*,
477 struct symt_compiland*);
479 #define Wine_DW_no_register -1
480 #define Wine_DW_frame_register -2
482 static unsigned long dwarf2_compute_location(dwarf2_parse_context_t* ctx,
483 struct dwarf2_block* block,
484 int* in_register)
486 unsigned long loc[64];
487 unsigned stk;
489 if (in_register) *in_register = Wine_DW_no_register;
490 loc[stk = 0] = 0;
492 if (block->size)
494 /* FIXME: would require better definition of contexts */
495 dwarf2_parse_context_t lctx;
496 unsigned char op;
497 BOOL piece_found = FALSE;
499 lctx.data = block->ptr;
500 lctx.end_data = block->ptr + block->size;
501 lctx.word_size = ctx->word_size;
503 while (lctx.data < lctx.end_data)
505 op = dwarf2_parse_byte(&lctx);
506 switch (op)
508 case DW_OP_addr: loc[++stk] = dwarf2_parse_addr(&lctx); break;
509 case DW_OP_const1u: loc[++stk] = dwarf2_parse_byte(&lctx); break;
510 case DW_OP_const1s: loc[++stk] = (long)(char)dwarf2_parse_byte(&lctx); break;
511 case DW_OP_const2u: loc[++stk] = dwarf2_parse_u2(&lctx); break;
512 case DW_OP_const2s: loc[++stk] = (long)(short)dwarf2_parse_u2(&lctx); break;
513 case DW_OP_const4u: loc[++stk] = dwarf2_parse_u4(&lctx); break;
514 case DW_OP_const4s: loc[++stk] = dwarf2_parse_u4(&lctx); break;
515 case DW_OP_constu: loc[++stk] = dwarf2_leb128_as_unsigned(&lctx); break;
516 case DW_OP_consts: loc[++stk] = dwarf2_leb128_as_signed(&lctx); break;
517 case DW_OP_plus_uconst:
518 loc[stk] += dwarf2_leb128_as_unsigned(&lctx); break;
519 case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3:
520 case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7:
521 case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11:
522 case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15:
523 case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19:
524 case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23:
525 case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27:
526 case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31:
527 if (in_register)
529 /* dbghelp APIs don't know how to cope with this anyway
530 * (for example 'long long' stored in two registers)
531 * FIXME: We should tell winedbg how to deal with it (sigh)
533 if (!piece_found || (op - DW_OP_reg0 != *in_register + 1))
535 if (*in_register != Wine_DW_no_register)
536 FIXME("Only supporting one reg (%d -> %d)\n",
537 *in_register, op - DW_OP_reg0);
538 *in_register = op - DW_OP_reg0;
541 else FIXME("Found register, while not expecting it\n");
542 break;
543 case DW_OP_fbreg:
544 if (in_register)
546 if (*in_register != Wine_DW_no_register)
547 FIXME("Only supporting one reg (%d -> -2)\n", *in_register);
548 *in_register = Wine_DW_frame_register;
550 else FIXME("Found register, while not expecting it\n");
551 loc[++stk] = dwarf2_leb128_as_signed(&lctx);
552 break;
553 case DW_OP_piece:
555 unsigned sz = dwarf2_leb128_as_unsigned(&lctx);
556 WARN("Not handling OP_piece directly (size=%d)\n", sz);
557 piece_found = TRUE;
559 break;
560 default:
561 FIXME("Unhandled attr op: %x\n", op);
562 return loc[stk];
566 return loc[stk];
569 static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx,
570 const dwarf2_debug_info_t* di)
572 union attribute attr;
574 if (dwarf2_find_attribute(di, DW_AT_type, &attr))
576 dwarf2_debug_info_t* type;
578 type = sparse_array_find(&ctx->debug_info_table, attr.uvalue);
579 if (!type) FIXME("Unable to find back reference to type %lx\n", attr.uvalue);
580 if (!type->symt)
582 /* load the debug info entity */
583 dwarf2_load_one_entry(ctx, type, NULL);
585 return type->symt;
587 return NULL;
590 /******************************************************************
591 * dwarf2_read_one_debug_info
593 * Loads into memory one debug info entry, and recursively its children (if any)
595 static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx,
596 dwarf2_debug_info_t** pdi)
598 const dwarf2_abbrev_entry_t*abbrev;
599 unsigned long entry_code;
600 unsigned long offset;
601 dwarf2_debug_info_t* di;
602 dwarf2_debug_info_t* child;
603 dwarf2_debug_info_t** where;
604 dwarf2_abbrev_entry_attr_t* attr;
605 unsigned i;
606 union attribute sibling;
608 offset = ctx->data - ctx->data_stream;
609 entry_code = dwarf2_leb128_as_unsigned(ctx);
610 TRACE("found entry_code %lu at 0x%lx\n", entry_code, offset);
611 if (!entry_code)
613 *pdi = NULL;
614 return TRUE;
616 abbrev = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
617 if (!abbrev)
619 WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, offset);
620 return FALSE;
622 di = sparse_array_add(&ctx->debug_info_table, offset, &ctx->pool);
623 if (!di) return FALSE;
624 di->offset = offset;
625 di->abbrev = abbrev;
626 di->symt = NULL;
628 if (abbrev->num_attr)
630 di->attributes = pool_alloc(&ctx->pool,
631 abbrev->num_attr * sizeof(union attribute));
632 for (i = 0, attr = abbrev->attrs; attr; i++, attr = attr->next)
634 dwarf2_parse_attr_into_di(ctx, attr, &di->attributes[i]);
637 else di->attributes = NULL;
638 if (abbrev->have_child)
640 vector_init(&di->children, sizeof(dwarf2_debug_info_t*), 16);
641 while (ctx->data < ctx->end_data)
643 if (!dwarf2_read_one_debug_info(ctx, &child)) return FALSE;
644 if (!child) break;
645 where = vector_add(&di->children, &ctx->pool);
646 if (!where) return FALSE;
647 *where = child;
650 if (dwarf2_find_attribute(di, DW_AT_sibling, &sibling) &&
651 ctx->data != ctx->data_stream + sibling.uvalue)
653 WARN("setting cursor for %s to next sibling <0x%lx>\n",
654 dwarf2_debug_ctx(ctx), sibling.uvalue);
655 ctx->data = ctx->data_stream + sibling.uvalue;
657 *pdi = di;
658 return TRUE;
661 static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx,
662 dwarf2_debug_info_t* di)
664 union attribute name;
665 union attribute size;
666 union attribute encoding;
667 enum BasicType bt;
669 if (di->symt) return di->symt;
671 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
673 dwarf2_find_name(ctx, di, &name, "base_type");
674 if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.uvalue = 0;
675 if (!dwarf2_find_attribute(di, DW_AT_encoding, &encoding)) encoding.uvalue = DW_ATE_void;
677 switch (encoding.uvalue)
679 case DW_ATE_void: bt = btVoid; break;
680 case DW_ATE_address: bt = btULong; break;
681 case DW_ATE_boolean: bt = btBool; break;
682 case DW_ATE_complex_float: bt = btComplex; break;
683 case DW_ATE_float: bt = btFloat; break;
684 case DW_ATE_signed: bt = btInt; break;
685 case DW_ATE_unsigned: bt = btUInt; break;
686 case DW_ATE_signed_char: bt = btChar; break;
687 case DW_ATE_unsigned_char: bt = btChar; break;
688 default: bt = btNoType; break;
690 di->symt = &symt_new_basic(ctx->module, bt, name.string, size.uvalue)->symt;
691 if (di->abbrev->have_child) FIXME("Unsupported children\n");
692 return di->symt;
695 static struct symt* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx,
696 dwarf2_debug_info_t* di)
698 struct symt* ref_type;
699 union attribute name;
701 if (di->symt) return di->symt;
703 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), di->abbrev->entry_code);
705 dwarf2_find_name(ctx, di, &name, "typedef");
706 ref_type = dwarf2_lookup_type(ctx, di);
708 if (name.string)
710 di->symt = &symt_new_typedef(ctx->module, ref_type, name.string)->symt;
712 if (di->abbrev->have_child) FIXME("Unsupported children\n");
713 return di->symt;
716 static struct symt* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx,
717 dwarf2_debug_info_t* di)
719 struct symt* ref_type;
720 union attribute size;
722 if (di->symt) return di->symt;
724 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
726 if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.uvalue = 0;
727 ref_type = dwarf2_lookup_type(ctx, di);
729 di->symt = &symt_new_pointer(ctx->module, ref_type)->symt;
730 if (di->abbrev->have_child) FIXME("Unsupported children\n");
731 return di->symt;
734 static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx,
735 dwarf2_debug_info_t* di)
737 struct symt* ref_type;
738 struct symt* idx_type = NULL;
739 union attribute min, max, cnt;
740 dwarf2_debug_info_t** pchild = NULL;
741 dwarf2_debug_info_t* child;
743 if (di->symt) return di->symt;
745 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
747 if (!di->abbrev->have_child)
749 FIXME("array without range information\n");
750 return NULL;
752 ref_type = dwarf2_lookup_type(ctx, di);
754 while ((pchild = vector_iter_up(&di->children, pchild)))
756 child = *pchild;
757 switch (child->abbrev->tag)
759 case DW_TAG_subrange_type:
760 idx_type = dwarf2_lookup_type(ctx, child);
761 if (!dwarf2_find_attribute(child, DW_AT_lower_bound, &min))
762 min.uvalue = 0;
763 if (!dwarf2_find_attribute(child, DW_AT_upper_bound, &max))
764 max.uvalue = 0;
765 if (dwarf2_find_attribute(child, DW_AT_count, &cnt))
766 max.uvalue = min.uvalue + cnt.uvalue;
767 break;
768 default:
769 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
770 child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
771 break;
774 di->symt = &symt_new_array(ctx->module, min.uvalue, max.uvalue, ref_type, idx_type)->symt;
775 return di->symt;
778 static struct symt* dwarf2_parse_const_type(dwarf2_parse_context_t* ctx,
779 dwarf2_debug_info_t* di)
781 struct symt* ref_type;
783 if (di->symt) return di->symt;
785 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
787 ref_type = dwarf2_lookup_type(ctx, di);
788 if (di->abbrev->have_child) FIXME("Unsupported children\n");
789 di->symt = ref_type;
791 return ref_type;
794 static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx,
795 dwarf2_debug_info_t* di)
797 struct symt* ref_type = NULL;
799 if (di->symt) return di->symt;
801 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
803 ref_type = dwarf2_lookup_type(ctx, di);
804 /* FIXME: for now, we hard-wire C++ references to pointers */
805 di->symt = &symt_new_pointer(ctx->module, ref_type)->symt;
807 if (di->abbrev->have_child) FIXME("Unsupported children\n");
809 return di->symt;
812 static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx,
813 dwarf2_debug_info_t* di,
814 struct symt_udt* parent)
816 struct symt* elt_type;
817 union attribute name;
818 union attribute loc;
819 unsigned long offset = 0;
821 assert(parent);
823 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
825 dwarf2_find_name(ctx, di, &name, "udt_member");
826 elt_type = dwarf2_lookup_type(ctx, di);
827 if (dwarf2_find_attribute(di, DW_AT_data_member_location, &loc))
829 TRACE("found member_location at %s\n", dwarf2_debug_ctx(ctx));
830 offset = dwarf2_compute_location(ctx, loc.block, NULL);
831 TRACE("found offset:%lu\n", offset);
834 symt_add_udt_element(ctx->module, parent, name.string, elt_type, offset, 0);
836 if (di->abbrev->have_child) FIXME("Unsupported children\n");
839 static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx,
840 dwarf2_debug_info_t* di,
841 enum UdtKind udt)
843 union attribute name;
844 union attribute size;
846 if (di->symt) return di->symt;
848 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
850 dwarf2_find_name(ctx, di, &name, "udt");
851 if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.uvalue = 0;
853 di->symt = &symt_new_udt(ctx->module, name.string, size.uvalue, udt)->symt;
855 if (di->abbrev->have_child) /** any interest to not have child ? */
857 dwarf2_debug_info_t** pchild = NULL;
858 dwarf2_debug_info_t* child;
860 while ((pchild = vector_iter_up(&di->children, pchild)))
862 child = *pchild;
864 switch (child->abbrev->tag)
866 case DW_TAG_member:
867 /* FIXME: should I follow the sibling stuff ?? */
868 dwarf2_parse_udt_member(ctx, child, (struct symt_udt*)di->symt);
869 break;
870 case DW_TAG_enumeration_type:
871 dwarf2_parse_enumeration_type(ctx, child);
872 break;
873 case DW_TAG_structure_type:
874 case DW_TAG_class_type:
875 case DW_TAG_union_type:
876 /* FIXME: we need to handle nested udt definitions */
877 break;
878 default:
879 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
880 child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
881 break;
886 return di->symt;
889 static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx,
890 dwarf2_debug_info_t* di,
891 struct symt_enum* parent)
893 union attribute name;
894 union attribute value;
896 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
898 dwarf2_find_name(ctx, di, &name, "enum_value");
899 if (!dwarf2_find_attribute(di, DW_AT_const_value, &value)) value.svalue = 0;
900 symt_add_enum_element(ctx->module, parent, name.string, value.svalue);
902 if (di->abbrev->have_child) FIXME("Unsupported children\n");
905 static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx,
906 dwarf2_debug_info_t* di)
908 union attribute name;
909 union attribute size;
911 if (di->symt) return di->symt;
913 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
915 dwarf2_find_name(ctx, di, &name, "enum");
916 if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.uvalue = 0;
918 di->symt = &symt_new_enum(ctx->module, name.string)->symt;
920 if (di->abbrev->have_child) /* any interest to not have child ? */
922 dwarf2_debug_info_t** pchild = NULL;
923 dwarf2_debug_info_t* child;
925 /* FIXME: should we use the sibling stuff ?? */
926 while ((pchild = vector_iter_up(&di->children, pchild)))
928 child = *pchild;
930 switch (child->abbrev->tag)
932 case DW_TAG_enumerator:
933 dwarf2_parse_enumerator(ctx, child, (struct symt_enum*)di->symt);
934 break;
935 default:
936 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
937 di->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
941 return di->symt;
944 static unsigned dwarf2_map_register(int regno)
946 unsigned reg;
948 switch (regno)
950 case Wine_DW_no_register: FIXME("What the heck\n"); reg = 0; break;
951 /* FIXME: this is a dirty hack */
952 case Wine_DW_frame_register: reg = 0; break;
953 case 0: reg = CV_REG_EAX; break;
954 case 1: reg = CV_REG_ECX; break;
955 case 2: reg = CV_REG_EDX; break;
956 case 3: reg = CV_REG_EBX; break;
957 case 4: reg = CV_REG_ESP; break;
958 case 5: reg = CV_REG_EBP; break;
959 case 6: reg = CV_REG_ESI; break;
960 case 7: reg = CV_REG_EDI; break;
961 case 8: reg = CV_REG_EIP; break;
962 case 9: reg = CV_REG_EFLAGS; break;
963 case 10: reg = CV_REG_CS; break;
964 case 11: reg = CV_REG_SS; break;
965 case 12: reg = CV_REG_DS; break;
966 case 13: reg = CV_REG_ES; break;
967 case 14: reg = CV_REG_FS; break;
968 case 15: reg = CV_REG_GS; break;
969 case 16: case 17: case 18: case 19:
970 case 20: case 21: case 22: case 23:
971 reg = CV_REG_ST0 + regno - 16; break;
972 case 24: reg = CV_REG_CTRL; break;
973 case 25: reg = CV_REG_STAT; break;
974 case 26: reg = CV_REG_TAG; break;
976 reg: fiseg 27
977 reg: fioff 28
978 reg: foseg 29
979 reg: fooff 30
980 reg: fop 31
982 case 32: case 33: case 34: case 35:
983 case 36: case 37: case 38: case 39:
984 reg = CV_REG_XMM0 + regno - 32; break;
985 case 40: reg = CV_REG_MXCSR; break;
986 default:
987 FIXME("Don't know how to map register %d\n", regno);
988 return 0;
990 return reg;
993 /* structure used to pass information around when parsing a subprogram */
994 typedef struct dwarf2_subprogram_s
996 dwarf2_parse_context_t* ctx;
997 struct symt_compiland* compiland;
998 struct symt_function* func;
999 long frame_offset;
1000 int frame_reg;
1001 } dwarf2_subprogram_t;
1003 /******************************************************************
1004 * dwarf2_parse_variable
1006 * Parses any variable (parameter, local/global variable)
1008 static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
1009 struct symt_block* block,
1010 dwarf2_debug_info_t* di)
1012 struct symt* param_type;
1013 union attribute loc;
1014 BOOL is_pmt = di->abbrev->tag == DW_TAG_formal_parameter;
1016 TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
1018 param_type = dwarf2_lookup_type(subpgm->ctx, di);
1019 if (dwarf2_find_attribute(di, DW_AT_location, &loc))
1021 union attribute name;
1022 union attribute ext;
1023 long offset;
1024 int in_reg;
1026 dwarf2_find_name(subpgm->ctx, di, &name, "parameter");
1027 offset = dwarf2_compute_location(subpgm->ctx, loc.block, &in_reg);
1028 TRACE("found parameter %s/%ld (reg=%d) at %s\n",
1029 name.string, offset, in_reg, dwarf2_debug_ctx(subpgm->ctx));
1030 switch (in_reg)
1032 case Wine_DW_no_register:
1033 /* it's a global variable */
1034 /* FIXME: we don't handle it's scope yet */
1035 if (!dwarf2_find_attribute(di, DW_AT_external, &ext))
1036 ext.uvalue = 0;
1037 symt_new_global_variable(subpgm->ctx->module, subpgm->compiland,
1038 name.string, !ext.uvalue,
1039 subpgm->ctx->module->module.BaseOfImage + offset,
1040 0, param_type);
1041 break;
1042 case Wine_DW_frame_register:
1043 in_reg = subpgm->frame_reg;
1044 offset += subpgm->frame_offset;
1045 /* fall through */
1046 default:
1047 /* either a pmt/variable relative to frame pointer or
1048 * pmt/variable in a register
1050 symt_add_func_local(subpgm->ctx->module, subpgm->func,
1051 is_pmt ? DataIsParam : DataIsLocal,
1052 dwarf2_map_register(in_reg), offset,
1053 block, param_type, name.string);
1054 break;
1057 if (is_pmt && subpgm->func && subpgm->func->type)
1058 symt_add_function_signature_parameter(subpgm->ctx->module,
1059 (struct symt_function_signature*)subpgm->func->type,
1060 param_type);
1062 if (di->abbrev->have_child) FIXME("Unsupported children\n");
1065 static void dwarf2_parse_subprogram_label(dwarf2_subprogram_t* subpgm,
1066 dwarf2_debug_info_t* di)
1068 union attribute name;
1069 union attribute low_pc;
1071 TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
1073 if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc)) low_pc.uvalue = 0;
1074 dwarf2_find_name(subpgm->ctx, di, &name, "label");
1076 symt_add_function_point(subpgm->ctx->module, subpgm->func, SymTagLabel,
1077 subpgm->ctx->module->module.BaseOfImage + low_pc.uvalue, name.string);
1080 static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm,
1081 struct symt_block* block_parent,
1082 dwarf2_debug_info_t* di);
1084 static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm,
1085 dwarf2_debug_info_t* di)
1087 TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
1089 /* FIXME: attributes to handle:
1090 DW_AT_low_pc:
1091 DW_AT_high_pc:
1092 DW_AT_name:
1095 if (di->abbrev->have_child) /** any interest to not have child ? */
1097 dwarf2_debug_info_t** pchild = NULL;
1098 dwarf2_debug_info_t* child;
1100 while ((pchild = vector_iter_up(&di->children, pchild)))
1102 child = *pchild;
1104 switch (child->abbrev->tag)
1106 case DW_TAG_formal_parameter:
1107 /* FIXME: this is not properly supported yet
1108 * dwarf2_parse_subprogram_parameter(ctx, child, NULL);
1110 break;
1111 case DW_TAG_variable:
1112 /* FIXME:
1113 * dwarf2_parse_variable(ctx, child);
1115 break;
1116 case DW_TAG_lexical_block:
1117 /* FIXME:
1118 dwarf2_parse_subprogram_block(ctx, child, func);
1120 break;
1121 case DW_TAG_inlined_subroutine:
1122 /* FIXME */
1123 dwarf2_parse_inlined_subroutine(subpgm, child);
1124 break;
1125 case DW_TAG_label:
1126 dwarf2_parse_subprogram_label(subpgm, child);
1127 break;
1128 default:
1129 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
1130 child->abbrev->tag, dwarf2_debug_ctx(subpgm->ctx),
1131 dwarf2_debug_di(di));
1137 static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm,
1138 struct symt_block* parent_block,
1139 dwarf2_debug_info_t* di)
1141 struct symt_block* block;
1142 union attribute low_pc;
1143 union attribute high_pc;
1145 TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
1147 if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc)) low_pc.uvalue = 0;
1148 if (!dwarf2_find_attribute(di, DW_AT_high_pc, &high_pc)) high_pc.uvalue = 0;
1150 block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block,
1151 low_pc.uvalue, high_pc.uvalue - low_pc.uvalue);
1153 if (di->abbrev->have_child) /** any interest to not have child ? */
1155 dwarf2_debug_info_t** pchild = NULL;
1156 dwarf2_debug_info_t* child;
1158 while ((pchild = vector_iter_up(&di->children, pchild)))
1160 child = *pchild;
1162 switch (child->abbrev->tag)
1164 case DW_TAG_inlined_subroutine:
1165 dwarf2_parse_inlined_subroutine(subpgm, child);
1166 break;
1167 case DW_TAG_variable:
1168 dwarf2_parse_variable(subpgm, block, child);
1169 break;
1170 case DW_TAG_lexical_block:
1171 dwarf2_parse_subprogram_block(subpgm, block, child);
1172 break;
1173 case DW_TAG_subprogram:
1174 /* FIXME: likely a declaration (to be checked)
1175 * skip it for now
1177 break;
1178 case DW_TAG_formal_parameter:
1179 /* FIXME: likely elements for exception handling (GCC flavor)
1180 * Skip it for now
1182 break;
1183 case DW_TAG_class_type:
1184 case DW_TAG_structure_type:
1185 case DW_TAG_union_type:
1186 case DW_TAG_enumeration_type:
1187 /* the type referred to will be loaded when we need it, so skip it */
1188 break;
1189 default:
1190 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
1191 child->abbrev->tag, dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
1196 symt_close_func_block(subpgm->ctx->module, subpgm->func, block, 0);
1199 static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
1200 dwarf2_debug_info_t* di,
1201 struct symt_compiland* compiland)
1203 union attribute name;
1204 union attribute low_pc;
1205 union attribute high_pc;
1206 union attribute is_decl;
1207 union attribute inline_flags;
1208 union attribute frame;
1209 struct symt* ret_type;
1210 struct symt_function_signature* sig_type;
1211 dwarf2_subprogram_t subpgm;
1213 if (di->symt) return di->symt;
1215 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
1217 if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc)) low_pc.uvalue = 0;
1218 if (!dwarf2_find_attribute(di, DW_AT_high_pc, &high_pc)) high_pc.uvalue = 0;
1219 if (!dwarf2_find_attribute(di, DW_AT_declaration, &is_decl)) is_decl.uvalue = 0;
1220 if (!dwarf2_find_attribute(di, DW_AT_inline, &inline_flags)) inline_flags.uvalue = 0;
1221 dwarf2_find_name(ctx, di, &name, "subprogram");
1222 ret_type = dwarf2_lookup_type(ctx, di);
1224 /* FIXME: assuming C source code */
1225 sig_type = symt_new_function_signature(ctx->module, ret_type, CV_CALL_FAR_C);
1226 if (!is_decl.uvalue)
1228 subpgm.func = symt_new_function(ctx->module, compiland, name.string,
1229 ctx->module->module.BaseOfImage + low_pc.uvalue,
1230 high_pc.uvalue - low_pc.uvalue,
1231 &sig_type->symt);
1232 di->symt = &subpgm.func->symt;
1234 else subpgm.func = NULL;
1236 subpgm.ctx = ctx;
1237 subpgm.compiland = compiland;
1238 if (dwarf2_find_attribute(di, DW_AT_frame_base, &frame))
1240 subpgm.frame_offset = dwarf2_compute_location(ctx, frame.block, &subpgm.frame_reg);
1241 TRACE("For %s got %ld/%d\n", name.string, subpgm.frame_offset, subpgm.frame_reg);
1243 else /* on stack !! */
1245 subpgm.frame_reg = 0;
1246 subpgm.frame_offset = 0;
1249 if (di->abbrev->have_child) /** any interest to not have child ? */
1251 dwarf2_debug_info_t** pchild = NULL;
1252 dwarf2_debug_info_t* child;
1254 while ((pchild = vector_iter_up(&di->children, pchild)))
1256 child = *pchild;
1258 switch (child->abbrev->tag)
1260 case DW_TAG_variable:
1261 case DW_TAG_formal_parameter:
1262 dwarf2_parse_variable(&subpgm, NULL, child);
1263 break;
1264 case DW_TAG_lexical_block:
1265 dwarf2_parse_subprogram_block(&subpgm, NULL, child);
1266 break;
1267 case DW_TAG_inlined_subroutine:
1268 dwarf2_parse_inlined_subroutine(&subpgm, child);
1269 break;
1270 case DW_TAG_subprogram:
1271 /* FIXME: likely a declaration (to be checked)
1272 * skip it for now
1274 break;
1275 case DW_TAG_label:
1276 dwarf2_parse_subprogram_label(&subpgm, child);
1277 break;
1278 case DW_TAG_class_type:
1279 case DW_TAG_structure_type:
1280 case DW_TAG_union_type:
1281 case DW_TAG_enumeration_type:
1282 case DW_TAG_typedef:
1283 /* the type referred to will be loaded when we need it, so skip it */
1284 break;
1285 case DW_TAG_unspecified_parameters:
1286 /* FIXME: no support in dbghelp's internals so far */
1287 break;
1288 default:
1289 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
1290 child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
1295 symt_normalize_function(subpgm.ctx->module, subpgm.func);
1297 return di->symt;
1300 static void dwarf2_load_one_entry(dwarf2_parse_context_t* ctx,
1301 dwarf2_debug_info_t* di,
1302 struct symt_compiland* compiland)
1304 switch (di->abbrev->tag)
1306 case DW_TAG_typedef:
1307 dwarf2_parse_typedef(ctx, di);
1308 break;
1309 case DW_TAG_base_type:
1310 dwarf2_parse_base_type(ctx, di);
1311 break;
1312 case DW_TAG_pointer_type:
1313 dwarf2_parse_pointer_type(ctx, di);
1314 break;
1315 case DW_TAG_class_type:
1316 dwarf2_parse_udt_type(ctx, di, UdtClass);
1317 break;
1318 case DW_TAG_structure_type:
1319 dwarf2_parse_udt_type(ctx, di, UdtStruct);
1320 break;
1321 case DW_TAG_union_type:
1322 dwarf2_parse_udt_type(ctx, di, UdtUnion);
1323 break;
1324 case DW_TAG_array_type:
1325 dwarf2_parse_array_type(ctx, di);
1326 break;
1327 case DW_TAG_const_type:
1328 dwarf2_parse_const_type(ctx, di);
1329 break;
1330 case DW_TAG_reference_type:
1331 dwarf2_parse_reference_type(ctx, di);
1332 break;
1333 case DW_TAG_enumeration_type:
1334 dwarf2_parse_enumeration_type(ctx, di);
1335 break;
1336 case DW_TAG_subprogram:
1337 dwarf2_parse_subprogram(ctx, di, compiland);
1338 break;
1339 default:
1340 WARN("Unhandled Tag type 0x%lx at %s, for %lu\n",
1341 di->abbrev->tag, dwarf2_debug_ctx(ctx), di->abbrev->entry_code);
1345 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
1346 const unsigned char* debug, unsigned int debug_size,
1347 const unsigned char* abbrev, unsigned int abbrev_size,
1348 const unsigned char* str, unsigned int str_sz)
1350 const unsigned char* comp_unit_cursor = debug;
1351 const unsigned char* end_debug = debug + debug_size;
1353 while (comp_unit_cursor < end_debug) {
1354 const dwarf2_comp_unit_stream_t* comp_unit_stream;
1355 dwarf2_comp_unit_t comp_unit;
1356 dwarf2_parse_context_t ctx;
1357 dwarf2_parse_context_t abbrev_ctx;
1358 dwarf2_debug_info_t* di;
1360 comp_unit_stream = (const dwarf2_comp_unit_stream_t*) comp_unit_cursor;
1362 comp_unit.length = *(unsigned long*) comp_unit_stream->length;
1363 comp_unit.version = *(unsigned short*) comp_unit_stream->version;
1364 comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset;
1365 comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size;
1367 TRACE("Compilation Unit Herder found at 0x%x:\n", comp_unit_cursor - debug);
1368 TRACE("- length: %lu\n", comp_unit.length);
1369 TRACE("- version: %u\n", comp_unit.version);
1370 TRACE("- abbrev_offset: %lu\n", comp_unit.abbrev_offset);
1371 TRACE("- word_size: %u\n", comp_unit.word_size);
1373 pool_init(&ctx.pool, 65536);
1374 ctx.module = module;
1375 ctx.data_stream = debug;
1376 ctx.data = ctx.start_data = comp_unit_cursor + sizeof(dwarf2_comp_unit_stream_t);
1377 ctx.offset = comp_unit_cursor - debug;
1378 ctx.word_size = comp_unit.word_size;
1379 ctx.str_section = str;
1381 comp_unit_cursor += comp_unit.length + sizeof(unsigned);
1382 ctx.end_data = comp_unit_cursor;
1384 if (2 != comp_unit.version) {
1385 WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", comp_unit.version);
1386 continue ;
1389 abbrev_ctx.data_stream = abbrev;
1390 abbrev_ctx.data = abbrev_ctx.start_data = abbrev + comp_unit.abbrev_offset;
1391 abbrev_ctx.end_data = abbrev + abbrev_size;
1392 abbrev_ctx.offset = comp_unit.abbrev_offset;
1393 abbrev_ctx.str_section = str;
1394 dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
1396 sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128);
1397 dwarf2_read_one_debug_info(&ctx, &di);
1398 ctx.data = ctx.start_data; /* FIXME */
1400 if (di->abbrev->tag == DW_TAG_compile_unit)
1402 union attribute name;
1403 dwarf2_debug_info_t** pdi = NULL;
1405 TRACE("beginning at 0x%lx, for %lu\n", di->offset, di->abbrev->entry_code);
1407 dwarf2_find_name(&ctx, di, &name, "compiland");
1408 di->symt = &symt_new_compiland(module, name.string)->symt;
1410 if (di->abbrev->have_child)
1412 while ((pdi = vector_iter_up(&di->children, pdi)))
1414 dwarf2_load_one_entry(&ctx, *pdi, (struct symt_compiland*)di->symt);
1418 else FIXME("Should have a compilation unit here\n");
1419 pool_destroy(&ctx.pool);
1422 module->module.SymType = SymDia;
1423 return TRUE;