Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendwarf.c
Go to the documentation of this file.
00001 /* 00002 * File dwarf.c - read dwarf2 information from the ELF modules 00003 * 00004 * Copyright (C) 2005, Raphael Junqueira 00005 * Copyright (C) 2006-2011, Eric Pouech 00006 * Copyright (C) 2010, Alexandre Julliard 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00021 */ 00022 00023 #define NONAMELESSUNION 00024 00025 #include "config.h" 00026 00027 #include <sys/types.h> 00028 #include <fcntl.h> 00029 #ifdef HAVE_SYS_STAT_H 00030 # include <sys/stat.h> 00031 #endif 00032 #ifdef HAVE_SYS_MMAN_H 00033 #include <sys/mman.h> 00034 #endif 00035 #include <limits.h> 00036 #include <stdlib.h> 00037 #include <string.h> 00038 #ifdef HAVE_UNISTD_H 00039 # include <unistd.h> 00040 #endif 00041 #include <stdio.h> 00042 #include <assert.h> 00043 #include <stdarg.h> 00044 00045 #include "windef.h" 00046 #include "winbase.h" 00047 #include "winuser.h" 00048 #include "ole2.h" 00049 #include "oleauto.h" 00050 00051 #include "dbghelp_private.h" 00052 #include "image_private.h" 00053 00054 #include "wine/debug.h" 00055 00056 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_dwarf); 00057 00058 /* FIXME: 00059 * - Functions: 00060 * o unspecified parameters 00061 * o inlined functions 00062 * o Debug{Start|End}Point 00063 * o CFA 00064 * - Udt 00065 * o proper types loading (nesting) 00066 */ 00067 00068 #if 0 00069 static void dump(const void* ptr, unsigned len) 00070 { 00071 int i, j; 00072 BYTE msg[128]; 00073 static const char hexof[] = "0123456789abcdef"; 00074 const BYTE* x = ptr; 00075 00076 for (i = 0; i < len; i += 16) 00077 { 00078 sprintf(msg, "%08x: ", i); 00079 memset(msg + 10, ' ', 3 * 16 + 1 + 16); 00080 for (j = 0; j < min(16, len - i); j++) 00081 { 00082 msg[10 + 3 * j + 0] = hexof[x[i + j] >> 4]; 00083 msg[10 + 3 * j + 1] = hexof[x[i + j] & 15]; 00084 msg[10 + 3 * j + 2] = ' '; 00085 msg[10 + 3 * 16 + 1 + j] = (x[i + j] >= 0x20 && x[i + j] < 0x7f) ? 00086 x[i + j] : '.'; 00087 } 00088 msg[10 + 3 * 16] = ' '; 00089 msg[10 + 3 * 16 + 1 + 16] = '\0'; 00090 TRACE("%s\n", msg); 00091 } 00092 } 00093 #endif 00094 00107 #include "dwarf.h" 00108 00113 typedef struct dwarf2_abbrev_entry_attr_s 00114 { 00115 unsigned long attribute; 00116 unsigned long form; 00117 struct dwarf2_abbrev_entry_attr_s* next; 00118 } dwarf2_abbrev_entry_attr_t; 00119 00120 typedef struct dwarf2_abbrev_entry_s 00121 { 00122 unsigned long entry_code; 00123 unsigned long tag; 00124 unsigned char have_child; 00125 unsigned num_attr; 00126 dwarf2_abbrev_entry_attr_t* attrs; 00127 } dwarf2_abbrev_entry_t; 00128 00129 struct dwarf2_block 00130 { 00131 unsigned size; 00132 const unsigned char* ptr; 00133 }; 00134 00135 struct attribute 00136 { 00137 unsigned long form; 00138 enum {attr_direct, attr_abstract_origin, attr_specification} gotten_from; 00139 union 00140 { 00141 unsigned long uvalue; 00142 ULONGLONG lluvalue; 00143 long svalue; 00144 const char* string; 00145 struct dwarf2_block block; 00146 } u; 00147 }; 00148 00149 typedef struct dwarf2_debug_info_s 00150 { 00151 const dwarf2_abbrev_entry_t*abbrev; 00152 struct symt* symt; 00153 const unsigned char** data; 00154 struct vector children; 00155 struct dwarf2_debug_info_s* parent; 00156 } dwarf2_debug_info_t; 00157 00158 typedef struct dwarf2_section_s 00159 { 00160 const unsigned char* address; 00161 unsigned size; 00162 DWORD_PTR rva; 00163 } dwarf2_section_t; 00164 00165 enum dwarf2_sections {section_debug, section_string, section_abbrev, section_line, section_ranges, section_max}; 00166 00167 typedef struct dwarf2_traverse_context_s 00168 { 00169 const unsigned char* data; 00170 const unsigned char* end_data; 00171 unsigned char word_size; 00172 } dwarf2_traverse_context_t; 00173 00174 /* symt_cache indexes */ 00175 #define sc_void 0 00176 #define sc_int1 1 00177 #define sc_int2 2 00178 #define sc_int4 3 00179 #define sc_num 4 00180 00181 typedef struct dwarf2_parse_context_s 00182 { 00183 const dwarf2_section_t* sections; 00184 unsigned section; 00185 struct pool pool; 00186 struct module* module; 00187 struct symt_compiland* compiland; 00188 const struct elf_thunk_area*thunks; 00189 struct sparse_array abbrev_table; 00190 struct sparse_array debug_info_table; 00191 unsigned long load_offset; 00192 unsigned long ref_offset; 00193 struct symt* symt_cache[sc_num]; /* void, int1, int2, int4 */ 00194 char* cpp_name; 00195 } dwarf2_parse_context_t; 00196 00197 /* stored in the dbghelp's module internal structure for later reuse */ 00198 struct dwarf2_module_info_s 00199 { 00200 dwarf2_section_t debug_loc; 00201 dwarf2_section_t debug_frame; 00202 dwarf2_section_t eh_frame; 00203 unsigned char word_size; 00204 }; 00205 00206 #define loc_dwarf2_location_list (loc_user + 0) 00207 #define loc_dwarf2_block (loc_user + 1) 00208 00209 /* forward declarations */ 00210 static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_debug_info_t* entry); 00211 00212 static unsigned char dwarf2_get_byte(const unsigned char* ptr) 00213 { 00214 return *ptr; 00215 } 00216 00217 static unsigned char dwarf2_parse_byte(dwarf2_traverse_context_t* ctx) 00218 { 00219 unsigned char uvalue = dwarf2_get_byte(ctx->data); 00220 ctx->data += 1; 00221 return uvalue; 00222 } 00223 00224 static unsigned short dwarf2_get_u2(const unsigned char* ptr) 00225 { 00226 return *(const UINT16*)ptr; 00227 } 00228 00229 static unsigned short dwarf2_parse_u2(dwarf2_traverse_context_t* ctx) 00230 { 00231 unsigned short uvalue = dwarf2_get_u2(ctx->data); 00232 ctx->data += 2; 00233 return uvalue; 00234 } 00235 00236 static unsigned long dwarf2_get_u4(const unsigned char* ptr) 00237 { 00238 return *(const UINT32*)ptr; 00239 } 00240 00241 static unsigned long dwarf2_parse_u4(dwarf2_traverse_context_t* ctx) 00242 { 00243 unsigned long uvalue = dwarf2_get_u4(ctx->data); 00244 ctx->data += 4; 00245 return uvalue; 00246 } 00247 00248 static DWORD64 dwarf2_get_u8(const unsigned char* ptr) 00249 { 00250 return *(const UINT64*)ptr; 00251 } 00252 00253 static DWORD64 dwarf2_parse_u8(dwarf2_traverse_context_t* ctx) 00254 { 00255 DWORD64 uvalue = dwarf2_get_u8(ctx->data); 00256 ctx->data += 8; 00257 return uvalue; 00258 } 00259 00260 static unsigned long dwarf2_get_leb128_as_unsigned(const unsigned char* ptr, const unsigned char** end) 00261 { 00262 unsigned long ret = 0; 00263 unsigned char byte; 00264 unsigned shift = 0; 00265 00266 do 00267 { 00268 byte = dwarf2_get_byte(ptr++); 00269 ret |= (byte & 0x7f) << shift; 00270 shift += 7; 00271 } while (byte & 0x80); 00272 00273 if (end) *end = ptr; 00274 return ret; 00275 } 00276 00277 static unsigned long dwarf2_leb128_as_unsigned(dwarf2_traverse_context_t* ctx) 00278 { 00279 unsigned long ret; 00280 00281 assert(ctx); 00282 00283 ret = dwarf2_get_leb128_as_unsigned(ctx->data, &ctx->data); 00284 00285 return ret; 00286 } 00287 00288 static long dwarf2_get_leb128_as_signed(const unsigned char* ptr, const unsigned char** end) 00289 { 00290 long ret = 0; 00291 unsigned char byte; 00292 unsigned shift = 0; 00293 const unsigned size = sizeof(int) * 8; 00294 00295 do 00296 { 00297 byte = dwarf2_get_byte(ptr++); 00298 ret |= (byte & 0x7f) << shift; 00299 shift += 7; 00300 } while (byte & 0x80); 00301 if (end) *end = ptr; 00302 00303 /* as spec: sign bit of byte is 2nd high order bit (80x40) 00304 * -> 0x80 is used as flag. 00305 */ 00306 if ((shift < size) && (byte & 0x40)) 00307 { 00308 ret |= - (1 << shift); 00309 } 00310 return ret; 00311 } 00312 00313 static long dwarf2_leb128_as_signed(dwarf2_traverse_context_t* ctx) 00314 { 00315 long ret = 0; 00316 00317 assert(ctx); 00318 00319 ret = dwarf2_get_leb128_as_signed(ctx->data, &ctx->data); 00320 return ret; 00321 } 00322 00323 static unsigned dwarf2_leb128_length(const dwarf2_traverse_context_t* ctx) 00324 { 00325 unsigned ret; 00326 for (ret = 0; ctx->data[ret] & 0x80; ret++); 00327 return ret + 1; 00328 } 00329 00330 /****************************************************************** 00331 * dwarf2_get_addr 00332 * 00333 * Returns an address. 00334 * We assume that in all cases word size from Dwarf matches the size of 00335 * addresses in platform where the exec is compiled. 00336 */ 00337 static unsigned long dwarf2_get_addr(const unsigned char* ptr, unsigned word_size) 00338 { 00339 unsigned long ret; 00340 00341 switch (word_size) 00342 { 00343 case 4: 00344 ret = dwarf2_get_u4(ptr); 00345 break; 00346 case 8: 00347 ret = dwarf2_get_u8(ptr); 00348 break; 00349 default: 00350 FIXME("Unsupported Word Size %u\n", word_size); 00351 ret = 0; 00352 } 00353 return ret; 00354 } 00355 00356 static unsigned long dwarf2_parse_addr(dwarf2_traverse_context_t* ctx) 00357 { 00358 unsigned long ret = dwarf2_get_addr(ctx->data, ctx->word_size); 00359 ctx->data += ctx->word_size; 00360 return ret; 00361 } 00362 00363 static const char* dwarf2_debug_traverse_ctx(const dwarf2_traverse_context_t* ctx) 00364 { 00365 return wine_dbg_sprintf("ctx(%p)", ctx->data); 00366 } 00367 00368 static const char* dwarf2_debug_ctx(const dwarf2_parse_context_t* ctx) 00369 { 00370 return wine_dbg_sprintf("ctx(%p,%s)", 00371 ctx, debugstr_w(ctx->module->module.ModuleName)); 00372 } 00373 00374 static const char* dwarf2_debug_di(const dwarf2_debug_info_t* di) 00375 { 00376 return wine_dbg_sprintf("debug_info(abbrev:%p,symt:%p)", 00377 di->abbrev, di->symt); 00378 } 00379 00380 static dwarf2_abbrev_entry_t* 00381 dwarf2_abbrev_table_find_entry(const struct sparse_array* abbrev_table, 00382 unsigned long entry_code) 00383 { 00384 assert( NULL != abbrev_table ); 00385 return sparse_array_find(abbrev_table, entry_code); 00386 } 00387 00388 static void dwarf2_parse_abbrev_set(dwarf2_traverse_context_t* abbrev_ctx, 00389 struct sparse_array* abbrev_table, 00390 struct pool* pool) 00391 { 00392 unsigned long entry_code; 00393 dwarf2_abbrev_entry_t* abbrev_entry; 00394 dwarf2_abbrev_entry_attr_t* new = NULL; 00395 dwarf2_abbrev_entry_attr_t* last = NULL; 00396 unsigned long attribute; 00397 unsigned long form; 00398 00399 assert( NULL != abbrev_ctx ); 00400 00401 TRACE("%s, end at %p\n", 00402 dwarf2_debug_traverse_ctx(abbrev_ctx), abbrev_ctx->end_data); 00403 00404 sparse_array_init(abbrev_table, sizeof(dwarf2_abbrev_entry_t), 32); 00405 while (abbrev_ctx->data < abbrev_ctx->end_data) 00406 { 00407 TRACE("now at %s\n", dwarf2_debug_traverse_ctx(abbrev_ctx)); 00408 entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx); 00409 TRACE("found entry_code %lu\n", entry_code); 00410 if (!entry_code) 00411 { 00412 TRACE("NULL entry code at %s\n", dwarf2_debug_traverse_ctx(abbrev_ctx)); 00413 break; 00414 } 00415 abbrev_entry = sparse_array_add(abbrev_table, entry_code, pool); 00416 assert( NULL != abbrev_entry ); 00417 00418 abbrev_entry->entry_code = entry_code; 00419 abbrev_entry->tag = dwarf2_leb128_as_unsigned(abbrev_ctx); 00420 abbrev_entry->have_child = dwarf2_parse_byte(abbrev_ctx); 00421 abbrev_entry->attrs = NULL; 00422 abbrev_entry->num_attr = 0; 00423 00424 TRACE("table:(%p,#%u) entry_code(%lu) tag(0x%lx) have_child(%u) -> %p\n", 00425 abbrev_table, sparse_array_length(abbrev_table), 00426 entry_code, abbrev_entry->tag, abbrev_entry->have_child, abbrev_entry); 00427 00428 last = NULL; 00429 while (1) 00430 { 00431 attribute = dwarf2_leb128_as_unsigned(abbrev_ctx); 00432 form = dwarf2_leb128_as_unsigned(abbrev_ctx); 00433 if (!attribute) break; 00434 00435 new = pool_alloc(pool, sizeof(dwarf2_abbrev_entry_attr_t)); 00436 assert(new); 00437 00438 new->attribute = attribute; 00439 new->form = form; 00440 new->next = NULL; 00441 if (abbrev_entry->attrs) last->next = new; 00442 else abbrev_entry->attrs = new; 00443 last = new; 00444 abbrev_entry->num_attr++; 00445 } 00446 } 00447 TRACE("found %u entries\n", sparse_array_length(abbrev_table)); 00448 } 00449 00450 static void dwarf2_swallow_attribute(dwarf2_traverse_context_t* ctx, 00451 const dwarf2_abbrev_entry_attr_t* abbrev_attr) 00452 { 00453 unsigned step; 00454 00455 TRACE("(attr:0x%lx,form:0x%lx)\n", abbrev_attr->attribute, abbrev_attr->form); 00456 00457 switch (abbrev_attr->form) 00458 { 00459 case DW_FORM_ref_addr: 00460 case DW_FORM_addr: step = ctx->word_size; break; 00461 case DW_FORM_flag: 00462 case DW_FORM_data1: 00463 case DW_FORM_ref1: step = 1; break; 00464 case DW_FORM_data2: 00465 case DW_FORM_ref2: step = 2; break; 00466 case DW_FORM_data4: 00467 case DW_FORM_ref4: 00468 case DW_FORM_strp: step = 4; break; 00469 case DW_FORM_data8: 00470 case DW_FORM_ref8: step = 8; break; 00471 case DW_FORM_sdata: 00472 case DW_FORM_ref_udata: 00473 case DW_FORM_udata: step = dwarf2_leb128_length(ctx); break; 00474 case DW_FORM_string: step = strlen((const char*)ctx->data) + 1; break; 00475 case DW_FORM_block: step = dwarf2_leb128_as_unsigned(ctx); break; 00476 case DW_FORM_block1: step = dwarf2_parse_byte(ctx); break; 00477 case DW_FORM_block2: step = dwarf2_parse_u2(ctx); break; 00478 case DW_FORM_block4: step = dwarf2_parse_u4(ctx); break; 00479 default: 00480 FIXME("Unhandled attribute form %lx\n", abbrev_attr->form); 00481 return; 00482 } 00483 ctx->data += step; 00484 } 00485 00486 static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, 00487 const dwarf2_abbrev_entry_attr_t* abbrev_attr, 00488 const unsigned char* data, 00489 struct attribute* attr) 00490 { 00491 attr->form = abbrev_attr->form; 00492 switch (attr->form) 00493 { 00494 case DW_FORM_ref_addr: 00495 case DW_FORM_addr: 00496 attr->u.uvalue = dwarf2_get_addr(data, 00497 ctx->module->format_info[DFI_DWARF]->u.dwarf2_info->word_size); 00498 TRACE("addr<0x%lx>\n", attr->u.uvalue); 00499 break; 00500 00501 case DW_FORM_flag: 00502 attr->u.uvalue = dwarf2_get_byte(data); 00503 TRACE("flag<0x%lx>\n", attr->u.uvalue); 00504 break; 00505 00506 case DW_FORM_data1: 00507 attr->u.uvalue = dwarf2_get_byte(data); 00508 TRACE("data1<%lu>\n", attr->u.uvalue); 00509 break; 00510 00511 case DW_FORM_data2: 00512 attr->u.uvalue = dwarf2_get_u2(data); 00513 TRACE("data2<%lu>\n", attr->u.uvalue); 00514 break; 00515 00516 case DW_FORM_data4: 00517 attr->u.uvalue = dwarf2_get_u4(data); 00518 TRACE("data4<%lu>\n", attr->u.uvalue); 00519 break; 00520 00521 case DW_FORM_data8: 00522 attr->u.lluvalue = dwarf2_get_u8(data); 00523 TRACE("data8<%s>\n", wine_dbgstr_longlong(attr->u.uvalue)); 00524 break; 00525 00526 case DW_FORM_ref1: 00527 attr->u.uvalue = ctx->ref_offset + dwarf2_get_byte(data); 00528 TRACE("ref1<0x%lx>\n", attr->u.uvalue); 00529 break; 00530 00531 case DW_FORM_ref2: 00532 attr->u.uvalue = ctx->ref_offset + dwarf2_get_u2(data); 00533 TRACE("ref2<0x%lx>\n", attr->u.uvalue); 00534 break; 00535 00536 case DW_FORM_ref4: 00537 attr->u.uvalue = ctx->ref_offset + dwarf2_get_u4(data); 00538 TRACE("ref4<0x%lx>\n", attr->u.uvalue); 00539 break; 00540 00541 case DW_FORM_ref8: 00542 FIXME("Unhandled 64 bit support\n"); 00543 break; 00544 00545 case DW_FORM_sdata: 00546 attr->u.svalue = dwarf2_get_leb128_as_signed(data, NULL); 00547 break; 00548 00549 case DW_FORM_ref_udata: 00550 attr->u.uvalue = dwarf2_get_leb128_as_unsigned(data, NULL); 00551 break; 00552 00553 case DW_FORM_udata: 00554 attr->u.uvalue = dwarf2_get_leb128_as_unsigned(data, NULL); 00555 break; 00556 00557 case DW_FORM_string: 00558 attr->u.string = (const char *)data; 00559 TRACE("string<%s>\n", attr->u.string); 00560 break; 00561 00562 case DW_FORM_strp: 00563 { 00564 unsigned long offset = dwarf2_get_u4(data); 00565 attr->u.string = (const char*)ctx->sections[section_string].address + offset; 00566 } 00567 TRACE("strp<%s>\n", attr->u.string); 00568 break; 00569 00570 case DW_FORM_block: 00571 attr->u.block.size = dwarf2_get_leb128_as_unsigned(data, &attr->u.block.ptr); 00572 break; 00573 00574 case DW_FORM_block1: 00575 attr->u.block.size = dwarf2_get_byte(data); 00576 attr->u.block.ptr = data + 1; 00577 break; 00578 00579 case DW_FORM_block2: 00580 attr->u.block.size = dwarf2_get_u2(data); 00581 attr->u.block.ptr = data + 2; 00582 break; 00583 00584 case DW_FORM_block4: 00585 attr->u.block.size = dwarf2_get_u4(data); 00586 attr->u.block.ptr = data + 4; 00587 break; 00588 00589 default: 00590 FIXME("Unhandled attribute form %lx\n", abbrev_attr->form); 00591 break; 00592 } 00593 } 00594 00595 static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx, 00596 const dwarf2_debug_info_t* di, 00597 unsigned at, struct attribute* attr) 00598 { 00599 unsigned i, refidx = 0; 00600 dwarf2_abbrev_entry_attr_t* abbrev_attr; 00601 dwarf2_abbrev_entry_attr_t* ref_abbrev_attr = NULL; 00602 00603 attr->gotten_from = attr_direct; 00604 while (di) 00605 { 00606 ref_abbrev_attr = NULL; 00607 for (i = 0, abbrev_attr = di->abbrev->attrs; abbrev_attr; i++, abbrev_attr = abbrev_attr->next) 00608 { 00609 if (abbrev_attr->attribute == at) 00610 { 00611 dwarf2_fill_attr(ctx, abbrev_attr, di->data[i], attr); 00612 return TRUE; 00613 } 00614 if ((abbrev_attr->attribute == DW_AT_abstract_origin || 00615 abbrev_attr->attribute == DW_AT_specification) && 00616 at != DW_AT_sibling) 00617 { 00618 if (ref_abbrev_attr) 00619 FIXME("two references %lx and %lx\n", ref_abbrev_attr->attribute, abbrev_attr->attribute); 00620 ref_abbrev_attr = abbrev_attr; 00621 refidx = i; 00622 attr->gotten_from = (abbrev_attr->attribute == DW_AT_abstract_origin) ? 00623 attr_abstract_origin : attr_specification; 00624 } 00625 } 00626 /* do we have either an abstract origin or a specification debug entry to look into ? */ 00627 if (!ref_abbrev_attr) break; 00628 dwarf2_fill_attr(ctx, ref_abbrev_attr, di->data[refidx], attr); 00629 if (!(di = sparse_array_find(&ctx->debug_info_table, attr->u.uvalue))) 00630 FIXME("Should have found the debug info entry\n"); 00631 } 00632 return FALSE; 00633 } 00634 00635 static void dwarf2_load_one_entry(dwarf2_parse_context_t*, dwarf2_debug_info_t*); 00636 00637 #define Wine_DW_no_register 0x7FFFFFFF 00638 00639 static unsigned dwarf2_map_register(int regno) 00640 { 00641 if (regno == Wine_DW_no_register) 00642 { 00643 FIXME("What the heck map reg 0x%x\n",regno); 00644 return 0; 00645 } 00646 return dbghelp_current_cpu->map_dwarf_register(regno); 00647 } 00648 00649 static enum location_error 00650 compute_location(dwarf2_traverse_context_t* ctx, struct location* loc, 00651 HANDLE hproc, const struct location* frame) 00652 { 00653 DWORD_PTR tmp, stack[64]; 00654 unsigned stk; 00655 unsigned char op; 00656 BOOL piece_found = FALSE; 00657 00658 stack[stk = 0] = 0; 00659 00660 loc->kind = loc_absolute; 00661 loc->reg = Wine_DW_no_register; 00662 00663 while (ctx->data < ctx->end_data) 00664 { 00665 op = dwarf2_parse_byte(ctx); 00666 00667 if (op >= DW_OP_lit0 && op <= DW_OP_lit31) 00668 stack[++stk] = op - DW_OP_lit0; 00669 else if (op >= DW_OP_reg0 && op <= DW_OP_reg31) 00670 { 00671 /* dbghelp APIs don't know how to cope with this anyway 00672 * (for example 'long long' stored in two registers) 00673 * FIXME: We should tell winedbg how to deal with it (sigh) 00674 */ 00675 if (!piece_found) 00676 { 00677 DWORD cvreg = dwarf2_map_register(op - DW_OP_reg0); 00678 if (loc->reg != Wine_DW_no_register) 00679 FIXME("Only supporting one reg (%s/%d -> %s/%d)\n", 00680 dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg, 00681 dbghelp_current_cpu->fetch_regname(cvreg), cvreg); 00682 loc->reg = cvreg; 00683 } 00684 loc->kind = loc_register; 00685 } 00686 else if (op >= DW_OP_breg0 && op <= DW_OP_breg31) 00687 { 00688 /* dbghelp APIs don't know how to cope with this anyway 00689 * (for example 'long long' stored in two registers) 00690 * FIXME: We should tell winedbg how to deal with it (sigh) 00691 */ 00692 if (!piece_found) 00693 { 00694 DWORD cvreg = dwarf2_map_register(op - DW_OP_breg0); 00695 if (loc->reg != Wine_DW_no_register) 00696 FIXME("Only supporting one breg (%s/%d -> %s/%d)\n", 00697 dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg, 00698 dbghelp_current_cpu->fetch_regname(cvreg), cvreg); 00699 loc->reg = cvreg; 00700 } 00701 stack[++stk] = dwarf2_leb128_as_signed(ctx); 00702 loc->kind = loc_regrel; 00703 } 00704 else switch (op) 00705 { 00706 case DW_OP_nop: break; 00707 case DW_OP_addr: stack[++stk] = dwarf2_parse_addr(ctx); break; 00708 case DW_OP_const1u: stack[++stk] = dwarf2_parse_byte(ctx); break; 00709 case DW_OP_const1s: stack[++stk] = dwarf2_parse_byte(ctx); break; 00710 case DW_OP_const2u: stack[++stk] = dwarf2_parse_u2(ctx); break; 00711 case DW_OP_const2s: stack[++stk] = dwarf2_parse_u2(ctx); break; 00712 case DW_OP_const4u: stack[++stk] = dwarf2_parse_u4(ctx); break; 00713 case DW_OP_const4s: stack[++stk] = dwarf2_parse_u4(ctx); break; 00714 case DW_OP_const8u: stack[++stk] = dwarf2_parse_u8(ctx); break; 00715 case DW_OP_const8s: stack[++stk] = dwarf2_parse_u8(ctx); break; 00716 case DW_OP_constu: stack[++stk] = dwarf2_leb128_as_unsigned(ctx); break; 00717 case DW_OP_consts: stack[++stk] = dwarf2_leb128_as_signed(ctx); break; 00718 case DW_OP_dup: stack[stk + 1] = stack[stk]; stk++; break; 00719 case DW_OP_drop: stk--; break; 00720 case DW_OP_over: stack[stk + 1] = stack[stk - 1]; stk++; break; 00721 case DW_OP_pick: stack[stk + 1] = stack[stk - dwarf2_parse_byte(ctx)]; stk++; break; 00722 case DW_OP_swap: tmp = stack[stk]; stack[stk] = stack[stk-1]; stack[stk-1] = tmp; break; 00723 case DW_OP_rot: tmp = stack[stk]; stack[stk] = stack[stk-1]; stack[stk-1] = stack[stk-2]; stack[stk-2] = tmp; break; 00724 case DW_OP_abs: stack[stk] = labs(stack[stk]); break; 00725 case DW_OP_neg: stack[stk] = -stack[stk]; break; 00726 case DW_OP_not: stack[stk] = ~stack[stk]; break; 00727 case DW_OP_and: stack[stk-1] &= stack[stk]; stk--; break; 00728 case DW_OP_or: stack[stk-1] |= stack[stk]; stk--; break; 00729 case DW_OP_minus: stack[stk-1] -= stack[stk]; stk--; break; 00730 case DW_OP_mul: stack[stk-1] *= stack[stk]; stk--; break; 00731 case DW_OP_plus: stack[stk-1] += stack[stk]; stk--; break; 00732 case DW_OP_xor: stack[stk-1] ^= stack[stk]; stk--; break; 00733 case DW_OP_shl: stack[stk-1] <<= stack[stk]; stk--; break; 00734 case DW_OP_shr: stack[stk-1] >>= stack[stk]; stk--; break; 00735 case DW_OP_plus_uconst: stack[stk] += dwarf2_leb128_as_unsigned(ctx); break; 00736 case DW_OP_shra: stack[stk-1] = stack[stk-1] / (1 << stack[stk]); stk--; break; 00737 case DW_OP_div: stack[stk-1] = stack[stk-1] / stack[stk]; stk--; break; 00738 case DW_OP_mod: stack[stk-1] = stack[stk-1] % stack[stk]; stk--; break; 00739 case DW_OP_ge: stack[stk-1] = (stack[stk-1] >= stack[stk]); stk--; break; 00740 case DW_OP_gt: stack[stk-1] = (stack[stk-1] > stack[stk]); stk--; break; 00741 case DW_OP_le: stack[stk-1] = (stack[stk-1] <= stack[stk]); stk--; break; 00742 case DW_OP_lt: stack[stk-1] = (stack[stk-1] < stack[stk]); stk--; break; 00743 case DW_OP_eq: stack[stk-1] = (stack[stk-1] == stack[stk]); stk--; break; 00744 case DW_OP_ne: stack[stk-1] = (stack[stk-1] != stack[stk]); stk--; break; 00745 case DW_OP_skip: tmp = dwarf2_parse_u2(ctx); ctx->data += tmp; break; 00746 case DW_OP_bra: tmp = dwarf2_parse_u2(ctx); if (!stack[stk--]) ctx->data += tmp; break; 00747 case DW_OP_regx: 00748 tmp = dwarf2_leb128_as_unsigned(ctx); 00749 if (!piece_found) 00750 { 00751 if (loc->reg != Wine_DW_no_register) 00752 FIXME("Only supporting one reg\n"); 00753 loc->reg = dwarf2_map_register(tmp); 00754 } 00755 loc->kind = loc_register; 00756 break; 00757 case DW_OP_bregx: 00758 tmp = dwarf2_leb128_as_unsigned(ctx); 00759 if (loc->reg != Wine_DW_no_register) 00760 FIXME("Only supporting one regx\n"); 00761 loc->reg = dwarf2_map_register(tmp); 00762 stack[++stk] = dwarf2_leb128_as_signed(ctx); 00763 loc->kind = loc_regrel; 00764 break; 00765 case DW_OP_fbreg: 00766 if (loc->reg != Wine_DW_no_register) 00767 FIXME("Only supporting one reg (%s/%d -> -2)\n", 00768 dbghelp_current_cpu->fetch_regname(loc->reg), loc->reg); 00769 if (frame && frame->kind == loc_register) 00770 { 00771 loc->kind = loc_regrel; 00772 loc->reg = frame->reg; 00773 stack[++stk] = dwarf2_leb128_as_signed(ctx); 00774 } 00775 else if (frame && frame->kind == loc_regrel) 00776 { 00777 loc->kind = loc_regrel; 00778 loc->reg = frame->reg; 00779 stack[++stk] = dwarf2_leb128_as_signed(ctx) + frame->offset; 00780 } 00781 else 00782 { 00783 /* FIXME: this could be later optimized by not recomputing 00784 * this very location expression 00785 */ 00786 loc->kind = loc_dwarf2_block; 00787 stack[++stk] = dwarf2_leb128_as_signed(ctx); 00788 } 00789 break; 00790 case DW_OP_piece: 00791 { 00792 unsigned sz = dwarf2_leb128_as_unsigned(ctx); 00793 WARN("Not handling OP_piece (size=%d)\n", sz); 00794 piece_found = TRUE; 00795 } 00796 break; 00797 case DW_OP_deref: 00798 if (!stk) 00799 { 00800 FIXME("Unexpected empty stack\n"); 00801 return loc_err_internal; 00802 } 00803 if (loc->reg != Wine_DW_no_register) 00804 { 00805 WARN("Too complex expression for deref\n"); 00806 return loc_err_too_complex; 00807 } 00808 if (hproc) 00809 { 00810 DWORD_PTR addr = stack[stk--]; 00811 DWORD_PTR deref; 00812 00813 if (!ReadProcessMemory(hproc, (void*)addr, &deref, sizeof(deref), NULL)) 00814 { 00815 WARN("Couldn't read memory at %lx\n", addr); 00816 return loc_err_cant_read; 00817 } 00818 stack[++stk] = deref; 00819 } 00820 else 00821 { 00822 loc->kind = loc_dwarf2_block; 00823 } 00824 break; 00825 case DW_OP_deref_size: 00826 if (!stk) 00827 { 00828 FIXME("Unexpected empty stack\n"); 00829 return loc_err_internal; 00830 } 00831 if (loc->reg != Wine_DW_no_register) 00832 { 00833 WARN("Too complex expression for deref\n"); 00834 return loc_err_too_complex; 00835 } 00836 if (hproc) 00837 { 00838 DWORD_PTR addr = stack[stk--]; 00839 BYTE derefsize = dwarf2_parse_byte(ctx); 00840 DWORD64 deref; 00841 00842 if (!ReadProcessMemory(hproc, (void*)addr, &deref, derefsize, NULL)) 00843 { 00844 WARN("Couldn't read memory at %lx\n", addr); 00845 return loc_err_cant_read; 00846 } 00847 00848 switch (derefsize) 00849 { 00850 case 1: stack[++stk] = *(unsigned char*)&deref; break; 00851 case 2: stack[++stk] = *(unsigned short*)&deref; break; 00852 case 4: stack[++stk] = *(DWORD*)&deref; break; 00853 case 8: if (ctx->word_size >= derefsize) stack[++stk] = deref; break; 00854 } 00855 } 00856 else 00857 { 00858 dwarf2_parse_byte(ctx); 00859 loc->kind = loc_dwarf2_block; 00860 } 00861 break; 00862 case DW_OP_stack_value: 00863 /* Expected behaviour is that this is the last instruction of this 00864 * expression and just the "top of stack" value should be put to loc->offset. */ 00865 break; 00866 default: 00867 if (op < DW_OP_lo_user) /* as DW_OP_hi_user is 0xFF, we don't need to test against it */ 00868 FIXME("Unhandled attr op: %x\n", op); 00869 /* FIXME else unhandled extension */ 00870 return loc_err_internal; 00871 } 00872 } 00873 loc->offset = stack[stk]; 00874 return 0; 00875 } 00876 00877 static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx, 00878 const dwarf2_debug_info_t* di, 00879 unsigned long dw, 00880 struct location* loc, 00881 const struct location* frame) 00882 { 00883 struct attribute xloc; 00884 00885 if (!dwarf2_find_attribute(ctx, di, dw, &xloc)) return FALSE; 00886 00887 switch (xloc.form) 00888 { 00889 case DW_FORM_data1: case DW_FORM_data2: 00890 case DW_FORM_udata: case DW_FORM_sdata: 00891 loc->kind = loc_absolute; 00892 loc->reg = 0; 00893 loc->offset = xloc.u.uvalue; 00894 return TRUE; 00895 case DW_FORM_data4: case DW_FORM_data8: 00896 loc->kind = loc_dwarf2_location_list; 00897 loc->reg = Wine_DW_no_register; 00898 loc->offset = xloc.u.uvalue; 00899 return TRUE; 00900 case DW_FORM_block: 00901 case DW_FORM_block1: 00902 case DW_FORM_block2: 00903 case DW_FORM_block4: 00904 break; 00905 default: FIXME("Unsupported yet form %lx\n", xloc.form); 00906 return FALSE; 00907 } 00908 00909 /* assume we have a block form */ 00910 00911 if (xloc.u.block.size) 00912 { 00913 dwarf2_traverse_context_t lctx; 00914 enum location_error err; 00915 00916 lctx.data = xloc.u.block.ptr; 00917 lctx.end_data = xloc.u.block.ptr + xloc.u.block.size; 00918 lctx.word_size = ctx->module->format_info[DFI_DWARF]->u.dwarf2_info->word_size; 00919 00920 err = compute_location(&lctx, loc, NULL, frame); 00921 if (err < 0) 00922 { 00923 loc->kind = loc_error; 00924 loc->reg = err; 00925 } 00926 else if (loc->kind == loc_dwarf2_block) 00927 { 00928 unsigned* ptr = pool_alloc(&ctx->module->pool, 00929 sizeof(unsigned) + xloc.u.block.size); 00930 *ptr = xloc.u.block.size; 00931 memcpy(ptr + 1, xloc.u.block.ptr, xloc.u.block.size); 00932 loc->offset = (unsigned long)ptr; 00933 } 00934 } 00935 return TRUE; 00936 } 00937 00938 static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx, 00939 const dwarf2_debug_info_t* di) 00940 { 00941 struct attribute attr; 00942 dwarf2_debug_info_t* type; 00943 00944 if (!dwarf2_find_attribute(ctx, di, DW_AT_type, &attr)) 00945 return NULL; 00946 if (!(type = sparse_array_find(&ctx->debug_info_table, attr.u.uvalue))) 00947 { 00948 FIXME("Unable to find back reference to type %lx\n", attr.u.uvalue); 00949 return NULL; 00950 } 00951 if (!type->symt) 00952 { 00953 /* load the debug info entity */ 00954 dwarf2_load_one_entry(ctx, type); 00955 if (!type->symt) 00956 FIXME("Unable to load forward reference for tag %lx\n", type->abbrev->tag); 00957 } 00958 return type->symt; 00959 } 00960 00961 static const char* dwarf2_get_cpp_name(dwarf2_parse_context_t* ctx, dwarf2_debug_info_t* di, const char* name) 00962 { 00963 char* last; 00964 struct attribute diname; 00965 struct attribute spec; 00966 00967 if (di->abbrev->tag == DW_TAG_compile_unit) return name; 00968 if (!ctx->cpp_name) 00969 ctx->cpp_name = pool_alloc(&ctx->pool, MAX_SYM_NAME); 00970 last = ctx->cpp_name + MAX_SYM_NAME - strlen(name) - 1; 00971 strcpy(last, name); 00972 00973 /* if the di is a definition, but has also a (previous) declaration, then scope must 00974 * be gotten from declaration not definition 00975 */ 00976 if (dwarf2_find_attribute(ctx, di, DW_AT_specification, &spec) && spec.gotten_from == attr_direct) 00977 { 00978 di = sparse_array_find(&ctx->debug_info_table, spec.u.uvalue); 00979 if (!di) 00980 { 00981 FIXME("Should have found the debug info entry\n"); 00982 return NULL; 00983 } 00984 } 00985 00986 for (di = di->parent; di; di = di->parent) 00987 { 00988 switch (di->abbrev->tag) 00989 { 00990 case DW_TAG_namespace: 00991 case DW_TAG_structure_type: 00992 case DW_TAG_class_type: 00993 case DW_TAG_interface_type: 00994 case DW_TAG_union_type: 00995 if (dwarf2_find_attribute(ctx, di, DW_AT_name, &diname)) 00996 { 00997 size_t len = strlen(diname.u.string); 00998 last -= 2 + len; 00999 if (last < ctx->cpp_name) return NULL; 01000 memcpy(last, diname.u.string, len); 01001 last[len] = last[len + 1] = ':'; 01002 } 01003 break; 01004 default: 01005 break; 01006 } 01007 } 01008 return last; 01009 } 01010 01011 /****************************************************************** 01012 * dwarf2_read_range 01013 * 01014 * read a range for a given debug_info (either using AT_range attribute, in which 01015 * case we don't return all the details, or using AT_low_pc & AT_high_pc attributes) 01016 * in all cases, range is relative to beginning of compilation unit 01017 */ 01018 static BOOL dwarf2_read_range(dwarf2_parse_context_t* ctx, const dwarf2_debug_info_t* di, 01019 unsigned long* plow, unsigned long* phigh) 01020 { 01021 struct attribute range; 01022 01023 if (dwarf2_find_attribute(ctx, di, DW_AT_ranges, &range)) 01024 { 01025 dwarf2_traverse_context_t traverse; 01026 unsigned long low, high; 01027 01028 traverse.data = ctx->sections[section_ranges].address + range.u.uvalue; 01029 traverse.end_data = ctx->sections[section_ranges].address + 01030 ctx->sections[section_ranges].size; 01031 traverse.word_size = ctx->module->format_info[DFI_DWARF]->u.dwarf2_info->word_size; 01032 01033 *plow = ULONG_MAX; 01034 *phigh = 0; 01035 while (traverse.data + 2 * traverse.word_size < traverse.end_data) 01036 { 01037 low = dwarf2_parse_addr(&traverse); 01038 high = dwarf2_parse_addr(&traverse); 01039 if (low == 0 && high == 0) break; 01040 if (low == ULONG_MAX) FIXME("unsupported yet (base address selection)\n"); 01041 if (low < *plow) *plow = low; 01042 if (high > *phigh) *phigh = high; 01043 } 01044 if (*plow == ULONG_MAX || *phigh == 0) {FIXME("no entry found\n"); return FALSE;} 01045 if (*plow == *phigh) {FIXME("entry found, but low=high\n"); return FALSE;} 01046 01047 return TRUE; 01048 } 01049 else 01050 { 01051 struct attribute low_pc; 01052 struct attribute high_pc; 01053 01054 if (!dwarf2_find_attribute(ctx, di, DW_AT_low_pc, &low_pc) || 01055 !dwarf2_find_attribute(ctx, di, DW_AT_high_pc, &high_pc)) 01056 return FALSE; 01057 *plow = low_pc.u.uvalue; 01058 *phigh = high_pc.u.uvalue; 01059 return TRUE; 01060 } 01061 } 01062 01063 /****************************************************************** 01064 * dwarf2_read_one_debug_info 01065 * 01066 * Loads into memory one debug info entry, and recursively its children (if any) 01067 */ 01068 static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx, 01069 dwarf2_traverse_context_t* traverse, 01070 dwarf2_debug_info_t* parent_di, 01071 dwarf2_debug_info_t** pdi) 01072 { 01073 const dwarf2_abbrev_entry_t*abbrev; 01074 unsigned long entry_code; 01075 unsigned long offset; 01076 dwarf2_debug_info_t* di; 01077 dwarf2_debug_info_t* child; 01078 dwarf2_debug_info_t** where; 01079 dwarf2_abbrev_entry_attr_t* attr; 01080 unsigned i; 01081 struct attribute sibling; 01082 01083 offset = traverse->data - ctx->sections[ctx->section].address; 01084 entry_code = dwarf2_leb128_as_unsigned(traverse); 01085 TRACE("found entry_code %lu at 0x%lx\n", entry_code, offset); 01086 if (!entry_code) 01087 { 01088 *pdi = NULL; 01089 return TRUE; 01090 } 01091 abbrev = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code); 01092 if (!abbrev) 01093 { 01094 WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, offset); 01095 return FALSE; 01096 } 01097 di = sparse_array_add(&ctx->debug_info_table, offset, &ctx->pool); 01098 if (!di) return FALSE; 01099 di->abbrev = abbrev; 01100 di->symt = NULL; 01101 di->parent = parent_di; 01102 01103 if (abbrev->num_attr) 01104 { 01105 di->data = pool_alloc(&ctx->pool, abbrev->num_attr * sizeof(const char*)); 01106 for (i = 0, attr = abbrev->attrs; attr; i++, attr = attr->next) 01107 { 01108 di->data[i] = traverse->data; 01109 dwarf2_swallow_attribute(traverse, attr); 01110 } 01111 } 01112 else di->data = NULL; 01113 if (abbrev->have_child) 01114 { 01115 vector_init(&di->children, sizeof(dwarf2_debug_info_t*), 16); 01116 while (traverse->data < traverse->end_data) 01117 { 01118 if (!dwarf2_read_one_debug_info(ctx, traverse, di, &child)) return FALSE; 01119 if (!child) break; 01120 where = vector_add(&di->children, &ctx->pool); 01121 if (!where) return FALSE; 01122 *where = child; 01123 } 01124 } 01125 if (dwarf2_find_attribute(ctx, di, DW_AT_sibling, &sibling) && 01126 traverse->data != ctx->sections[ctx->section].address + sibling.u.uvalue) 01127 { 01128 WARN("setting cursor for %s to next sibling <0x%lx>\n", 01129 dwarf2_debug_traverse_ctx(traverse), sibling.u.uvalue); 01130 traverse->data = ctx->sections[ctx->section].address + sibling.u.uvalue; 01131 } 01132 *pdi = di; 01133 return TRUE; 01134 } 01135 01136 static struct vector* dwarf2_get_di_children(dwarf2_parse_context_t* ctx, 01137 dwarf2_debug_info_t* di) 01138 { 01139 struct attribute spec; 01140 01141 while (di) 01142 { 01143 if (di->abbrev->have_child) 01144 return &di->children; 01145 if (!dwarf2_find_attribute(ctx, di, DW_AT_specification, &spec)) break; 01146 if (!(di = sparse_array_find(&ctx->debug_info_table, spec.u.uvalue))) 01147 FIXME("Should have found the debug info entry\n"); 01148 } 01149 return NULL; 01150 } 01151 01152 static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx, 01153 dwarf2_debug_info_t* di) 01154 { 01155 struct attribute name; 01156 struct attribute size; 01157 struct attribute encoding; 01158 enum BasicType bt; 01159 int cache_idx = -1; 01160 if (di->symt) return di->symt; 01161 01162 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01163 01164 if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) 01165 name.u.string = NULL; 01166 if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = 0; 01167 if (!dwarf2_find_attribute(ctx, di, DW_AT_encoding, &encoding)) encoding.u.uvalue = DW_ATE_void; 01168 01169 switch (encoding.u.uvalue) 01170 { 01171 case DW_ATE_void: bt = btVoid; break; 01172 case DW_ATE_address: bt = btULong; break; 01173 case DW_ATE_boolean: bt = btBool; break; 01174 case DW_ATE_complex_float: bt = btComplex; break; 01175 case DW_ATE_float: bt = btFloat; break; 01176 case DW_ATE_signed: bt = btInt; break; 01177 case DW_ATE_unsigned: bt = btUInt; break; 01178 case DW_ATE_signed_char: bt = btChar; break; 01179 case DW_ATE_unsigned_char: bt = btChar; break; 01180 default: bt = btNoType; break; 01181 } 01182 di->symt = &symt_new_basic(ctx->module, bt, name.u.string, size.u.uvalue)->symt; 01183 switch (bt) 01184 { 01185 case btVoid: 01186 assert(size.u.uvalue == 0); 01187 cache_idx = sc_void; 01188 break; 01189 case btInt: 01190 switch (size.u.uvalue) 01191 { 01192 case 1: cache_idx = sc_int1; break; 01193 case 2: cache_idx = sc_int2; break; 01194 case 4: cache_idx = sc_int4; break; 01195 } 01196 break; 01197 default: break; 01198 } 01199 if (cache_idx != -1 && !ctx->symt_cache[cache_idx]) 01200 ctx->symt_cache[cache_idx] = di->symt; 01201 01202 if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); 01203 return di->symt; 01204 } 01205 01206 static struct symt* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx, 01207 dwarf2_debug_info_t* di) 01208 { 01209 struct symt* ref_type; 01210 struct attribute name; 01211 01212 if (di->symt) return di->symt; 01213 01214 TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), di->abbrev->entry_code); 01215 01216 if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) name.u.string = NULL; 01217 ref_type = dwarf2_lookup_type(ctx, di); 01218 01219 if (name.u.string) 01220 di->symt = &symt_new_typedef(ctx->module, ref_type, name.u.string)->symt; 01221 if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); 01222 return di->symt; 01223 } 01224 01225 static struct symt* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx, 01226 dwarf2_debug_info_t* di) 01227 { 01228 struct symt* ref_type; 01229 struct attribute size; 01230 01231 if (di->symt) return di->symt; 01232 01233 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01234 01235 if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = sizeof(void *); 01236 if (!(ref_type = dwarf2_lookup_type(ctx, di))) 01237 { 01238 ref_type = ctx->symt_cache[sc_void]; 01239 assert(ref_type); 01240 } 01241 di->symt = &symt_new_pointer(ctx->module, ref_type, size.u.uvalue)->symt; 01242 if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); 01243 return di->symt; 01244 } 01245 01246 static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, 01247 dwarf2_debug_info_t* di) 01248 { 01249 struct symt* ref_type; 01250 struct symt* idx_type = NULL; 01251 struct attribute min, max, cnt; 01252 dwarf2_debug_info_t* child; 01253 unsigned int i; 01254 const struct vector* children; 01255 01256 if (di->symt) return di->symt; 01257 01258 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01259 01260 ref_type = dwarf2_lookup_type(ctx, di); 01261 01262 if (!(children = dwarf2_get_di_children(ctx, di))) 01263 { 01264 /* fake an array with unknown size */ 01265 /* FIXME: int4 even on 64bit machines??? */ 01266 idx_type = ctx->symt_cache[sc_int4]; 01267 min.u.uvalue = 0; 01268 max.u.uvalue = -1; 01269 } 01270 else for (i = 0; i < vector_length(children); i++) 01271 { 01272 child = *(dwarf2_debug_info_t**)vector_at(children, i); 01273 switch (child->abbrev->tag) 01274 { 01275 case DW_TAG_subrange_type: 01276 idx_type = dwarf2_lookup_type(ctx, child); 01277 if (!dwarf2_find_attribute(ctx, child, DW_AT_lower_bound, &min)) 01278 min.u.uvalue = 0; 01279 if (!dwarf2_find_attribute(ctx, child, DW_AT_upper_bound, &max)) 01280 max.u.uvalue = 0; 01281 if (dwarf2_find_attribute(ctx, child, DW_AT_count, &cnt)) 01282 max.u.uvalue = min.u.uvalue + cnt.u.uvalue; 01283 break; 01284 default: 01285 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", 01286 child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01287 break; 01288 } 01289 } 01290 di->symt = &symt_new_array(ctx->module, min.u.uvalue, max.u.uvalue, ref_type, idx_type)->symt; 01291 return di->symt; 01292 } 01293 01294 static struct symt* dwarf2_parse_const_type(dwarf2_parse_context_t* ctx, 01295 dwarf2_debug_info_t* di) 01296 { 01297 struct symt* ref_type; 01298 01299 if (di->symt) return di->symt; 01300 01301 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01302 01303 if (!(ref_type = dwarf2_lookup_type(ctx, di))) 01304 { 01305 ref_type = ctx->symt_cache[sc_void]; 01306 assert(ref_type); 01307 } 01308 if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); 01309 di->symt = ref_type; 01310 01311 return ref_type; 01312 } 01313 01314 static struct symt* dwarf2_parse_volatile_type(dwarf2_parse_context_t* ctx, 01315 dwarf2_debug_info_t* di) 01316 { 01317 struct symt* ref_type; 01318 01319 if (di->symt) return di->symt; 01320 01321 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01322 01323 if (!(ref_type = dwarf2_lookup_type(ctx, di))) 01324 { 01325 ref_type = ctx->symt_cache[sc_void]; 01326 assert(ref_type); 01327 } 01328 if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); 01329 di->symt = ref_type; 01330 01331 return ref_type; 01332 } 01333 01334 static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx, 01335 dwarf2_debug_info_t* di) 01336 { 01337 struct symt* ref_type = NULL; 01338 01339 if (di->symt) return di->symt; 01340 01341 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01342 01343 ref_type = dwarf2_lookup_type(ctx, di); 01344 /* FIXME: for now, we hard-wire C++ references to pointers */ 01345 di->symt = &symt_new_pointer(ctx->module, ref_type, sizeof(void *))->symt; 01346 01347 if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); 01348 01349 return di->symt; 01350 } 01351 01352 static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx, 01353 dwarf2_debug_info_t* di, 01354 struct symt_udt* parent) 01355 { 01356 struct symt* elt_type; 01357 struct attribute name; 01358 struct attribute bit_size; 01359 struct attribute bit_offset; 01360 struct location loc; 01361 01362 assert(parent); 01363 01364 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01365 01366 if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) name.u.string = NULL; 01367 elt_type = dwarf2_lookup_type(ctx, di); 01368 if (dwarf2_compute_location_attr(ctx, di, DW_AT_data_member_location, &loc, NULL)) 01369 { 01370 if (loc.kind != loc_absolute) 01371 { 01372 FIXME("Found register, while not expecting it\n"); 01373 loc.offset = 0; 01374 } 01375 else 01376 TRACE("found member_location at %s -> %lu\n", 01377 dwarf2_debug_ctx(ctx), loc.offset); 01378 } 01379 else 01380 loc.offset = 0; 01381 if (!dwarf2_find_attribute(ctx, di, DW_AT_bit_size, &bit_size)) 01382 bit_size.u.uvalue = 0; 01383 if (dwarf2_find_attribute(ctx, di, DW_AT_bit_offset, &bit_offset)) 01384 { 01385 /* FIXME: we should only do this when implementation is LSB (which is 01386 * the case on i386 processors) 01387 */ 01388 struct attribute nbytes; 01389 if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &nbytes)) 01390 { 01391 DWORD64 size; 01392 nbytes.u.uvalue = symt_get_info(ctx->module, elt_type, TI_GET_LENGTH, &size) ? 01393 (unsigned long)size : 0; 01394 } 01395 bit_offset.u.uvalue = nbytes.u.uvalue * 8 - bit_offset.u.uvalue - bit_size.u.uvalue; 01396 } 01397 else bit_offset.u.uvalue = 0; 01398 symt_add_udt_element(ctx->module, parent, name.u.string, elt_type, 01399 (loc.offset << 3) + bit_offset.u.uvalue, 01400 bit_size.u.uvalue); 01401 01402 if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); 01403 } 01404 01405 static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, 01406 dwarf2_debug_info_t* di); 01407 01408 static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, 01409 dwarf2_debug_info_t* di, 01410 enum UdtKind udt) 01411 { 01412 struct attribute name; 01413 struct attribute size; 01414 struct vector* children; 01415 dwarf2_debug_info_t*child; 01416 unsigned int i; 01417 01418 if (di->symt) return di->symt; 01419 01420 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01421 01422 /* quirk... FIXME provide real support for anonymous UDTs */ 01423 if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) 01424 name.u.string = "zz_anon_zz"; 01425 if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = 0; 01426 01427 di->symt = &symt_new_udt(ctx->module, dwarf2_get_cpp_name(ctx, di, name.u.string), 01428 size.u.uvalue, udt)->symt; 01429 01430 children = dwarf2_get_di_children(ctx, di); 01431 if (children) for (i = 0; i < vector_length(children); i++) 01432 { 01433 child = *(dwarf2_debug_info_t**)vector_at(children, i); 01434 01435 switch (child->abbrev->tag) 01436 { 01437 case DW_TAG_member: 01438 /* FIXME: should I follow the sibling stuff ?? */ 01439 dwarf2_parse_udt_member(ctx, child, (struct symt_udt*)di->symt); 01440 break; 01441 case DW_TAG_enumeration_type: 01442 dwarf2_parse_enumeration_type(ctx, child); 01443 break; 01444 case DW_TAG_subprogram: 01445 dwarf2_parse_subprogram(ctx, child); 01446 break; 01447 case DW_TAG_structure_type: 01448 case DW_TAG_class_type: 01449 case DW_TAG_union_type: 01450 case DW_TAG_typedef: 01451 /* FIXME: we need to handle nested udt definitions */ 01452 case DW_TAG_inheritance: 01453 case DW_TAG_template_type_param: 01454 case DW_TAG_template_value_param: 01455 case DW_TAG_variable: 01456 case DW_TAG_imported_declaration: 01457 case DW_TAG_ptr_to_member_type: 01458 /* FIXME: some C++ related stuff */ 01459 break; 01460 default: 01461 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", 01462 child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01463 break; 01464 } 01465 } 01466 01467 return di->symt; 01468 } 01469 01470 static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx, 01471 dwarf2_debug_info_t* di, 01472 struct symt_enum* parent) 01473 { 01474 struct attribute name; 01475 struct attribute value; 01476 01477 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01478 01479 if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) return; 01480 if (!dwarf2_find_attribute(ctx, di, DW_AT_const_value, &value)) value.u.svalue = 0; 01481 symt_add_enum_element(ctx->module, parent, name.u.string, value.u.svalue); 01482 01483 if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); 01484 } 01485 01486 static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, 01487 dwarf2_debug_info_t* di) 01488 { 01489 struct attribute name; 01490 struct attribute size; 01491 struct symt_basic* basetype; 01492 struct vector* children; 01493 dwarf2_debug_info_t*child; 01494 unsigned int i; 01495 01496 if (di->symt) return di->symt; 01497 01498 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01499 01500 if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) name.u.string = NULL; 01501 if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = 4; 01502 01503 switch (size.u.uvalue) /* FIXME: that's wrong */ 01504 { 01505 case 1: basetype = symt_new_basic(ctx->module, btInt, "char", 1); break; 01506 case 2: basetype = symt_new_basic(ctx->module, btInt, "short", 2); break; 01507 default: 01508 case 4: basetype = symt_new_basic(ctx->module, btInt, "int", 4); break; 01509 } 01510 01511 di->symt = &symt_new_enum(ctx->module, name.u.string, &basetype->symt)->symt; 01512 01513 children = dwarf2_get_di_children(ctx, di); 01514 /* FIXME: should we use the sibling stuff ?? */ 01515 if (children) for (i = 0; i < vector_length(children); i++) 01516 { 01517 child = *(dwarf2_debug_info_t**)vector_at(children, i); 01518 01519 switch (child->abbrev->tag) 01520 { 01521 case DW_TAG_enumerator: 01522 dwarf2_parse_enumerator(ctx, child, (struct symt_enum*)di->symt); 01523 break; 01524 default: 01525 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", 01526 di->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01527 } 01528 } 01529 return di->symt; 01530 } 01531 01532 /* structure used to pass information around when parsing a subprogram */ 01533 typedef struct dwarf2_subprogram_s 01534 { 01535 dwarf2_parse_context_t* ctx; 01536 struct symt_function* func; 01537 BOOL non_computed_variable; 01538 struct location frame; 01539 } dwarf2_subprogram_t; 01540 01541 /****************************************************************** 01542 * dwarf2_parse_variable 01543 * 01544 * Parses any variable (parameter, local/global variable) 01545 */ 01546 static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, 01547 struct symt_block* block, 01548 dwarf2_debug_info_t* di) 01549 { 01550 struct symt* param_type; 01551 struct attribute name, value; 01552 struct location loc; 01553 BOOL is_pmt; 01554 01555 TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); 01556 01557 is_pmt = !block && di->abbrev->tag == DW_TAG_formal_parameter; 01558 param_type = dwarf2_lookup_type(subpgm->ctx, di); 01559 01560 if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_name, &name)) { 01561 /* cannot do much without the name, the functions below won't like it. */ 01562 return; 01563 } 01564 if (dwarf2_compute_location_attr(subpgm->ctx, di, DW_AT_location, 01565 &loc, &subpgm->frame)) 01566 { 01567 struct attribute ext; 01568 01569 TRACE("found parameter %s (kind=%d, offset=%ld, reg=%d) at %s\n", 01570 name.u.string, loc.kind, loc.offset, loc.reg, 01571 dwarf2_debug_ctx(subpgm->ctx)); 01572 01573 switch (loc.kind) 01574 { 01575 case loc_error: 01576 break; 01577 case loc_absolute: 01578 /* it's a global variable */ 01579 /* FIXME: we don't handle its scope yet */ 01580 if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_external, &ext)) 01581 ext.u.uvalue = 0; 01582 loc.offset += subpgm->ctx->load_offset; 01583 symt_new_global_variable(subpgm->ctx->module, subpgm->ctx->compiland, 01584 dwarf2_get_cpp_name(subpgm->ctx, di, name.u.string), !ext.u.uvalue, 01585 loc, 0, param_type); 01586 break; 01587 default: 01588 subpgm->non_computed_variable = TRUE; 01589 /* fall through */ 01590 case loc_register: 01591 case loc_regrel: 01592 /* either a pmt/variable relative to frame pointer or 01593 * pmt/variable in a register 01594 */ 01595 assert(subpgm->func); 01596 symt_add_func_local(subpgm->ctx->module, subpgm->func, 01597 is_pmt ? DataIsParam : DataIsLocal, 01598 &loc, block, param_type, name.u.string); 01599 break; 01600 } 01601 } 01602 else if (dwarf2_find_attribute(subpgm->ctx, di, DW_AT_const_value, &value)) 01603 { 01604 VARIANT v; 01605 if (subpgm->func) WARN("Unsupported constant %s in function\n", name.u.string); 01606 if (is_pmt) FIXME("Unsupported constant (parameter) %s in function\n", name.u.string); 01607 switch (value.form) 01608 { 01609 case DW_FORM_data1: 01610 case DW_FORM_data2: 01611 case DW_FORM_data4: 01612 case DW_FORM_udata: 01613 case DW_FORM_addr: 01614 v.n1.n2.vt = VT_UI4; 01615 v.n1.n2.n3.lVal = value.u.uvalue; 01616 break; 01617 01618 case DW_FORM_data8: 01619 v.n1.n2.vt = VT_UI8; 01620 v.n1.n2.n3.llVal = value.u.lluvalue; 01621 break; 01622 01623 case DW_FORM_sdata: 01624 v.n1.n2.vt = VT_I4; 01625 v.n1.n2.n3.lVal = value.u.svalue; 01626 break; 01627 01628 case DW_FORM_strp: 01629 case DW_FORM_string: 01630 /* FIXME: native doesn't report const strings from here !! 01631 * however, the value of the string is in the code somewhere 01632 */ 01633 v.n1.n2.vt = VT_I1 | VT_BYREF; 01634 v.n1.n2.n3.byref = pool_strdup(&subpgm->ctx->module->pool, value.u.string); 01635 break; 01636 01637 case DW_FORM_block: 01638 case DW_FORM_block1: 01639 case DW_FORM_block2: 01640 case DW_FORM_block4: 01641 v.n1.n2.vt = VT_I4; 01642 switch (value.u.block.size) 01643 { 01644 case 1: v.n1.n2.n3.lVal = *(BYTE*)value.u.block.ptr; break; 01645 case 2: v.n1.n2.n3.lVal = *(USHORT*)value.u.block.ptr; break; 01646 case 4: v.n1.n2.n3.lVal = *(DWORD*)value.u.block.ptr; break; 01647 default: 01648 v.n1.n2.vt = VT_I1 | VT_BYREF; 01649 v.n1.n2.n3.byref = pool_alloc(&subpgm->ctx->module->pool, value.u.block.size); 01650 memcpy(v.n1.n2.n3.byref, value.u.block.ptr, value.u.block.size); 01651 } 01652 break; 01653 01654 default: 01655 FIXME("Unsupported form for const value %s (%lx)\n", 01656 name.u.string, value.form); 01657 v.n1.n2.vt = VT_EMPTY; 01658 } 01659 di->symt = &symt_new_constant(subpgm->ctx->module, subpgm->ctx->compiland, 01660 name.u.string, param_type, &v)->symt; 01661 } 01662 else 01663 { 01664 /* variable has been optimized away... report anyway */ 01665 loc.kind = loc_error; 01666 loc.reg = loc_err_no_location; 01667 if (subpgm->func) 01668 { 01669 symt_add_func_local(subpgm->ctx->module, subpgm->func, 01670 is_pmt ? DataIsParam : DataIsLocal, 01671 &loc, block, param_type, name.u.string); 01672 } 01673 else 01674 { 01675 WARN("dropping global variable %s which has been optimized away\n", name.u.string); 01676 } 01677 } 01678 if (is_pmt && subpgm->func && subpgm->func->type) 01679 symt_add_function_signature_parameter(subpgm->ctx->module, 01680 (struct symt_function_signature*)subpgm->func->type, 01681 param_type); 01682 01683 if (dwarf2_get_di_children(subpgm->ctx, di)) FIXME("Unsupported children\n"); 01684 } 01685 01686 static void dwarf2_parse_subprogram_label(dwarf2_subprogram_t* subpgm, 01687 const dwarf2_debug_info_t* di) 01688 { 01689 struct attribute name; 01690 struct attribute low_pc; 01691 struct location loc; 01692 01693 TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); 01694 01695 if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0; 01696 if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_name, &name)) 01697 name.u.string = NULL; 01698 01699 loc.kind = loc_absolute; 01700 loc.offset = subpgm->ctx->load_offset + low_pc.u.uvalue; 01701 symt_add_function_point(subpgm->ctx->module, subpgm->func, SymTagLabel, 01702 &loc, name.u.string); 01703 } 01704 01705 static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, 01706 struct symt_block* parent_block, 01707 dwarf2_debug_info_t* di); 01708 01709 static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm, 01710 struct symt_block* parent_block, 01711 dwarf2_debug_info_t* di) 01712 { 01713 struct symt_block* block; 01714 unsigned long low_pc, high_pc; 01715 struct vector* children; 01716 dwarf2_debug_info_t*child; 01717 unsigned int i; 01718 01719 TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); 01720 01721 if (!dwarf2_read_range(subpgm->ctx, di, &low_pc, &high_pc)) 01722 { 01723 FIXME("cannot read range\n"); 01724 return; 01725 } 01726 01727 block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block, 01728 subpgm->ctx->load_offset + low_pc - subpgm->func->address, 01729 high_pc - low_pc); 01730 01731 children = dwarf2_get_di_children(subpgm->ctx, di); 01732 if (children) for (i = 0; i < vector_length(children); i++) 01733 { 01734 child = *(dwarf2_debug_info_t**)vector_at(children, i); 01735 01736 switch (child->abbrev->tag) 01737 { 01738 case DW_TAG_formal_parameter: 01739 case DW_TAG_variable: 01740 dwarf2_parse_variable(subpgm, block, child); 01741 break; 01742 case DW_TAG_lexical_block: 01743 dwarf2_parse_subprogram_block(subpgm, block, child); 01744 break; 01745 case DW_TAG_inlined_subroutine: 01746 dwarf2_parse_inlined_subroutine(subpgm, block, child); 01747 break; 01748 case DW_TAG_label: 01749 dwarf2_parse_subprogram_label(subpgm, child); 01750 break; 01751 case DW_TAG_GNU_call_site: 01752 /* this isn't properly supported by dbghelp interface. skip it for now */ 01753 break; 01754 default: 01755 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", 01756 child->abbrev->tag, dwarf2_debug_ctx(subpgm->ctx), 01757 dwarf2_debug_di(di)); 01758 } 01759 } 01760 symt_close_func_block(subpgm->ctx->module, subpgm->func, block, 0); 01761 } 01762 01763 static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, 01764 struct symt_block* parent_block, 01765 dwarf2_debug_info_t* di) 01766 { 01767 struct symt_block* block; 01768 unsigned long low_pc, high_pc; 01769 struct vector* children; 01770 dwarf2_debug_info_t*child; 01771 unsigned int i; 01772 01773 TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); 01774 01775 if (!dwarf2_read_range(subpgm->ctx, di, &low_pc, &high_pc)) 01776 { 01777 FIXME("no range\n"); 01778 return; 01779 } 01780 01781 block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block, 01782 subpgm->ctx->load_offset + low_pc - subpgm->func->address, 01783 high_pc - low_pc); 01784 01785 children = dwarf2_get_di_children(subpgm->ctx, di); 01786 if (children) for (i = 0; i < vector_length(children); i++) 01787 { 01788 child = *(dwarf2_debug_info_t**)vector_at(children, i); 01789 01790 switch (child->abbrev->tag) 01791 { 01792 case DW_TAG_inlined_subroutine: 01793 dwarf2_parse_inlined_subroutine(subpgm, block, child); 01794 break; 01795 case DW_TAG_variable: 01796 dwarf2_parse_variable(subpgm, block, child); 01797 break; 01798 case DW_TAG_lexical_block: 01799 dwarf2_parse_subprogram_block(subpgm, block, child); 01800 break; 01801 case DW_TAG_subprogram: 01802 /* FIXME: likely a declaration (to be checked) 01803 * skip it for now 01804 */ 01805 break; 01806 case DW_TAG_formal_parameter: 01807 /* FIXME: likely elements for exception handling (GCC flavor) 01808 * Skip it for now 01809 */ 01810 break; 01811 case DW_TAG_imported_module: 01812 /* C++ stuff to be silenced (for now) */ 01813 break; 01814 case DW_TAG_GNU_call_site: 01815 /* this isn't properly supported by dbghelp interface. skip it for now */ 01816 break; 01817 case DW_TAG_label: 01818 dwarf2_parse_subprogram_label(subpgm, child); 01819 break; 01820 case DW_TAG_class_type: 01821 case DW_TAG_structure_type: 01822 case DW_TAG_union_type: 01823 case DW_TAG_enumeration_type: 01824 case DW_TAG_typedef: 01825 /* the type referred to will be loaded when we need it, so skip it */ 01826 break; 01827 default: 01828 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", 01829 child->abbrev->tag, dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); 01830 } 01831 } 01832 01833 symt_close_func_block(subpgm->ctx->module, subpgm->func, block, 0); 01834 } 01835 01836 static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, 01837 dwarf2_debug_info_t* di) 01838 { 01839 struct attribute name; 01840 unsigned long low_pc, high_pc; 01841 struct attribute is_decl; 01842 struct attribute inline_flags; 01843 struct symt* ret_type; 01844 struct symt_function_signature* sig_type; 01845 dwarf2_subprogram_t subpgm; 01846 struct vector* children; 01847 dwarf2_debug_info_t* child; 01848 unsigned int i; 01849 01850 if (di->symt) return di->symt; 01851 01852 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01853 01854 if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) 01855 { 01856 WARN("No name for function... dropping function\n"); 01857 return NULL; 01858 } 01859 /* if it's an abstract representation of an inline function, there should be 01860 * a concrete object that we'll handle 01861 */ 01862 if (dwarf2_find_attribute(ctx, di, DW_AT_inline, &inline_flags) && 01863 inline_flags.u.uvalue != DW_INL_not_inlined) 01864 { 01865 TRACE("Function %s declared as inlined (%ld)... skipping\n", 01866 name.u.string ? name.u.string : "(null)", inline_flags.u.uvalue); 01867 return NULL; 01868 } 01869 01870 if (dwarf2_find_attribute(ctx, di, DW_AT_declaration, &is_decl) && 01871 is_decl.u.uvalue && is_decl.gotten_from == attr_direct) 01872 { 01873 /* it's a real declaration, skip it */ 01874 return NULL; 01875 } 01876 if (!dwarf2_read_range(ctx, di, &low_pc, &high_pc)) 01877 { 01878 WARN("cannot get range for %s\n", name.u.string); 01879 return NULL; 01880 } 01881 /* As functions (defined as inline assembly) get debug info with dwarf 01882 * (not the case for stabs), we just drop Wine's thunks here... 01883 * Actual thunks will be created in elf_module from the symbol table 01884 */ 01885 if (elf_is_in_thunk_area(ctx->load_offset + low_pc, ctx->thunks) >= 0) 01886 return NULL; 01887 if (!(ret_type = dwarf2_lookup_type(ctx, di))) 01888 { 01889 ret_type = ctx->symt_cache[sc_void]; 01890 assert(ret_type); 01891 } 01892 /* FIXME: assuming C source code */ 01893 sig_type = symt_new_function_signature(ctx->module, ret_type, CV_CALL_FAR_C); 01894 subpgm.func = symt_new_function(ctx->module, ctx->compiland, 01895 dwarf2_get_cpp_name(ctx, di, name.u.string), 01896 ctx->load_offset + low_pc, high_pc - low_pc, 01897 &sig_type->symt); 01898 di->symt = &subpgm.func->symt; 01899 subpgm.ctx = ctx; 01900 if (!dwarf2_compute_location_attr(ctx, di, DW_AT_frame_base, 01901 &subpgm.frame, NULL)) 01902 { 01903 /* on stack !! */ 01904 subpgm.frame.kind = loc_regrel; 01905 subpgm.frame.reg = dbghelp_current_cpu->frame_regno; 01906 subpgm.frame.offset = 0; 01907 } 01908 subpgm.non_computed_variable = FALSE; 01909 01910 children = dwarf2_get_di_children(ctx, di); 01911 if (children) for (i = 0; i < vector_length(children); i++) 01912 { 01913 child = *(dwarf2_debug_info_t**)vector_at(children, i); 01914 01915 switch (child->abbrev->tag) 01916 { 01917 case DW_TAG_variable: 01918 case DW_TAG_formal_parameter: 01919 dwarf2_parse_variable(&subpgm, NULL, child); 01920 break; 01921 case DW_TAG_lexical_block: 01922 dwarf2_parse_subprogram_block(&subpgm, NULL, child); 01923 break; 01924 case DW_TAG_inlined_subroutine: 01925 dwarf2_parse_inlined_subroutine(&subpgm, NULL, child); 01926 break; 01927 case DW_TAG_subprogram: 01928 /* FIXME: likely a declaration (to be checked) 01929 * skip it for now 01930 */ 01931 break; 01932 case DW_TAG_label: 01933 dwarf2_parse_subprogram_label(&subpgm, child); 01934 break; 01935 case DW_TAG_class_type: 01936 case DW_TAG_structure_type: 01937 case DW_TAG_union_type: 01938 case DW_TAG_enumeration_type: 01939 case DW_TAG_typedef: 01940 /* the type referred to will be loaded when we need it, so skip it */ 01941 break; 01942 case DW_TAG_unspecified_parameters: 01943 case DW_TAG_template_type_param: 01944 case DW_TAG_template_value_param: 01945 case DW_TAG_GNU_call_site: 01946 /* FIXME: no support in dbghelp's internals so far */ 01947 break; 01948 default: 01949 FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", 01950 child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01951 } 01952 } 01953 01954 if (subpgm.non_computed_variable || subpgm.frame.kind >= loc_user) 01955 { 01956 symt_add_function_point(ctx->module, subpgm.func, SymTagCustom, 01957 &subpgm.frame, NULL); 01958 } 01959 if (subpgm.func) symt_normalize_function(subpgm.ctx->module, subpgm.func); 01960 01961 return di->symt; 01962 } 01963 01964 static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx, 01965 dwarf2_debug_info_t* di) 01966 { 01967 struct symt* ret_type; 01968 struct symt_function_signature* sig_type; 01969 struct vector* children; 01970 dwarf2_debug_info_t* child; 01971 unsigned int i; 01972 01973 if (di->symt) return di->symt; 01974 01975 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 01976 01977 if (!(ret_type = dwarf2_lookup_type(ctx, di))) 01978 { 01979 ret_type = ctx->symt_cache[sc_void]; 01980 assert(ret_type); 01981 } 01982 01983 /* FIXME: assuming C source code */ 01984 sig_type = symt_new_function_signature(ctx->module, ret_type, CV_CALL_FAR_C); 01985 01986 children = dwarf2_get_di_children(ctx, di); 01987 if (children) for (i = 0; i < vector_length(children); i++) 01988 { 01989 child = *(dwarf2_debug_info_t**)vector_at(children, i); 01990 01991 switch (child->abbrev->tag) 01992 { 01993 case DW_TAG_formal_parameter: 01994 symt_add_function_signature_parameter(ctx->module, sig_type, 01995 dwarf2_lookup_type(ctx, child)); 01996 break; 01997 case DW_TAG_unspecified_parameters: 01998 WARN("Unsupported unspecified parameters\n"); 01999 break; 02000 } 02001 } 02002 02003 return di->symt = &sig_type->symt; 02004 } 02005 02006 static void dwarf2_parse_namespace(dwarf2_parse_context_t* ctx, 02007 dwarf2_debug_info_t* di) 02008 { 02009 struct vector* children; 02010 dwarf2_debug_info_t* child; 02011 unsigned int i; 02012 02013 if (di->symt) return; 02014 02015 TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); 02016 02017 di->symt = ctx->symt_cache[sc_void]; 02018 02019 children = dwarf2_get_di_children(ctx, di); 02020 if (children) for (i = 0; i < vector_length(children); i++) 02021 { 02022 child = *(dwarf2_debug_info_t**)vector_at(children, i); 02023 dwarf2_load_one_entry(ctx, child); 02024 } 02025 } 02026 02027 static void dwarf2_load_one_entry(dwarf2_parse_context_t* ctx, 02028 dwarf2_debug_info_t* di) 02029 { 02030 switch (di->abbrev->tag) 02031 { 02032 case DW_TAG_typedef: 02033 dwarf2_parse_typedef(ctx, di); 02034 break; 02035 case DW_TAG_base_type: 02036 dwarf2_parse_base_type(ctx, di); 02037 break; 02038 case DW_TAG_pointer_type: 02039 dwarf2_parse_pointer_type(ctx, di); 02040 break; 02041 case DW_TAG_class_type: 02042 dwarf2_parse_udt_type(ctx, di, UdtClass); 02043 break; 02044 case DW_TAG_structure_type: 02045 dwarf2_parse_udt_type(ctx, di, UdtStruct); 02046 break; 02047 case DW_TAG_union_type: 02048 dwarf2_parse_udt_type(ctx, di, UdtUnion); 02049 break; 02050 case DW_TAG_array_type: 02051 dwarf2_parse_array_type(ctx, di); 02052 break; 02053 case DW_TAG_const_type: 02054 dwarf2_parse_const_type(ctx, di); 02055 break; 02056 case DW_TAG_volatile_type: 02057 dwarf2_parse_volatile_type(ctx, di); 02058 break; 02059 case DW_TAG_reference_type: 02060 dwarf2_parse_reference_type(ctx, di); 02061 break; 02062 case DW_TAG_enumeration_type: 02063 dwarf2_parse_enumeration_type(ctx, di); 02064 break; 02065 case DW_TAG_subprogram: 02066 dwarf2_parse_subprogram(ctx, di); 02067 break; 02068 case DW_TAG_subroutine_type: 02069 dwarf2_parse_subroutine_type(ctx, di); 02070 break; 02071 case DW_TAG_variable: 02072 { 02073 dwarf2_subprogram_t subpgm; 02074 02075 subpgm.ctx = ctx; 02076 subpgm.func = NULL; 02077 subpgm.frame.kind = loc_absolute; 02078 subpgm.frame.offset = 0; 02079 subpgm.frame.reg = Wine_DW_no_register; 02080 dwarf2_parse_variable(&subpgm, NULL, di); 02081 } 02082 break; 02083 case DW_TAG_namespace: 02084 dwarf2_parse_namespace(ctx, di); 02085 break; 02086 /* silence a couple of C++ defines */ 02087 case DW_TAG_imported_module: 02088 case DW_TAG_imported_declaration: 02089 case DW_TAG_ptr_to_member_type: 02090 break; 02091 default: 02092 FIXME("Unhandled Tag type 0x%lx at %s, for %lu\n", 02093 di->abbrev->tag, dwarf2_debug_ctx(ctx), di->abbrev->entry_code); 02094 } 02095 } 02096 02097 static void dwarf2_set_line_number(struct module* module, unsigned long address, 02098 const struct vector* v, unsigned file, unsigned line) 02099 { 02100 struct symt_function* func; 02101 struct symt_ht* symt; 02102 unsigned* psrc; 02103 02104 if (!file || !(psrc = vector_at(v, file - 1))) return; 02105 02106 TRACE("%s %lx %s %u\n", 02107 debugstr_w(module->module.ModuleName), address, source_get(module, *psrc), line); 02108 if (!(symt = symt_find_nearest(module, address)) || 02109 symt->symt.tag != SymTagFunction) return; 02110 func = (struct symt_function*)symt; 02111 symt_add_func_line(module, func, *psrc, line, address - func->address); 02112 } 02113 02114 static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, 02115 dwarf2_parse_context_t* ctx, 02116 const char* compile_dir, 02117 unsigned long offset) 02118 { 02119 dwarf2_traverse_context_t traverse; 02120 unsigned long length; 02121 unsigned insn_size, default_stmt; 02122 unsigned line_range, opcode_base; 02123 int line_base; 02124 const unsigned char* opcode_len; 02125 struct vector dirs; 02126 struct vector files; 02127 const char** p; 02128 02129 /* section with line numbers stripped */ 02130 if (sections[section_line].address == IMAGE_NO_MAP) 02131 return FALSE; 02132 02133 if (offset + 4 > sections[section_line].size) 02134 { 02135 WARN("out of bounds offset\n"); 02136 return FALSE; 02137 } 02138 traverse.data = sections[section_line].address + offset; 02139 traverse.end_data = traverse.data + 4; 02140 traverse.word_size = ctx->module->format_info[DFI_DWARF]->u.dwarf2_info->word_size; 02141 02142 length = dwarf2_parse_u4(&traverse); 02143 traverse.end_data = sections[section_line].address + offset + length; 02144 02145 if (offset + 4 + length > sections[section_line].size) 02146 { 02147 WARN("out of bounds header\n"); 02148 return FALSE; 02149 } 02150 dwarf2_parse_u2(&traverse); /* version */ 02151 dwarf2_parse_u4(&traverse); /* header_len */ 02152 insn_size = dwarf2_parse_byte(&traverse); 02153 default_stmt = dwarf2_parse_byte(&traverse); 02154 line_base = (signed char)dwarf2_parse_byte(&traverse); 02155 line_range = dwarf2_parse_byte(&traverse); 02156 opcode_base = dwarf2_parse_byte(&traverse); 02157 02158 opcode_len = traverse.data; 02159 traverse.data += opcode_base - 1; 02160 02161 vector_init(&dirs, sizeof(const char*), 4); 02162 p = vector_add(&dirs, &ctx->pool); 02163 *p = compile_dir ? compile_dir : "."; 02164 while (*traverse.data) 02165 { 02166 const char* rel = (const char*)traverse.data; 02167 unsigned rellen = strlen(rel); 02168 TRACE("Got include %s\n", rel); 02169 traverse.data += rellen + 1; 02170 p = vector_add(&dirs, &ctx->pool); 02171 02172 if (*rel == '/' || !compile_dir) 02173 *p = rel; 02174 else 02175 { 02176 /* include directory relative to compile directory */ 02177 unsigned baselen = strlen(compile_dir); 02178 char* tmp = pool_alloc(&ctx->pool, baselen + 1 + rellen + 1); 02179 strcpy(tmp, compile_dir); 02180 if (tmp[baselen - 1] != '/') tmp[baselen++] = '/'; 02181 strcpy(&tmp[baselen], rel); 02182 *p = tmp; 02183 } 02184 02185 } 02186 traverse.data++; 02187 02188 vector_init(&files, sizeof(unsigned), 16); 02189 while (*traverse.data) 02190 { 02191 unsigned int dir_index, mod_time, length; 02192 const char* name; 02193 const char* dir; 02194 unsigned* psrc; 02195 02196 name = (const char*)traverse.data; 02197 traverse.data += strlen(name) + 1; 02198 dir_index = dwarf2_leb128_as_unsigned(&traverse); 02199 mod_time = dwarf2_leb128_as_unsigned(&traverse); 02200 length = dwarf2_leb128_as_unsigned(&traverse); 02201 dir = *(const char**)vector_at(&dirs, dir_index); 02202 TRACE("Got file %s/%s (%u,%u)\n", dir, name, mod_time, length); 02203 psrc = vector_add(&files, &ctx->pool); 02204 *psrc = source_new(ctx->module, dir, name); 02205 } 02206 traverse.data++; 02207 02208 while (traverse.data < traverse.end_data) 02209 { 02210 unsigned long address = 0; 02211 unsigned file = 1; 02212 unsigned line = 1; 02213 unsigned is_stmt = default_stmt; 02214 BOOL end_sequence = FALSE; 02215 unsigned opcode, extopcode, i; 02216 02217 while (!end_sequence) 02218 { 02219 opcode = dwarf2_parse_byte(&traverse); 02220 TRACE("Got opcode %x\n", opcode); 02221 02222 if (opcode >= opcode_base) 02223 { 02224 unsigned delta = opcode - opcode_base; 02225 02226 address += (delta / line_range) * insn_size; 02227 line += line_base + (delta % line_range); 02228 dwarf2_set_line_number(ctx->module, address, &files, file, line); 02229 } 02230 else 02231 { 02232 switch (opcode) 02233 { 02234 case DW_LNS_copy: 02235 dwarf2_set_line_number(ctx->module, address, &files, file, line); 02236 break; 02237 case DW_LNS_advance_pc: 02238 address += insn_size * dwarf2_leb128_as_unsigned(&traverse); 02239 break; 02240 case DW_LNS_advance_line: 02241 line += dwarf2_leb128_as_signed(&traverse); 02242 break; 02243 case DW_LNS_set_file: 02244 file = dwarf2_leb128_as_unsigned(&traverse); 02245 break; 02246 case DW_LNS_set_column: 02247 dwarf2_leb128_as_unsigned(&traverse); 02248 break; 02249 case DW_LNS_negate_stmt: 02250 is_stmt = !is_stmt; 02251 break; 02252 case DW_LNS_set_basic_block: 02253 break; 02254 case DW_LNS_const_add_pc: 02255 address += ((255 - opcode_base) / line_range) * insn_size; 02256 break; 02257 case DW_LNS_fixed_advance_pc: 02258 address += dwarf2_parse_u2(&traverse); 02259 break; 02260 case DW_LNS_extended_op: 02261 dwarf2_leb128_as_unsigned(&traverse); 02262 extopcode = dwarf2_parse_byte(&traverse); 02263 switch (extopcode) 02264 { 02265 case DW_LNE_end_sequence: 02266 dwarf2_set_line_number(ctx->module, address, &files, file, line); 02267 end_sequence = TRUE; 02268 break; 02269 case DW_LNE_set_address: 02270 address = ctx->load_offset + dwarf2_parse_addr(&traverse); 02271 break; 02272 case DW_LNE_define_file: 02273 FIXME("not handled %s\n", traverse.data); 02274 traverse.data += strlen((const char *)traverse.data) + 1; 02275 dwarf2_leb128_as_unsigned(&traverse); 02276 dwarf2_leb128_as_unsigned(&traverse); 02277 dwarf2_leb128_as_unsigned(&traverse); 02278 break; 02279 case DW_LNE_set_discriminator: 02280 WARN("not handled %s\n", traverse.data); 02281 dwarf2_leb128_as_unsigned(&traverse); 02282 break; 02283 default: 02284 FIXME("Unsupported extended opcode %x\n", extopcode); 02285 break; 02286 } 02287 break; 02288 default: 02289 WARN("Unsupported opcode %x\n", opcode); 02290 for (i = 0; i < opcode_len[opcode]; i++) 02291 dwarf2_leb128_as_unsigned(&traverse); 02292 break; 02293 } 02294 } 02295 } 02296 } 02297 return TRUE; 02298 } 02299 02300 static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, 02301 struct module* module, 02302 const struct elf_thunk_area* thunks, 02303 dwarf2_traverse_context_t* mod_ctx, 02304 unsigned long load_offset) 02305 { 02306 dwarf2_parse_context_t ctx; 02307 dwarf2_traverse_context_t abbrev_ctx; 02308 dwarf2_debug_info_t* di; 02309 dwarf2_traverse_context_t cu_ctx; 02310 const unsigned char* comp_unit_start = mod_ctx->data; 02311 unsigned long cu_length; 02312 unsigned short cu_version; 02313 unsigned long cu_abbrev_offset; 02314 BOOL ret = FALSE; 02315 02316 cu_length = dwarf2_parse_u4(mod_ctx); 02317 cu_ctx.data = mod_ctx->data; 02318 cu_ctx.end_data = mod_ctx->data + cu_length; 02319 mod_ctx->data += cu_length; 02320 cu_version = dwarf2_parse_u2(&cu_ctx); 02321 cu_abbrev_offset = dwarf2_parse_u4(&cu_ctx); 02322 cu_ctx.word_size = dwarf2_parse_byte(&cu_ctx); 02323 02324 TRACE("Compilation Unit Header found at 0x%x:\n", 02325 (int)(comp_unit_start - sections[section_debug].address)); 02326 TRACE("- length: %lu\n", cu_length); 02327 TRACE("- version: %u\n", cu_version); 02328 TRACE("- abbrev_offset: %lu\n", cu_abbrev_offset); 02329 TRACE("- word_size: %u\n", cu_ctx.word_size); 02330 02331 if (cu_version != 2) 02332 { 02333 WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", 02334 cu_version); 02335 return FALSE; 02336 } 02337 02338 module->format_info[DFI_DWARF]->u.dwarf2_info->word_size = cu_ctx.word_size; 02339 mod_ctx->word_size = cu_ctx.word_size; 02340 02341 pool_init(&ctx.pool, 65536); 02342 ctx.sections = sections; 02343 ctx.section = section_debug; 02344 ctx.module = module; 02345 ctx.thunks = thunks; 02346 ctx.load_offset = load_offset; 02347 ctx.ref_offset = comp_unit_start - sections[section_debug].address; 02348 memset(ctx.symt_cache, 0, sizeof(ctx.symt_cache)); 02349 ctx.symt_cache[sc_void] = &symt_new_basic(module, btVoid, "void", 0)->symt; 02350 ctx.cpp_name = NULL; 02351 02352 abbrev_ctx.data = sections[section_abbrev].address + cu_abbrev_offset; 02353 abbrev_ctx.end_data = sections[section_abbrev].address + sections[section_abbrev].size; 02354 abbrev_ctx.word_size = cu_ctx.word_size; 02355 dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool); 02356 02357 sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128); 02358 dwarf2_read_one_debug_info(&ctx, &cu_ctx, NULL, &di); 02359 02360 if (di->abbrev->tag == DW_TAG_compile_unit) 02361 { 02362 struct attribute name; 02363 struct vector* children; 02364 dwarf2_debug_info_t* child = NULL; 02365 unsigned int i; 02366 struct attribute stmt_list, low_pc; 02367 struct attribute comp_dir; 02368 02369 if (!dwarf2_find_attribute(&ctx, di, DW_AT_name, &name)) 02370 name.u.string = NULL; 02371 02372 /* get working directory of current compilation unit */ 02373 if (!dwarf2_find_attribute(&ctx, di, DW_AT_comp_dir, &comp_dir)) 02374 comp_dir.u.string = NULL; 02375 02376 if (!dwarf2_find_attribute(&ctx, di, DW_AT_low_pc, &low_pc)) 02377 low_pc.u.uvalue = 0; 02378 ctx.compiland = symt_new_compiland(module, ctx.load_offset + low_pc.u.uvalue, 02379 source_new(module, comp_dir.u.string, name.u.string)); 02380 di->symt = &ctx.compiland->symt; 02381 children = dwarf2_get_di_children(&ctx, di); 02382 if (children) for (i = 0; i < vector_length(children); i++) 02383 { 02384 child = *(dwarf2_debug_info_t**)vector_at(children, i); 02385 dwarf2_load_one_entry(&ctx, child); 02386 } 02387 if (dwarf2_find_attribute(&ctx, di, DW_AT_stmt_list, &stmt_list)) 02388 { 02389 if (dwarf2_parse_line_numbers(sections, &ctx, comp_dir.u.string, stmt_list.u.uvalue)) 02390 module->module.LineNumbers = TRUE; 02391 } 02392 ret = TRUE; 02393 } 02394 else FIXME("Should have a compilation unit here\n"); 02395 pool_destroy(&ctx.pool); 02396 return ret; 02397 } 02398 02399 static BOOL dwarf2_lookup_loclist(const struct module_format* modfmt, const BYTE* start, 02400 unsigned long ip, dwarf2_traverse_context_t* lctx) 02401 { 02402 DWORD_PTR beg, end; 02403 const BYTE* ptr = start; 02404 DWORD len; 02405 02406 while (ptr < modfmt->u.dwarf2_info->debug_loc.address + modfmt->u.dwarf2_info->debug_loc.size) 02407 { 02408 beg = dwarf2_get_addr(ptr, modfmt->u.dwarf2_info->word_size); ptr += modfmt->u.dwarf2_info->word_size; 02409 end = dwarf2_get_addr(ptr, modfmt->u.dwarf2_info->word_size); ptr += modfmt->u.dwarf2_info->word_size; 02410 if (!beg && !end) break; 02411 len = dwarf2_get_u2(ptr); ptr += 2; 02412 02413 if (beg <= ip && ip < end) 02414 { 02415 lctx->data = ptr; 02416 lctx->end_data = ptr + len; 02417 lctx->word_size = modfmt->u.dwarf2_info->word_size; 02418 return TRUE; 02419 } 02420 ptr += len; 02421 } 02422 WARN("Couldn't find ip in location list\n"); 02423 return FALSE; 02424 } 02425 02426 static enum location_error loc_compute_frame(struct process* pcs, 02427 const struct module_format* modfmt, 02428 const struct symt_function* func, 02429 DWORD_PTR ip, struct location* frame) 02430 { 02431 struct symt** psym = NULL; 02432 struct location* pframe; 02433 dwarf2_traverse_context_t lctx; 02434 enum location_error err; 02435 unsigned int i; 02436 02437 for (i=0; i<vector_length(&func->vchildren); i++) 02438 { 02439 psym = vector_at(&func->vchildren, i); 02440 if ((*psym)->tag == SymTagCustom) 02441 { 02442 pframe = &((struct symt_hierarchy_point*)*psym)->loc; 02443 02444 /* First, recompute the frame information, if needed */ 02445 switch (pframe->kind) 02446 { 02447 case loc_regrel: 02448 case loc_register: 02449 *frame = *pframe; 02450 break; 02451 case loc_dwarf2_location_list: 02452 WARN("Searching loclist for %s\n", func->hash_elt.name); 02453 if (!dwarf2_lookup_loclist(modfmt, 02454 modfmt->u.dwarf2_info->debug_loc.address + pframe->offset, 02455 ip, &lctx)) 02456 return loc_err_out_of_scope; 02457 if ((err = compute_location(&lctx, frame, pcs->handle, NULL)) < 0) return err; 02458 if (frame->kind >= loc_user) 02459 { 02460 WARN("Couldn't compute runtime frame location\n"); 02461 return loc_err_too_complex; 02462 } 02463 break; 02464 default: 02465 WARN("Unsupported frame kind %d\n", pframe->kind); 02466 return loc_err_internal; 02467 } 02468 return 0; 02469 } 02470 } 02471 WARN("Couldn't find Custom function point, whilst location list offset is searched\n"); 02472 return loc_err_internal; 02473 } 02474 02475 enum reg_rule 02476 { 02477 RULE_UNSET, /* not set at all */ 02478 RULE_UNDEFINED, /* undefined value */ 02479 RULE_SAME, /* same value as previous frame */ 02480 RULE_CFA_OFFSET, /* stored at cfa offset */ 02481 RULE_OTHER_REG, /* stored in other register */ 02482 RULE_EXPRESSION, /* address specified by expression */ 02483 RULE_VAL_EXPRESSION /* value specified by expression */ 02484 }; 02485 02486 /* make it large enough for all CPUs */ 02487 #define NB_FRAME_REGS 64 02488 #define MAX_SAVED_STATES 16 02489 02490 struct frame_state 02491 { 02492 ULONG_PTR cfa_offset; 02493 unsigned char cfa_reg; 02494 enum reg_rule cfa_rule; 02495 enum reg_rule rules[NB_FRAME_REGS]; 02496 ULONG_PTR regs[NB_FRAME_REGS]; 02497 }; 02498 02499 struct frame_info 02500 { 02501 ULONG_PTR ip; 02502 ULONG_PTR code_align; 02503 LONG_PTR data_align; 02504 unsigned char retaddr_reg; 02505 unsigned char fde_encoding; 02506 unsigned char lsda_encoding; 02507 unsigned char signal_frame; 02508 unsigned char aug_z_format; 02509 unsigned char state_sp; 02510 struct frame_state state; 02511 struct frame_state state_stack[MAX_SAVED_STATES]; 02512 }; 02513 02514 static ULONG_PTR dwarf2_parse_augmentation_ptr(dwarf2_traverse_context_t* ctx, unsigned char encoding) 02515 { 02516 ULONG_PTR base; 02517 02518 if (encoding == DW_EH_PE_omit) return 0; 02519 02520 switch (encoding & 0xf0) 02521 { 02522 case DW_EH_PE_abs: 02523 base = 0; 02524 break; 02525 case DW_EH_PE_pcrel: 02526 base = (ULONG_PTR)ctx->data; 02527 break; 02528 default: 02529 FIXME("unsupported encoding %02x\n", encoding); 02530 return 0; 02531 } 02532 02533 switch (encoding & 0x0f) 02534 { 02535 case DW_EH_PE_native: 02536 return base + dwarf2_parse_addr(ctx); 02537 case DW_EH_PE_leb128: 02538 return base + dwarf2_leb128_as_unsigned(ctx); 02539 case DW_EH_PE_data2: 02540 return base + dwarf2_parse_u2(ctx); 02541 case DW_EH_PE_data4: 02542 return base + dwarf2_parse_u4(ctx); 02543 case DW_EH_PE_data8: 02544 return base + dwarf2_parse_u8(ctx); 02545 case DW_EH_PE_signed|DW_EH_PE_leb128: 02546 return base + dwarf2_leb128_as_signed(ctx); 02547 case DW_EH_PE_signed|DW_EH_PE_data2: 02548 return base + (signed short)dwarf2_parse_u2(ctx); 02549 case DW_EH_PE_signed|DW_EH_PE_data4: 02550 return base + (signed int)dwarf2_parse_u4(ctx); 02551 case DW_EH_PE_signed|DW_EH_PE_data8: 02552 return base + (LONG64)dwarf2_parse_u8(ctx); 02553 default: 02554 FIXME("unsupported encoding %02x\n", encoding); 02555 return 0; 02556 } 02557 } 02558 02559 static BOOL parse_cie_details(dwarf2_traverse_context_t* ctx, struct frame_info* info) 02560 { 02561 unsigned char version; 02562 const char* augmentation; 02563 const unsigned char* end; 02564 ULONG_PTR len; 02565 02566 memset(info, 0, sizeof(*info)); 02567 info->lsda_encoding = DW_EH_PE_omit; 02568 info->aug_z_format = 0; 02569 02570 /* parse the CIE first */ 02571 version = dwarf2_parse_byte(ctx); 02572 if (version != 1) 02573 { 02574 FIXME("unknown CIE version %u at %p\n", version, ctx->data - 1); 02575 return FALSE; 02576 } 02577 augmentation = (const char*)ctx->data; 02578 ctx->data += strlen(augmentation) + 1; 02579 02580 info->code_align = dwarf2_leb128_as_unsigned(ctx); 02581 info->data_align = dwarf2_leb128_as_signed(ctx); 02582 info->retaddr_reg = dwarf2_parse_byte(ctx); 02583 info->state.cfa_rule = RULE_CFA_OFFSET; 02584 02585 end = NULL; 02586 TRACE("\tparsing augmentation %s\n", augmentation); 02587 if (*augmentation) do 02588 { 02589 switch (*augmentation) 02590 { 02591 case 'z': 02592 len = dwarf2_leb128_as_unsigned(ctx); 02593 end = ctx->data + len; 02594 info->aug_z_format = 1; 02595 continue; 02596 case 'L': 02597 info->lsda_encoding = dwarf2_parse_byte(ctx); 02598 continue; 02599 case 'P': 02600 { 02601 unsigned char encoding = dwarf2_parse_byte(ctx); 02602 /* throw away the indirect bit, as we don't care for the result */ 02603 encoding &= ~DW_EH_PE_indirect; 02604 dwarf2_parse_augmentation_ptr(ctx, encoding); /* handler */ 02605 continue; 02606 } 02607 case 'R': 02608 info->fde_encoding = dwarf2_parse_byte(ctx); 02609 continue; 02610 case 'S': 02611 info->signal_frame = 1; 02612 continue; 02613 } 02614 FIXME("unknown augmentation '%c'\n", *augmentation); 02615 if (!end) return FALSE; 02616 break; 02617 } while (*++augmentation); 02618 if (end) ctx->data = end; 02619 return TRUE; 02620 } 02621 02622 static BOOL dwarf2_get_cie(unsigned long addr, struct module* module, DWORD_PTR delta, 02623 dwarf2_traverse_context_t* fde_ctx, dwarf2_traverse_context_t* cie_ctx, 02624 struct frame_info* info, BOOL in_eh_frame) 02625 { 02626 const unsigned char* ptr_blk; 02627 const unsigned char* cie_ptr; 02628 const unsigned char* last_cie_ptr = (const unsigned char*)~0; 02629 unsigned len, id; 02630 unsigned long start, range; 02631 unsigned cie_id; 02632 const BYTE* start_data = fde_ctx->data; 02633 02634 cie_id = in_eh_frame ? 0 : DW_CIE_ID; 02635 for (; fde_ctx->data + 2 * 4 < fde_ctx->end_data; fde_ctx->data = ptr_blk) 02636 { 02637 /* find the FDE for address addr (skip CIE) */ 02638 len = dwarf2_parse_u4(fde_ctx); 02639 if (len == 0xffffffff) FIXME("Unsupported yet 64-bit CIEs\n"); 02640 ptr_blk = fde_ctx->data + len; 02641 id = dwarf2_parse_u4(fde_ctx); 02642 if (id == cie_id) 02643 { 02644 last_cie_ptr = fde_ctx->data - 8; 02645 /* we need some bits out of the CIE in order to parse all contents */ 02646 if (!parse_cie_details(fde_ctx, info)) return FALSE; 02647 cie_ctx->data = fde_ctx->data; 02648 cie_ctx->end_data = ptr_blk; 02649 cie_ctx->word_size = fde_ctx->word_size; 02650 continue; 02651 } 02652 cie_ptr = (in_eh_frame) ? fde_ctx->data - id - 4 : start_data + id; 02653 if (cie_ptr != last_cie_ptr) 02654 { 02655 last_cie_ptr = cie_ptr; 02656 cie_ctx->data = cie_ptr; 02657 cie_ctx->word_size = fde_ctx->word_size; 02658 cie_ctx->end_data = cie_ptr + 4; 02659 cie_ctx->end_data = cie_ptr + 4 + dwarf2_parse_u4(cie_ctx); 02660 if (dwarf2_parse_u4(cie_ctx) != cie_id) 02661 { 02662 FIXME("wrong CIE pointer\n"); 02663 return FALSE; 02664 } 02665 if (!parse_cie_details(cie_ctx, info)) return FALSE; 02666 } 02667 start = delta + dwarf2_parse_augmentation_ptr(fde_ctx, info->fde_encoding); 02668 range = dwarf2_parse_augmentation_ptr(fde_ctx, info->fde_encoding & 0x0F); 02669 02670 if (addr >= start && addr < start + range) 02671 { 02672 /* reset the FDE context */ 02673 fde_ctx->end_data = ptr_blk; 02674 02675 info->ip = start; 02676 return TRUE; 02677 } 02678 } 02679 return FALSE; 02680 } 02681 02682 static int valid_reg(ULONG_PTR reg) 02683 { 02684 if (reg >= NB_FRAME_REGS) FIXME("unsupported reg %lx\n", reg); 02685 return (reg < NB_FRAME_REGS); 02686 } 02687 02688 static void execute_cfa_instructions(dwarf2_traverse_context_t* ctx, 02689 ULONG_PTR last_ip, struct frame_info *info) 02690 { 02691 while (ctx->data < ctx->end_data && info->ip <= last_ip + info->signal_frame) 02692 { 02693 enum dwarf_call_frame_info op = dwarf2_parse_byte(ctx); 02694 02695 if (op & 0xc0) 02696 { 02697 switch (op & 0xc0) 02698 { 02699 case DW_CFA_advance_loc: 02700 { 02701 ULONG_PTR offset = (op & 0x3f) * info->code_align; 02702 TRACE("%lx: DW_CFA_advance_loc %lu\n", info->ip, offset); 02703 info->ip += offset; 02704 break; 02705 } 02706 case DW_CFA_offset: 02707 { 02708 ULONG_PTR reg = op & 0x3f; 02709 LONG_PTR offset = dwarf2_leb128_as_unsigned(ctx) * info->data_align; 02710 if (!valid_reg(reg)) break; 02711 TRACE("%lx: DW_CFA_offset %s, %ld\n", 02712 info->ip, 02713 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)), 02714 offset); 02715 info->state.regs[reg] = offset; 02716 info->state.rules[reg] = RULE_CFA_OFFSET; 02717 break; 02718 } 02719 case DW_CFA_restore: 02720 { 02721 ULONG_PTR reg = op & 0x3f; 02722 if (!valid_reg(reg)) break; 02723 TRACE("%lx: DW_CFA_restore %s\n", 02724 info->ip, 02725 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg))); 02726 info->state.rules[reg] = RULE_UNSET; 02727 break; 02728 } 02729 } 02730 } 02731 else switch (op) 02732 { 02733 case DW_CFA_nop: 02734 break; 02735 case DW_CFA_set_loc: 02736 { 02737 ULONG_PTR loc = dwarf2_parse_augmentation_ptr(ctx, info->fde_encoding); 02738 TRACE("%lx: DW_CFA_set_loc %lx\n", info->ip, loc); 02739 info->ip = loc; 02740 break; 02741 } 02742 case DW_CFA_advance_loc1: 02743 { 02744 ULONG_PTR offset = dwarf2_parse_byte(ctx) * info->code_align; 02745 TRACE("%lx: DW_CFA_advance_loc1 %lu\n", info->ip, offset); 02746 info->ip += offset; 02747 break; 02748 } 02749 case DW_CFA_advance_loc2: 02750 { 02751 ULONG_PTR offset = dwarf2_parse_u2(ctx) * info->code_align; 02752 TRACE("%lx: DW_CFA_advance_loc2 %lu\n", info->ip, offset); 02753 info->ip += offset; 02754 break; 02755 } 02756 case DW_CFA_advance_loc4: 02757 { 02758 ULONG_PTR offset = dwarf2_parse_u4(ctx) * info->code_align; 02759 TRACE("%lx: DW_CFA_advance_loc4 %lu\n", info->ip, offset); 02760 info->ip += offset; 02761 break; 02762 } 02763 case DW_CFA_offset_extended: 02764 case DW_CFA_offset_extended_sf: 02765 { 02766 ULONG_PTR reg = dwarf2_leb128_as_unsigned(ctx); 02767 LONG_PTR offset = (op == DW_CFA_offset_extended) ? dwarf2_leb128_as_unsigned(ctx) * info->data_align 02768 : dwarf2_leb128_as_signed(ctx) * info->data_align; 02769 if (!valid_reg(reg)) break; 02770 TRACE("%lx: DW_CFA_offset_extended %s, %ld\n", 02771 info->ip, 02772 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)), 02773 offset); 02774 info->state.regs[reg] = offset; 02775 info->state.rules[reg] = RULE_CFA_OFFSET; 02776 break; 02777 } 02778 case DW_CFA_restore_extended: 02779 { 02780 ULONG_PTR reg = dwarf2_leb128_as_unsigned(ctx); 02781 if (!valid_reg(reg)) break; 02782 TRACE("%lx: DW_CFA_restore_extended %s\n", 02783 info->ip, 02784 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg))); 02785 info->state.rules[reg] = RULE_UNSET; 02786 break; 02787 } 02788 case DW_CFA_undefined: 02789 { 02790 ULONG_PTR reg = dwarf2_leb128_as_unsigned(ctx); 02791 if (!valid_reg(reg)) break; 02792 TRACE("%lx: DW_CFA_undefined %s\n", 02793 info->ip, 02794 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg))); 02795 info->state.rules[reg] = RULE_UNDEFINED; 02796 break; 02797 } 02798 case DW_CFA_same_value: 02799 { 02800 ULONG_PTR reg = dwarf2_leb128_as_unsigned(ctx); 02801 if (!valid_reg(reg)) break; 02802 TRACE("%lx: DW_CFA_same_value %s\n", 02803 info->ip, 02804 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg))); 02805 info->state.regs[reg] = reg; 02806 info->state.rules[reg] = RULE_SAME; 02807 break; 02808 } 02809 case DW_CFA_register: 02810 { 02811 ULONG_PTR reg = dwarf2_leb128_as_unsigned(ctx); 02812 ULONG_PTR reg2 = dwarf2_leb128_as_unsigned(ctx); 02813 if (!valid_reg(reg) || !valid_reg(reg2)) break; 02814 TRACE("%lx: DW_CFA_register %s == %s\n", 02815 info->ip, 02816 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)), 02817 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg2))); 02818 info->state.regs[reg] = reg2; 02819 info->state.rules[reg] = RULE_OTHER_REG; 02820 break; 02821 } 02822 case DW_CFA_remember_state: 02823 TRACE("%lx: DW_CFA_remember_state\n", info->ip); 02824 if (info->state_sp >= MAX_SAVED_STATES) 02825 FIXME("%lx: DW_CFA_remember_state too many nested saves\n", info->ip); 02826 else 02827 info->state_stack[info->state_sp++] = info->state; 02828 break; 02829 case DW_CFA_restore_state: 02830 TRACE("%lx: DW_CFA_restore_state\n", info->ip); 02831 if (!info->state_sp) 02832 FIXME("%lx: DW_CFA_restore_state without corresponding save\n", info->ip); 02833 else 02834 info->state = info->state_stack[--info->state_sp]; 02835 break; 02836 case DW_CFA_def_cfa: 02837 case DW_CFA_def_cfa_sf: 02838 { 02839 ULONG_PTR reg = dwarf2_leb128_as_unsigned(ctx); 02840 ULONG_PTR offset = (op == DW_CFA_def_cfa) ? dwarf2_leb128_as_unsigned(ctx) 02841 : dwarf2_leb128_as_signed(ctx) * info->data_align; 02842 if (!valid_reg(reg)) break; 02843 TRACE("%lx: DW_CFA_def_cfa %s, %lu\n", 02844 info->ip, 02845 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)), 02846 offset); 02847 info->state.cfa_reg = reg; 02848 info->state.cfa_offset = offset; 02849 info->state.cfa_rule = RULE_CFA_OFFSET; 02850 break; 02851 } 02852 case DW_CFA_def_cfa_register: 02853 { 02854 ULONG_PTR reg = dwarf2_leb128_as_unsigned(ctx); 02855 if (!valid_reg(reg)) break; 02856 TRACE("%lx: DW_CFA_def_cfa_register %s\n", 02857 info->ip, 02858 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg))); 02859 info->state.cfa_reg = reg; 02860 info->state.cfa_rule = RULE_CFA_OFFSET; 02861 break; 02862 } 02863 case DW_CFA_def_cfa_offset: 02864 case DW_CFA_def_cfa_offset_sf: 02865 { 02866 ULONG_PTR offset = (op == DW_CFA_def_cfa_offset) ? dwarf2_leb128_as_unsigned(ctx) 02867 : dwarf2_leb128_as_signed(ctx) * info->data_align; 02868 TRACE("%lx: DW_CFA_def_cfa_offset %lu\n", info->ip, offset); 02869 info->state.cfa_offset = offset; 02870 info->state.cfa_rule = RULE_CFA_OFFSET; 02871 break; 02872 } 02873 case DW_CFA_def_cfa_expression: 02874 { 02875 ULONG_PTR expr = (ULONG_PTR)ctx->data; 02876 ULONG_PTR len = dwarf2_leb128_as_unsigned(ctx); 02877 TRACE("%lx: DW_CFA_def_cfa_expression %lx-%lx\n", info->ip, expr, expr+len); 02878 info->state.cfa_offset = expr; 02879 info->state.cfa_rule = RULE_VAL_EXPRESSION; 02880 ctx->data += len; 02881 break; 02882 } 02883 case DW_CFA_expression: 02884 case DW_CFA_val_expression: 02885 { 02886 ULONG_PTR reg = dwarf2_leb128_as_unsigned(ctx); 02887 ULONG_PTR expr = (ULONG_PTR)ctx->data; 02888 ULONG_PTR len = dwarf2_leb128_as_unsigned(ctx); 02889 if (!valid_reg(reg)) break; 02890 TRACE("%lx: DW_CFA_%sexpression %s %lx-%lx\n", 02891 info->ip, (op == DW_CFA_expression) ? "" : "val_", 02892 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(reg)), 02893 expr, expr + len); 02894 info->state.regs[reg] = expr; 02895 info->state.rules[reg] = (op == DW_CFA_expression) ? RULE_EXPRESSION : RULE_VAL_EXPRESSION; 02896 ctx->data += len; 02897 break; 02898 } 02899 case DW_CFA_GNU_args_size: 02900 /* FIXME: should check that GCC is the compiler for this CU */ 02901 { 02902 ULONG_PTR args = dwarf2_leb128_as_unsigned(ctx); 02903 TRACE("%lx: DW_CFA_GNU_args_size %lu\n", info->ip, args); 02904 /* ignored */ 02905 break; 02906 } 02907 default: 02908 FIXME("%lx: unknown CFA opcode %02x\n", info->ip, op); 02909 break; 02910 } 02911 } 02912 } 02913 02914 /* retrieve a context register from its dwarf number */ 02915 static ULONG_PTR get_context_reg(CONTEXT *context, ULONG_PTR dw_reg) 02916 { 02917 unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg), sz; 02918 ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz); 02919 02920 if (sz != sizeof(ULONG_PTR)) 02921 { 02922 FIXME("reading register %lu/%u of wrong size %u\n", dw_reg, regno, sz); 02923 return 0; 02924 } 02925 return *ptr; 02926 } 02927 02928 /* set a context register from its dwarf number */ 02929 static void set_context_reg(struct cpu_stack_walk* csw, CONTEXT *context, ULONG_PTR dw_reg, 02930 ULONG_PTR val, BOOL isdebuggee) 02931 { 02932 unsigned regno = dbghelp_current_cpu->map_dwarf_register(dw_reg), sz; 02933 ULONG_PTR* ptr = dbghelp_current_cpu->fetch_context_reg(context, regno, &sz); 02934 02935 if (isdebuggee) 02936 { 02937 char tmp[16]; 02938 02939 if (sz > sizeof(tmp)) 02940 { 02941 FIXME("register %lu/%u size is too wide: %u\n", dw_reg, regno, sz); 02942 return; 02943 } 02944 if (!sw_read_mem(csw, val, tmp, sz)) 02945 { 02946 WARN("Couldn't read memory at %p\n", (void*)val); 02947 return; 02948 } 02949 memcpy(ptr, tmp, sz); 02950 } 02951 else 02952 { 02953 if (sz != sizeof(ULONG_PTR)) 02954 { 02955 FIXME("assigning to register %lu/%u of wrong size %u\n", dw_reg, regno, sz); 02956 return; 02957 } 02958 *ptr = val; 02959 } 02960 } 02961 02962 /* copy a register from one context to another using dwarf number */ 02963 static void copy_context_reg(CONTEXT *dstcontext, ULONG_PTR dwregdst, CONTEXT* srccontext, ULONG_PTR dwregsrc) 02964 { 02965 unsigned regdstno = dbghelp_current_cpu->map_dwarf_register(dwregdst), szdst; 02966 unsigned regsrcno = dbghelp_current_cpu->map_dwarf_register(dwregsrc), szsrc; 02967 ULONG_PTR* ptrdst = dbghelp_current_cpu->fetch_context_reg(dstcontext, regdstno, &szdst); 02968 ULONG_PTR* ptrsrc = dbghelp_current_cpu->fetch_context_reg(srccontext, regsrcno, &szsrc); 02969 02970 if (szdst != szsrc) 02971 { 02972 FIXME("Cannot copy register %lu/%u => %lu/%u because of size mismatch (%u => %u)\n", 02973 dwregsrc, regsrcno, dwregdst, regdstno, szsrc, szdst); 02974 return; 02975 } 02976 memcpy(ptrdst, ptrsrc, szdst); 02977 } 02978 02979 static ULONG_PTR eval_expression(const struct module* module, struct cpu_stack_walk* csw, 02980 const unsigned char* zp, CONTEXT *context) 02981 { 02982 dwarf2_traverse_context_t ctx; 02983 ULONG_PTR reg, sz, tmp, stack[64]; 02984 int sp = -1; 02985 ULONG_PTR len; 02986 02987 ctx.data = zp; 02988 ctx.end_data = zp + 4; 02989 len = dwarf2_leb128_as_unsigned(&ctx); 02990 ctx.end_data = ctx.data + len; 02991 ctx.word_size = module->format_info[DFI_DWARF]->u.dwarf2_info->word_size; 02992 02993 while (ctx.data < ctx.end_data) 02994 { 02995 unsigned char opcode = dwarf2_parse_byte(&ctx); 02996 02997 if (opcode >= DW_OP_lit0 && opcode <= DW_OP_lit31) 02998 stack[++sp] = opcode - DW_OP_lit0; 02999 else if (opcode >= DW_OP_reg0 && opcode <= DW_OP_reg31) 03000 stack[++sp] = get_context_reg(context, opcode - DW_OP_reg0); 03001 else if (opcode >= DW_OP_breg0 && opcode <= DW_OP_breg31) 03002 stack[++sp] = get_context_reg(context, opcode - DW_OP_breg0) + dwarf2_leb128_as_signed(&ctx); 03003 else switch (opcode) 03004 { 03005 case DW_OP_nop: break; 03006 case DW_OP_addr: stack[++sp] = dwarf2_parse_addr(&ctx); break; 03007 case DW_OP_const1u: stack[++sp] = dwarf2_parse_byte(&ctx); break; 03008 case DW_OP_const1s: stack[++sp] = (signed char)dwarf2_parse_byte(&ctx); break; 03009 case DW_OP_const2u: stack[++sp] = dwarf2_parse_u2(&ctx); break; 03010 case DW_OP_const2s: stack[++sp] = (short)dwarf2_parse_u2(&ctx); break; 03011 case DW_OP_const4u: stack[++sp] = dwarf2_parse_u4(&ctx); break; 03012 case DW_OP_const4s: stack[++sp] = (signed int)dwarf2_parse_u4(&ctx); break; 03013 case DW_OP_const8u: stack[++sp] = dwarf2_parse_u8(&ctx); break; 03014 case DW_OP_const8s: stack[++sp] = (LONG_PTR)dwarf2_parse_u8(&ctx); break; 03015 case DW_OP_constu: stack[++sp] = dwarf2_leb128_as_unsigned(&ctx); break; 03016 case DW_OP_consts: stack[++sp] = dwarf2_leb128_as_signed(&ctx); break; 03017 case DW_OP_deref: 03018 if (!sw_read_mem(csw, stack[sp], &tmp, sizeof(tmp))) 03019 { 03020 ERR("Couldn't read memory at %lx\n", stack[sp]); 03021 tmp = 0; 03022 } 03023 stack[sp] = tmp; 03024 break; 03025 case DW_OP_dup: stack[sp + 1] = stack[sp]; sp++; break; 03026 case DW_OP_drop: sp--; break; 03027 case DW_OP_over: stack[sp + 1] = stack[sp - 1]; sp++; break; 03028 case DW_OP_pick: stack[sp + 1] = stack[sp - dwarf2_parse_byte(&ctx)]; sp++; break; 03029 case DW_OP_swap: tmp = stack[sp]; stack[sp] = stack[sp-1]; stack[sp-1] = tmp; break; 03030 case DW_OP_rot: tmp = stack[sp]; stack[sp] = stack[sp-1]; stack[sp-1] = stack[sp-2]; stack[sp-2] = tmp; break; 03031 case DW_OP_abs: stack[sp] = labs(stack[sp]); break; 03032 case DW_OP_neg: stack[sp] = -stack[sp]; break; 03033 case DW_OP_not: stack[sp] = ~stack[sp]; break; 03034 case DW_OP_and: stack[sp-1] &= stack[sp]; sp--; break; 03035 case DW_OP_or: stack[sp-1] |= stack[sp]; sp--; break; 03036 case DW_OP_minus: stack[sp-1] -= stack[sp]; sp--; break; 03037 case DW_OP_mul: stack[sp-1] *= stack[sp]; sp--; break; 03038 case DW_OP_plus: stack[sp-1] += stack[sp]; sp--; break; 03039 case DW_OP_xor: stack[sp-1] ^= stack[sp]; sp--; break; 03040 case DW_OP_shl: stack[sp-1] <<= stack[sp]; sp--; break; 03041 case DW_OP_shr: stack[sp-1] >>= stack[sp]; sp--; break; 03042 case DW_OP_plus_uconst: stack[sp] += dwarf2_leb128_as_unsigned(&ctx); break; 03043 case DW_OP_shra: stack[sp-1] = (LONG_PTR)stack[sp-1] / (1 << stack[sp]); sp--; break; 03044 case DW_OP_div: stack[sp-1] = (LONG_PTR)stack[sp-1] / (LONG_PTR)stack[sp]; sp--; break; 03045 case DW_OP_mod: stack[sp-1] = (LONG_PTR)stack[sp-1] % (LONG_PTR)stack[sp]; sp--; break; 03046 case DW_OP_ge: stack[sp-1] = ((LONG_PTR)stack[sp-1] >= (LONG_PTR)stack[sp]); sp--; break; 03047 case DW_OP_gt: stack[sp-1] = ((LONG_PTR)stack[sp-1] > (LONG_PTR)stack[sp]); sp--; break; 03048 case DW_OP_le: stack[sp-1] = ((LONG_PTR)stack[sp-1] <= (LONG_PTR)stack[sp]); sp--; break; 03049 case DW_OP_lt: stack[sp-1] = ((LONG_PTR)stack[sp-1] < (LONG_PTR)stack[sp]); sp--; break; 03050 case DW_OP_eq: stack[sp-1] = (stack[sp-1] == stack[sp]); sp--; break; 03051 case DW_OP_ne: stack[sp-1] = (stack[sp-1] != stack[sp]); sp--; break; 03052 case DW_OP_skip: tmp = (short)dwarf2_parse_u2(&ctx); ctx.data += tmp; break; 03053 case DW_OP_bra: tmp = (short)dwarf2_parse_u2(&ctx); if (!stack[sp--]) ctx.data += tmp; break; 03054 case DW_OP_GNU_encoded_addr: 03055 tmp = dwarf2_parse_byte(&ctx); 03056 stack[++sp] = dwarf2_parse_augmentation_ptr(&ctx, tmp); 03057 break; 03058 case DW_OP_regx: 03059 stack[++sp] = get_context_reg(context, dwarf2_leb128_as_unsigned(&ctx)); 03060 break; 03061 case DW_OP_bregx: 03062 reg = dwarf2_leb128_as_unsigned(&ctx); 03063 tmp = dwarf2_leb128_as_signed(&ctx); 03064 stack[++sp] = get_context_reg(context, reg) + tmp; 03065 break; 03066 case DW_OP_deref_size: 03067 sz = dwarf2_parse_byte(&ctx); 03068 if (!sw_read_mem(csw, stack[sp], &tmp, sz)) 03069 { 03070 ERR("Couldn't read memory at %lx\n", stack[sp]); 03071 tmp = 0; 03072 } 03073 /* do integral promotion */ 03074 switch (sz) 03075 { 03076 case 1: stack[sp] = *(unsigned char*)&tmp; break; 03077 case 2: stack[sp] = *(unsigned short*)&tmp; break; 03078 case 4: stack[sp] = *(unsigned int*)&tmp; break; 03079 case 8: stack[sp] = *(ULONG_PTR*)&tmp; break; /* FIXME: won't work on 32bit platform */ 03080 default: FIXME("Unknown size for deref 0x%lx\n", sz); 03081 } 03082 break; 03083 default: 03084 FIXME("unhandled opcode %02x\n", opcode); 03085 } 03086 } 03087 return stack[sp]; 03088 } 03089 03090 static void apply_frame_state(const struct module* module, struct cpu_stack_walk* csw, 03091 CONTEXT *context, struct frame_state *state, ULONG_PTR* cfa) 03092 { 03093 unsigned int i; 03094 ULONG_PTR value; 03095 CONTEXT new_context = *context; 03096 03097 switch (state->cfa_rule) 03098 { 03099 case RULE_EXPRESSION: 03100 *cfa = eval_expression(module, csw, (const unsigned char*)state->cfa_offset, context); 03101 if (!sw_read_mem(csw, *cfa, cfa, sizeof(*cfa))) 03102 { 03103 WARN("Couldn't read memory at %p\n", (void*)*cfa); 03104 return; 03105 } 03106 break; 03107 case RULE_VAL_EXPRESSION: 03108 *cfa = eval_expression(module, csw, (const unsigned char*)state->cfa_offset, context); 03109 break; 03110 default: 03111 *cfa = get_context_reg(context, state->cfa_reg) + state->cfa_offset; 03112 break; 03113 } 03114 if (!*cfa) return; 03115 03116 for (i = 0; i < NB_FRAME_REGS; i++) 03117 { 03118 switch (state->rules[i]) 03119 { 03120 case RULE_UNSET: 03121 case RULE_UNDEFINED: 03122 case RULE_SAME: 03123 break; 03124 case RULE_CFA_OFFSET: 03125 set_context_reg(csw, &new_context, i, *cfa + state->regs[i], TRUE); 03126 break; 03127 case RULE_OTHER_REG: 03128 copy_context_reg(&new_context, i, context, state->regs[i]); 03129 break; 03130 case RULE_EXPRESSION: 03131 value = eval_expression(module, csw, (const unsigned char*)state->regs[i], context); 03132 set_context_reg(csw, &new_context, i, value, TRUE); 03133 break; 03134 case RULE_VAL_EXPRESSION: 03135 value = eval_expression(module, csw, (const unsigned char*)state->regs[i], context); 03136 set_context_reg(csw, &new_context, i, value, FALSE); 03137 break; 03138 } 03139 } 03140 *context = new_context; 03141 } 03142 03143 /*********************************************************************** 03144 * dwarf2_virtual_unwind 03145 * 03146 */ 03147 BOOL dwarf2_virtual_unwind(struct cpu_stack_walk* csw, ULONG_PTR ip, CONTEXT* context, ULONG_PTR* cfa) 03148 { 03149 struct module_pair pair; 03150 struct frame_info info; 03151 dwarf2_traverse_context_t cie_ctx, fde_ctx; 03152 struct module_format* modfmt; 03153 const unsigned char* end; 03154 DWORD_PTR delta; 03155 03156 if (!(pair.pcs = process_find_by_handle(csw->hProcess)) || 03157 !(pair.requested = module_find_by_addr(pair.pcs, ip, DMT_UNKNOWN)) || 03158 !module_get_debug(&pair)) 03159 return FALSE; 03160 modfmt = pair.effective->format_info[DFI_DWARF]; 03161 if (!modfmt) return FALSE; 03162 memset(&info, 0, sizeof(info)); 03163 fde_ctx.data = modfmt->u.dwarf2_info->eh_frame.address; 03164 fde_ctx.end_data = fde_ctx.data + modfmt->u.dwarf2_info->eh_frame.size; 03165 fde_ctx.word_size = modfmt->u.dwarf2_info->word_size; 03166 /* let offsets relative to the eh_frame sections be correctly computed, as we'll map 03167 * in this process the IMAGE section at a different address as the one expected by 03168 * the image 03169 */ 03170 delta = pair.effective->module.BaseOfImage + modfmt->u.dwarf2_info->eh_frame.rva - 03171 (DWORD_PTR)modfmt->u.dwarf2_info->eh_frame.address; 03172 if (!dwarf2_get_cie(ip, pair.effective, delta, &fde_ctx, &cie_ctx, &info, TRUE)) 03173 { 03174 fde_ctx.data = modfmt->u.dwarf2_info->debug_frame.address; 03175 fde_ctx.end_data = fde_ctx.data + modfmt->u.dwarf2_info->debug_frame.size; 03176 fde_ctx.word_size = modfmt->u.dwarf2_info->word_size; 03177 delta = pair.effective->reloc_delta; 03178 if (!dwarf2_get_cie(ip, pair.effective, delta, &fde_ctx, &cie_ctx, &info, FALSE)) 03179 { 03180 TRACE("Couldn't find information for %lx\n", ip); 03181 return FALSE; 03182 } 03183 } 03184 03185 TRACE("function %lx/%lx code_align %lu data_align %ld retaddr %s\n", 03186 ip, info.ip, info.code_align, info.data_align, 03187 dbghelp_current_cpu->fetch_regname(dbghelp_current_cpu->map_dwarf_register(info.retaddr_reg))); 03188 03189 /* if at very beginning of function, return and use default unwinder */ 03190 if (ip == info.ip) return FALSE; 03191 execute_cfa_instructions(&cie_ctx, ip, &info); 03192 03193 if (info.aug_z_format) /* get length of augmentation data */ 03194 { 03195 ULONG_PTR len = dwarf2_leb128_as_unsigned(&fde_ctx); 03196 end = fde_ctx.data + len; 03197 } 03198 else end = NULL; 03199 dwarf2_parse_augmentation_ptr(&fde_ctx, info.lsda_encoding); /* handler_data */ 03200 if (end) fde_ctx.data = end; 03201 03202 execute_cfa_instructions(&fde_ctx, ip, &info); 03203 apply_frame_state(pair.effective, csw, context, &info.state, cfa); 03204 03205 return TRUE; 03206 } 03207 03208 static void dwarf2_location_compute(struct process* pcs, 03209 const struct module_format* modfmt, 03210 const struct symt_function* func, 03211 struct location* loc) 03212 { 03213 struct location frame; 03214 DWORD_PTR ip; 03215 int err; 03216 dwarf2_traverse_context_t lctx; 03217 03218 if (!func->container || func->container->tag != SymTagCompiland) 03219 { 03220 WARN("We'd expect function %s's container to exist and be a compiland\n", func->hash_elt.name); 03221 err = loc_err_internal; 03222 } 03223 else 03224 { 03225 /* instruction pointer relative to compiland's start */ 03226 ip = pcs->ctx_frame.InstructionOffset - ((struct symt_compiland*)func->container)->address; 03227 03228 if ((err = loc_compute_frame(pcs, modfmt, func, ip, &frame)) == 0) 03229 { 03230 switch (loc->kind) 03231 { 03232 case loc_dwarf2_location_list: 03233 /* Then, if the variable has a location list, find it !! */ 03234 if (dwarf2_lookup_loclist(modfmt, 03235 modfmt->u.dwarf2_info->debug_loc.address + loc->offset, 03236 ip, &lctx)) 03237 goto do_compute; 03238 err = loc_err_out_of_scope; 03239 break; 03240 case loc_dwarf2_block: 03241 /* or if we have a copy of an existing block, get ready for it */ 03242 { 03243 unsigned* ptr = (unsigned*)loc->offset; 03244 03245 lctx.data = (const BYTE*)(ptr + 1); 03246 lctx.end_data = lctx.data + *ptr; 03247 lctx.word_size = modfmt->u.dwarf2_info->word_size; 03248 } 03249 do_compute: 03250 /* now get the variable */ 03251 err = compute_location(&lctx, loc, pcs->handle, &frame); 03252 break; 03253 case loc_register: 03254 case loc_regrel: 03255 /* nothing to do */ 03256 break; 03257 default: 03258 WARN("Unsupported local kind %d\n", loc->kind); 03259 err = loc_err_internal; 03260 } 03261 } 03262 } 03263 if (err < 0) 03264 { 03265 loc->kind = loc_register; 03266 loc->reg = err; 03267 } 03268 } 03269 03270 static void dwarf2_module_remove(struct process* pcs, struct module_format* modfmt) 03271 { 03272 HeapFree(GetProcessHeap(), 0, modfmt); 03273 } 03274 03275 static inline BOOL dwarf2_init_section(dwarf2_section_t* section, struct image_file_map* fmap, 03276 const char* sectname, struct image_section_map* ism) 03277 { 03278 struct image_section_map local_ism; 03279 03280 if (!ism) ism = &local_ism; 03281 if (!image_find_section(fmap, sectname, ism)) 03282 { 03283 section->address = NULL; 03284 section->size = 0; 03285 section->rva = 0; 03286 return FALSE; 03287 } 03288 03289 section->address = (const BYTE*)image_map_section(ism); 03290 section->size = image_get_map_size(ism); 03291 section->rva = image_get_map_rva(ism); 03292 return TRUE; 03293 } 03294 03295 BOOL dwarf2_parse(struct module* module, unsigned long load_offset, 03296 const struct elf_thunk_area* thunks, 03297 struct image_file_map* fmap) 03298 { 03299 dwarf2_section_t eh_frame, section[section_max]; 03300 dwarf2_traverse_context_t mod_ctx; 03301 struct image_section_map debug_sect, debug_str_sect, debug_abbrev_sect, 03302 debug_line_sect, debug_ranges_sect, eh_frame_sect; 03303 BOOL ret = TRUE; 03304 struct module_format* dwarf2_modfmt; 03305 03306 dwarf2_init_section(&eh_frame, fmap, ".eh_frame", &eh_frame_sect); 03307 dwarf2_init_section(§ion[section_debug], fmap, ".debug_info", &debug_sect); 03308 dwarf2_init_section(§ion[section_abbrev], fmap, ".debug_abbrev", &debug_abbrev_sect); 03309 dwarf2_init_section(§ion[section_string], fmap, ".debug_str", &debug_str_sect); 03310 dwarf2_init_section(§ion[section_line], fmap, ".debug_line", &debug_line_sect); 03311 dwarf2_init_section(§ion[section_ranges], fmap, ".debug_ranges", &debug_ranges_sect); 03312 03313 /* to do anything useful we need either .eh_frame or .debug_info */ 03314 if ((!eh_frame.address || eh_frame.address == IMAGE_NO_MAP) && 03315 (!section[section_debug].address || section[section_debug].address == IMAGE_NO_MAP)) 03316 { 03317 ret = FALSE; 03318 goto leave; 03319 } 03320 03321 if (fmap->modtype == DMT_ELF && debug_sect.fmap) 03322 { 03323 /* debug info might have a different base address than .so file 03324 * when elf file is prelinked after splitting off debug info 03325 * adjust symbol base addresses accordingly 03326 */ 03327 load_offset += fmap->u.elf.elf_start - debug_sect.fmap->u.elf.elf_start; 03328 } 03329 03330 TRACE("Loading Dwarf2 information for %s\n", debugstr_w(module->module.ModuleName)); 03331 03332 mod_ctx.data = section[section_debug].address; 03333 mod_ctx.end_data = mod_ctx.data + section[section_debug].size; 03334 mod_ctx.word_size = 0; /* will be correctly set later on */ 03335 03336 dwarf2_modfmt = HeapAlloc(GetProcessHeap(), 0, 03337 sizeof(*dwarf2_modfmt) + sizeof(*dwarf2_modfmt->u.dwarf2_info)); 03338 if (!dwarf2_modfmt) 03339 { 03340 ret = FALSE; 03341 goto leave; 03342 } 03343 dwarf2_modfmt->module = module; 03344 dwarf2_modfmt->remove = dwarf2_module_remove; 03345 dwarf2_modfmt->loc_compute = dwarf2_location_compute; 03346 dwarf2_modfmt->u.dwarf2_info = (struct dwarf2_module_info_s*)(dwarf2_modfmt + 1); 03347 dwarf2_modfmt->u.dwarf2_info->word_size = 0; /* will be correctly set later on */ 03348 dwarf2_modfmt->module->format_info[DFI_DWARF] = dwarf2_modfmt; 03349 03350 /* As we'll need later some sections' content, we won't unmap these 03351 * sections upon existing this function 03352 */ 03353 dwarf2_init_section(&dwarf2_modfmt->u.dwarf2_info->debug_loc, fmap, ".debug_loc", NULL); 03354 dwarf2_init_section(&dwarf2_modfmt->u.dwarf2_info->debug_frame, fmap, ".debug_frame", NULL); 03355 dwarf2_modfmt->u.dwarf2_info->eh_frame = eh_frame; 03356 03357 while (mod_ctx.data < mod_ctx.end_data) 03358 { 03359 dwarf2_parse_compilation_unit(section, dwarf2_modfmt->module, thunks, &mod_ctx, load_offset); 03360 } 03361 dwarf2_modfmt->module->module.SymType = SymDia; 03362 dwarf2_modfmt->module->module.CVSig = 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24); 03363 /* FIXME: we could have a finer grain here */ 03364 dwarf2_modfmt->module->module.GlobalSymbols = TRUE; 03365 dwarf2_modfmt->module->module.TypeInfo = TRUE; 03366 dwarf2_modfmt->module->module.SourceIndexed = TRUE; 03367 dwarf2_modfmt->module->module.Publics = TRUE; 03368 03369 leave: 03370 image_unmap_section(&debug_sect); 03371 image_unmap_section(&debug_abbrev_sect); 03372 image_unmap_section(&debug_str_sect); 03373 image_unmap_section(&debug_line_sect); 03374 image_unmap_section(&debug_ranges_sect); 03375 if (!ret) image_unmap_section(&eh_frame_sect); 03376 03377 return ret; 03378 } Generated on Fri May 25 2012 04:21:20 for ReactOS by
1.7.6.1
|