Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstabs.c
Go to the documentation of this file.
00001 /* 00002 * File stabs.c - read stabs information from the modules 00003 * 00004 * Copyright (C) 1996, Eric Youngdale. 00005 * 1999-2005, Eric Pouech 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 * 00021 * 00022 * Maintenance Information 00023 * ----------------------- 00024 * 00025 * For documentation on the stabs format see for example 00026 * The "stabs" debug format 00027 * by Julia Menapace, Jim Kingdon, David Mackenzie 00028 * of Cygnus Support 00029 * available (hopefully) from http://sources.redhat.com/gdb/onlinedocs 00030 */ 00031 00032 #include "config.h" 00033 #include "wine/port.h" 00034 00035 #include <sys/types.h> 00036 #include <fcntl.h> 00037 #ifdef HAVE_SYS_STAT_H 00038 # include <sys/stat.h> 00039 #endif 00040 #ifdef HAVE_SYS_MMAN_H 00041 #include <sys/mman.h> 00042 #endif 00043 #include <limits.h> 00044 #include <stdlib.h> 00045 #include <string.h> 00046 #ifdef HAVE_UNISTD_H 00047 # include <unistd.h> 00048 #endif 00049 #include <stdio.h> 00050 #include <assert.h> 00051 #include <stdarg.h> 00052 00053 #ifdef HAVE_MACH_O_NLIST_H 00054 # include <mach-o/nlist.h> 00055 #endif 00056 00057 #include "windef.h" 00058 #include "winbase.h" 00059 #include "winnls.h" 00060 00061 #include "dbghelp_private.h" 00062 00063 #include "wine/debug.h" 00064 00065 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_stabs); 00066 00067 #define strtoull _strtoui64 00068 00069 /* Masks for n_type field */ 00070 #ifndef N_STAB 00071 #define N_STAB 0xe0 00072 #endif 00073 #ifndef N_TYPE 00074 #define N_TYPE 0x1e 00075 #endif 00076 #ifndef N_EXT 00077 #define N_EXT 0x01 00078 #endif 00079 00080 /* Values for (n_type & N_TYPE) */ 00081 #ifndef N_UNDF 00082 #define N_UNDF 0x00 00083 #endif 00084 #ifndef N_ABS 00085 #define N_ABS 0x02 00086 #endif 00087 00088 #define N_GSYM 0x20 00089 #define N_FUN 0x24 00090 #define N_STSYM 0x26 00091 #define N_LCSYM 0x28 00092 #define N_MAIN 0x2a 00093 #define N_ROSYM 0x2c 00094 #define N_BNSYM 0x2e 00095 #define N_OPT 0x3c 00096 #define N_RSYM 0x40 00097 #define N_SLINE 0x44 00098 #define N_ENSYM 0x4e 00099 #define N_SO 0x64 00100 #define N_OSO 0x66 00101 #define N_LSYM 0x80 00102 #define N_BINCL 0x82 00103 #define N_SOL 0x84 00104 #define N_PSYM 0xa0 00105 #define N_EINCL 0xa2 00106 #define N_LBRAC 0xc0 00107 #define N_EXCL 0xc2 00108 #define N_RBRAC 0xe0 00109 00110 struct stab_nlist 00111 { 00112 unsigned n_strx; 00113 unsigned char n_type; 00114 char n_other; 00115 short n_desc; 00116 unsigned n_value; 00117 }; 00118 00119 static void stab_strcpy(char* dest, int sz, const char* source) 00120 { 00121 char* ptr = dest; 00122 /* 00123 * A strcpy routine that stops when we hit the ':' character. 00124 * Faster than copying the whole thing, and then nuking the 00125 * ':'. 00126 * Takes also care of (valid) a::b constructs 00127 */ 00128 while (*source != '\0') 00129 { 00130 if (source[0] != ':' && sz-- > 0) *ptr++ = *source++; 00131 else if (source[1] == ':' && (sz -= 2) > 0) 00132 { 00133 *ptr++ = *source++; 00134 *ptr++ = *source++; 00135 } 00136 else break; 00137 } 00138 *ptr-- = '\0'; 00139 /* GCC emits, in some cases, a .<digit>+ suffix. 00140 * This is used for static variable inside functions, so 00141 * that we can have several such variables with same name in 00142 * the same compilation unit 00143 * We simply ignore that suffix when present (we also get rid 00144 * of it in ELF symtab parsing) 00145 */ 00146 if (ptr >= dest && isdigit(*ptr)) 00147 { 00148 while (ptr > dest && isdigit(*ptr)) ptr--; 00149 if (*ptr == '.') *ptr = '\0'; 00150 } 00151 assert(sz > 0); 00152 } 00153 00154 typedef struct 00155 { 00156 char* name; 00157 unsigned long value; 00158 struct symt** vector; 00159 int nrofentries; 00160 } include_def; 00161 00162 #define MAX_INCLUDES 5120 00163 00164 static include_def* include_defs = NULL; 00165 static int num_include_def = 0; 00166 static int num_alloc_include_def = 0; 00167 static int cu_include_stack[MAX_INCLUDES]; 00168 static int cu_include_stk_idx = 0; 00169 static struct symt** cu_vector = NULL; 00170 static int cu_nrofentries = 0; 00171 static struct symt_basic* stabs_basic[36]; 00172 00173 static int stabs_new_include(const char* file, unsigned long val) 00174 { 00175 if (num_include_def == num_alloc_include_def) 00176 { 00177 if (!include_defs) 00178 { 00179 num_alloc_include_def = 256; 00180 include_defs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 00181 sizeof(include_defs[0]) * num_alloc_include_def); 00182 } 00183 else 00184 { 00185 num_alloc_include_def *= 2; 00186 include_defs = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, include_defs, 00187 sizeof(include_defs[0]) * num_alloc_include_def); 00188 } 00189 } 00190 include_defs[num_include_def].name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(file) + 1), file); 00191 include_defs[num_include_def].value = val; 00192 include_defs[num_include_def].vector = NULL; 00193 include_defs[num_include_def].nrofentries = 0; 00194 00195 return num_include_def++; 00196 } 00197 00198 static int stabs_find_include(const char* file, unsigned long val) 00199 { 00200 int i; 00201 00202 for (i = 0; i < num_include_def; i++) 00203 { 00204 if (val == include_defs[i].value && 00205 strcmp(file, include_defs[i].name) == 0) 00206 return i; 00207 } 00208 return -1; 00209 } 00210 00211 static int stabs_add_include(int idx) 00212 { 00213 if (idx < 0) return -1; 00214 cu_include_stk_idx++; 00215 00216 /* if this happens, just bump MAX_INCLUDES */ 00217 /* we could also handle this as another dynarray */ 00218 assert(cu_include_stk_idx < MAX_INCLUDES); 00219 cu_include_stack[cu_include_stk_idx] = idx; 00220 return cu_include_stk_idx; 00221 } 00222 00223 static void stabs_reset_includes(void) 00224 { 00225 /* 00226 * The struct symt:s that we would need to use are reset when 00227 * we start a new file. (at least the ones in filenr == 0) 00228 */ 00229 cu_include_stk_idx = 0;/* keep 0 as index for the .c file itself */ 00230 memset(cu_vector, 0, sizeof(cu_vector[0]) * cu_nrofentries); 00231 } 00232 00233 static void stabs_free_includes(void) 00234 { 00235 int i; 00236 00237 stabs_reset_includes(); 00238 for (i = 0; i < num_include_def; i++) 00239 { 00240 HeapFree(GetProcessHeap(), 0, include_defs[i].name); 00241 HeapFree(GetProcessHeap(), 0, include_defs[i].vector); 00242 } 00243 HeapFree(GetProcessHeap(), 0, include_defs); 00244 include_defs = NULL; 00245 num_include_def = 0; 00246 num_alloc_include_def = 0; 00247 HeapFree(GetProcessHeap(), 0, cu_vector); 00248 cu_vector = NULL; 00249 cu_nrofentries = 0; 00250 } 00251 00252 static struct symt** stabs_find_ref(long filenr, long subnr) 00253 { 00254 struct symt** ret; 00255 00256 /* FIXME: I could perhaps create a dummy include_def for each compilation 00257 * unit which would allow not to handle those two cases separately 00258 */ 00259 if (filenr == 0) 00260 { 00261 if (cu_nrofentries <= subnr) 00262 { 00263 cu_nrofentries = max( cu_nrofentries * 2, subnr + 1 ); 00264 if (!cu_vector) 00265 cu_vector = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 00266 sizeof(cu_vector[0]) * cu_nrofentries); 00267 else 00268 cu_vector = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 00269 cu_vector, sizeof(cu_vector[0]) * cu_nrofentries); 00270 } 00271 ret = &cu_vector[subnr]; 00272 } 00273 else 00274 { 00275 include_def* idef; 00276 00277 assert(filenr <= cu_include_stk_idx); 00278 idef = &include_defs[cu_include_stack[filenr]]; 00279 00280 if (idef->nrofentries <= subnr) 00281 { 00282 idef->nrofentries = max( idef->nrofentries * 2, subnr + 1 ); 00283 if (!idef->vector) 00284 idef->vector = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 00285 sizeof(idef->vector[0]) * idef->nrofentries); 00286 else 00287 idef->vector = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 00288 idef->vector, sizeof(idef->vector[0]) * idef->nrofentries); 00289 } 00290 ret = &idef->vector[subnr]; 00291 } 00292 TRACE("(%ld,%ld) => %p (%p)\n", filenr, subnr, ret, *ret); 00293 return ret; 00294 } 00295 00296 static struct symt** stabs_read_type_enum(const char** x) 00297 { 00298 long filenr, subnr; 00299 const char* iter; 00300 char* end; 00301 00302 iter = *x; 00303 if (*iter == '(') 00304 { 00305 ++iter; /* '(' */ 00306 filenr = strtol(iter, &end, 10); /* <int> */ 00307 iter = ++end; /* ',' */ 00308 subnr = strtol(iter, &end, 10); /* <int> */ 00309 iter = ++end; /* ')' */ 00310 } 00311 else 00312 { 00313 filenr = 0; 00314 subnr = strtol(iter, &end, 10); /* <int> */ 00315 iter = end; 00316 } 00317 *x = iter; 00318 return stabs_find_ref(filenr, subnr); 00319 } 00320 00321 #define PTS_DEBUG 00322 struct ParseTypedefData 00323 { 00324 const char* ptr; 00325 char buf[1024]; 00326 int idx; 00327 struct module* module; 00328 #ifdef PTS_DEBUG 00329 struct PTS_Error 00330 { 00331 const char* ptr; 00332 unsigned line; 00333 } errors[16]; 00334 int err_idx; 00335 #endif 00336 }; 00337 00338 #ifdef PTS_DEBUG 00339 static void stabs_pts_push(struct ParseTypedefData* ptd, unsigned line) 00340 { 00341 assert(ptd->err_idx < sizeof(ptd->errors) / sizeof(ptd->errors[0])); 00342 ptd->errors[ptd->err_idx].line = line; 00343 ptd->errors[ptd->err_idx].ptr = ptd->ptr; 00344 ptd->err_idx++; 00345 } 00346 #define PTS_ABORTIF(ptd, t) do { if (t) { stabs_pts_push((ptd), __LINE__); return -1;} } while (0) 00347 #else 00348 #define PTS_ABORTIF(ptd, t) do { if (t) return -1; } while (0) 00349 #endif 00350 00351 static int stabs_get_basic(struct ParseTypedefData* ptd, unsigned basic, struct symt** symt) 00352 { 00353 PTS_ABORTIF(ptd, basic >= sizeof(stabs_basic) / sizeof(stabs_basic[0])); 00354 00355 if (!stabs_basic[basic]) 00356 { 00357 switch (basic) 00358 { 00359 case 1: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "int", 4); break; 00360 case 2: stabs_basic[basic] = symt_new_basic(ptd->module, btChar, "char", 1); break; 00361 case 3: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "short int", 2); break; 00362 case 4: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "long int", 4); break; 00363 case 5: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned char", 1); break; 00364 case 6: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "signed char", 1); break; 00365 case 7: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned short int", 2); break; 00366 case 8: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned int", 4); break; 00367 case 9: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned", 2); break; 00368 case 10: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned long int", 2); break; 00369 case 11: stabs_basic[basic] = symt_new_basic(ptd->module, btVoid, "void", 0); break; 00370 case 12: stabs_basic[basic] = symt_new_basic(ptd->module, btFloat, "float", 4); break; 00371 case 13: stabs_basic[basic] = symt_new_basic(ptd->module, btFloat, "double", 8); break; 00372 case 14: stabs_basic[basic] = symt_new_basic(ptd->module, btFloat, "long double", 12); break; 00373 case 15: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "integer", 4); break; 00374 case 16: stabs_basic[basic] = symt_new_basic(ptd->module, btBool, "bool", 1); break; 00375 /* case 17: short real */ 00376 /* case 18: real */ 00377 case 25: stabs_basic[basic] = symt_new_basic(ptd->module, btComplex, "float complex", 8); break; 00378 case 26: stabs_basic[basic] = symt_new_basic(ptd->module, btComplex, "double complex", 16); break; 00379 case 30: stabs_basic[basic] = symt_new_basic(ptd->module, btWChar, "wchar_t", 2); break; 00380 case 31: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "long long int", 8); break; 00381 case 32: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "long long unsigned", 8); break; 00382 /* starting at 35 are wine extensions (especially for R implementation) */ 00383 case 35: stabs_basic[basic] = symt_new_basic(ptd->module, btComplex, "long double complex", 24); break; 00384 default: PTS_ABORTIF(ptd, 1); 00385 } 00386 } 00387 *symt = &stabs_basic[basic]->symt; 00388 return 0; 00389 } 00390 00391 static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, 00392 const char* typename, struct symt** dt); 00393 00394 static int stabs_pts_read_id(struct ParseTypedefData* ptd) 00395 { 00396 const char* first = ptd->ptr; 00397 unsigned int template = 0; 00398 char ch; 00399 00400 while ((ch = *ptd->ptr++) != '\0') 00401 { 00402 switch (ch) 00403 { 00404 case ':': 00405 if (template == 0) 00406 { 00407 unsigned int len = ptd->ptr - first - 1; 00408 PTS_ABORTIF(ptd, len >= sizeof(ptd->buf) - ptd->idx); 00409 memcpy(ptd->buf + ptd->idx, first, len); 00410 ptd->buf[ptd->idx + len] = '\0'; 00411 ptd->idx += len + 1; 00412 return 0; 00413 } 00414 break; 00415 case '<': template++; break; 00416 case '>': PTS_ABORTIF(ptd, template == 0); template--; break; 00417 } 00418 } 00419 return -1; 00420 } 00421 00422 static int stabs_pts_read_number(struct ParseTypedefData* ptd, long* v) 00423 { 00424 char* last; 00425 00426 *v = strtol(ptd->ptr, &last, 10); 00427 PTS_ABORTIF(ptd, last == ptd->ptr); 00428 ptd->ptr = last; 00429 return 0; 00430 } 00431 00432 static int stabs_pts_read_type_reference(struct ParseTypedefData* ptd, 00433 long* filenr, long* subnr) 00434 { 00435 if (*ptd->ptr == '(') 00436 { 00437 /* '(' <int> ',' <int> ')' */ 00438 ptd->ptr++; 00439 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, filenr) == -1); 00440 PTS_ABORTIF(ptd, *ptd->ptr++ != ','); 00441 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, subnr) == -1); 00442 PTS_ABORTIF(ptd, *ptd->ptr++ != ')'); 00443 } 00444 else 00445 { 00446 *filenr = 0; 00447 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, subnr) == -1); 00448 } 00449 return 0; 00450 } 00451 00452 struct pts_range_value 00453 { 00454 ULONGLONG val; 00455 int sign; 00456 }; 00457 00458 static int stabs_pts_read_range_value(struct ParseTypedefData* ptd, struct pts_range_value* prv) 00459 { 00460 char* last; 00461 00462 switch (*ptd->ptr) 00463 { 00464 case '0': 00465 while (*ptd->ptr == '0') ptd->ptr++; 00466 if (*ptd->ptr >= '1' && *ptd->ptr <= '7') 00467 { 00468 switch (ptd->ptr[1]) 00469 { 00470 case '0': 00471 PTS_ABORTIF(ptd, ptd->ptr[0] != '1'); 00472 prv->sign = -1; 00473 prv->val = 0; 00474 while (isdigit(*ptd->ptr)) prv->val = (prv->val << 3) + *ptd->ptr++ - '0'; 00475 break; 00476 case '7': 00477 prv->sign = 1; 00478 prv->val = 0; 00479 while (isdigit(*ptd->ptr)) prv->val = (prv->val << 3) + *ptd->ptr++ - '0'; 00480 break; 00481 default: PTS_ABORTIF(ptd, 1); break; 00482 } 00483 } else prv->sign = 0; 00484 break; 00485 case '-': 00486 prv->sign = -1; 00487 prv->val = strtoull(++ptd->ptr, &last, 10); 00488 ptd->ptr = last; 00489 break; 00490 case '+': 00491 default: 00492 prv->sign = 1; 00493 prv->val = strtoull(ptd->ptr, &last, 10); 00494 ptd->ptr = last; 00495 break; 00496 } 00497 return 0; 00498 } 00499 00500 static int stabs_pts_read_range(struct ParseTypedefData* ptd, const char* typename, 00501 struct symt** dt) 00502 { 00503 struct symt* ref; 00504 struct pts_range_value lo; 00505 struct pts_range_value hi; 00506 unsigned size; 00507 enum BasicType bt; 00508 int i; 00509 ULONGLONG v; 00510 00511 /* type ';' <int> ';' <int> ';' */ 00512 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref) == -1); 00513 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */ 00514 PTS_ABORTIF(ptd, stabs_pts_read_range_value(ptd, &lo) == -1); 00515 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */ 00516 PTS_ABORTIF(ptd, stabs_pts_read_range_value(ptd, &hi) == -1); 00517 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */ 00518 00519 /* basically, we don't use ref... in some cases, for example, float is declared 00520 * as a derived type of int... which won't help us... so we guess the types 00521 * from the various formats 00522 */ 00523 if (lo.sign == 0 && hi.sign < 0) 00524 { 00525 bt = btUInt; 00526 size = hi.val; 00527 } 00528 else if (lo.sign < 0 && hi.sign == 0) 00529 { 00530 bt = btUInt; 00531 size = lo.val; 00532 } 00533 else if (lo.sign > 0 && hi.sign == 0) 00534 { 00535 bt = btFloat; 00536 size = lo.val; 00537 } 00538 else if (lo.sign < 0 && hi.sign > 0) 00539 { 00540 v = 1 << 7; 00541 for (i = 7; i < 64; i += 8) 00542 { 00543 if (lo.val == v && hi.val == v - 1) 00544 { 00545 bt = btInt; 00546 size = (i + 1) / 8; 00547 break; 00548 } 00549 v <<= 8; 00550 } 00551 PTS_ABORTIF(ptd, i >= 64); 00552 } 00553 else if (lo.sign == 0 && hi.sign > 0) 00554 { 00555 if (hi.val == 127) /* specific case for char... */ 00556 { 00557 bt = btChar; 00558 size = 1; 00559 } 00560 else 00561 { 00562 v = 1; 00563 for (i = 8; i <= 64; i += 8) 00564 { 00565 v <<= 8; 00566 if (hi.val + 1 == v) 00567 { 00568 bt = btUInt; 00569 size = (i + 1) / 8; 00570 break; 00571 } 00572 } 00573 PTS_ABORTIF(ptd, i > 64); 00574 } 00575 } 00576 else PTS_ABORTIF(ptd, 1); 00577 00578 *dt = &symt_new_basic(ptd->module, bt, typename, size)->symt; 00579 return 0; 00580 } 00581 00582 static inline int stabs_pts_read_method_info(struct ParseTypedefData* ptd) 00583 { 00584 struct symt* dt; 00585 const char* tmp; 00586 char mthd; 00587 00588 do 00589 { 00590 /* get type of return value */ 00591 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1); 00592 if (*ptd->ptr == ';') ptd->ptr++; 00593 00594 /* get types of parameters */ 00595 if (*ptd->ptr == ':') 00596 { 00597 PTS_ABORTIF(ptd, !(tmp = strchr(ptd->ptr + 1, ';'))); 00598 ptd->ptr = tmp + 1; 00599 } 00600 PTS_ABORTIF(ptd, !(*ptd->ptr >= '0' && *ptd->ptr <= '9')); 00601 ptd->ptr++; 00602 PTS_ABORTIF(ptd, !(ptd->ptr[0] >= 'A' && *ptd->ptr <= 'D')); 00603 mthd = *++ptd->ptr; 00604 PTS_ABORTIF(ptd, mthd != '.' && mthd != '?' && mthd != '*'); 00605 ptd->ptr++; 00606 if (mthd == '*') 00607 { 00608 long int ofs; 00609 struct symt* dt; 00610 00611 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &ofs) == -1); 00612 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00613 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1); 00614 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00615 } 00616 } while (*ptd->ptr != ';'); 00617 ptd->ptr++; 00618 00619 return 0; 00620 } 00621 00622 static inline int stabs_pts_read_aggregate(struct ParseTypedefData* ptd, 00623 struct symt_udt* sdt) 00624 { 00625 long sz, ofs; 00626 struct symt* adt; 00627 struct symt* dt = NULL; 00628 int idx; 00629 int doadd; 00630 00631 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &sz) == -1); 00632 00633 doadd = symt_set_udt_size(ptd->module, sdt, sz); 00634 if (*ptd->ptr == '!') /* C++ inheritence */ 00635 { 00636 long num_classes; 00637 00638 ptd->ptr++; 00639 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &num_classes) == -1); 00640 PTS_ABORTIF(ptd, *ptd->ptr++ != ','); 00641 while (--num_classes >= 0) 00642 { 00643 ptd->ptr += 2; /* skip visibility and inheritence */ 00644 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &ofs) == -1); 00645 PTS_ABORTIF(ptd, *ptd->ptr++ != ','); 00646 00647 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &adt) == -1); 00648 00649 if (doadd && adt) 00650 { 00651 char tmp[256]; 00652 DWORD64 size; 00653 00654 strcpy(tmp, "__inherited_class_"); 00655 strcat(tmp, symt_get_name(adt)); 00656 00657 /* FIXME: TI_GET_LENGTH will not always work, especially when adt 00658 * has just been seen as a forward definition and not the real stuff 00659 * yet. 00660 * As we don't use much the size of members in structs, this may not 00661 * be much of a problem 00662 */ 00663 symt_get_info(ptd->module, adt, TI_GET_LENGTH, &size); 00664 symt_add_udt_element(ptd->module, sdt, tmp, adt, ofs, (DWORD)size * 8); 00665 } 00666 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00667 } 00668 00669 } 00670 /* if the structure has already been filled, just redo the parsing 00671 * but don't store results into the struct 00672 * FIXME: there's a quite ugly memory leak in there... 00673 */ 00674 00675 /* Now parse the individual elements of the structure/union. */ 00676 while (*ptd->ptr != ';') 00677 { 00678 /* agg_name : type ',' <int:offset> ',' <int:size> */ 00679 idx = ptd->idx; 00680 00681 if (ptd->ptr[0] == '$' && ptd->ptr[1] == 'v') 00682 { 00683 long x; 00684 00685 if (ptd->ptr[2] == 'f') 00686 { 00687 /* C++ virtual method table */ 00688 ptd->ptr += 3; 00689 stabs_read_type_enum(&ptd->ptr); 00690 PTS_ABORTIF(ptd, *ptd->ptr++ != ':'); 00691 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1); 00692 PTS_ABORTIF(ptd, *ptd->ptr++ != ','); 00693 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &x) == -1); 00694 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00695 ptd->idx = idx; 00696 continue; 00697 } 00698 else if (ptd->ptr[2] == 'b') 00699 { 00700 ptd->ptr += 3; 00701 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1); 00702 PTS_ABORTIF(ptd, *ptd->ptr++ != ':'); 00703 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1); 00704 PTS_ABORTIF(ptd, *ptd->ptr++ != ','); 00705 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &x) == -1); 00706 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00707 ptd->idx = idx; 00708 continue; 00709 } 00710 } 00711 00712 PTS_ABORTIF(ptd, stabs_pts_read_id(ptd) == -1); 00713 /* Ref. TSDF R2.130 Section 7.4. When the field name is a method name 00714 * it is followed by two colons rather than one. 00715 */ 00716 if (*ptd->ptr == ':') 00717 { 00718 ptd->ptr++; 00719 stabs_pts_read_method_info(ptd); 00720 ptd->idx = idx; 00721 continue; 00722 } 00723 else 00724 { 00725 /* skip C++ member protection /0 /1 or /2 */ 00726 if (*ptd->ptr == '/') ptd->ptr += 2; 00727 } 00728 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &adt) == -1); 00729 00730 switch (*ptd->ptr++) 00731 { 00732 case ',': 00733 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &ofs) == -1); 00734 PTS_ABORTIF(ptd, *ptd->ptr++ != ','); 00735 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &sz) == -1); 00736 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00737 00738 if (doadd) symt_add_udt_element(ptd->module, sdt, ptd->buf + idx, adt, ofs, sz); 00739 break; 00740 case ':': 00741 { 00742 const char* tmp; 00743 /* method parameters... terminated by ';' */ 00744 PTS_ABORTIF(ptd, !(tmp = strchr(ptd->ptr, ';'))); 00745 ptd->ptr = tmp + 1; 00746 } 00747 break; 00748 default: 00749 PTS_ABORTIF(ptd, TRUE); 00750 } 00751 ptd->idx = idx; 00752 } 00753 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00754 if (*ptd->ptr == '~') 00755 { 00756 ptd->ptr++; 00757 PTS_ABORTIF(ptd, *ptd->ptr++ != '%'); 00758 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1); 00759 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00760 } 00761 return 0; 00762 } 00763 00764 static inline int stabs_pts_read_enum(struct ParseTypedefData* ptd, 00765 struct symt_enum* edt) 00766 { 00767 long value; 00768 int idx; 00769 00770 while (*ptd->ptr != ';') 00771 { 00772 idx = ptd->idx; 00773 PTS_ABORTIF(ptd, stabs_pts_read_id(ptd) == -1); 00774 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &value) == -1); 00775 PTS_ABORTIF(ptd, *ptd->ptr++ != ','); 00776 symt_add_enum_element(ptd->module, edt, ptd->buf + idx, value); 00777 ptd->idx = idx; 00778 } 00779 ptd->ptr++; 00780 return 0; 00781 } 00782 00783 static inline int stabs_pts_read_array(struct ParseTypedefData* ptd, 00784 struct symt** adt) 00785 { 00786 long lo, hi; 00787 struct symt* range_dt; 00788 struct symt* base_dt; 00789 00790 /* ar<typeinfo_nodef>;<int>;<int>;<typeinfo> */ 00791 00792 PTS_ABORTIF(ptd, *ptd->ptr++ != 'r'); 00793 00794 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &range_dt) == -1); 00795 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */ 00796 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &lo) == -1); 00797 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */ 00798 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &hi) == -1); 00799 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */ 00800 00801 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &base_dt) == -1); 00802 00803 *adt = &symt_new_array(ptd->module, lo, hi, base_dt, range_dt)->symt; 00804 return 0; 00805 } 00806 00807 static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typename, 00808 struct symt** ret_dt) 00809 { 00810 int idx; 00811 long sz = -1; 00812 struct symt* new_dt = NULL; /* newly created data type */ 00813 struct symt* ref_dt; /* referenced data type (pointer...) */ 00814 long filenr1, subnr1, tmp; 00815 00816 /* things are a bit complicated because of the way the typedefs are stored inside 00817 * the file, because addresses can change when realloc is done, so we must call 00818 * over and over stabs_find_ref() to keep the correct values around 00819 */ 00820 PTS_ABORTIF(ptd, stabs_pts_read_type_reference(ptd, &filenr1, &subnr1) == -1); 00821 00822 while (*ptd->ptr == '=') 00823 { 00824 ptd->ptr++; 00825 PTS_ABORTIF(ptd, new_dt != NULL); 00826 00827 /* first handle attribute if any */ 00828 switch (*ptd->ptr) 00829 { 00830 case '@': 00831 if (*++ptd->ptr == 's') 00832 { 00833 ptd->ptr++; 00834 if (stabs_pts_read_number(ptd, &sz) == -1) 00835 { 00836 ERR("Not an attribute... NIY\n"); 00837 ptd->ptr -= 2; 00838 return -1; 00839 } 00840 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00841 } 00842 break; 00843 } 00844 /* then the real definitions */ 00845 switch (*ptd->ptr++) 00846 { 00847 case '*': 00848 case '&': 00849 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); 00850 new_dt = &symt_new_pointer(ptd->module, ref_dt, sizeof(void*))->symt; 00851 break; 00852 case 'k': /* 'const' modifier */ 00853 case 'B': /* 'volatile' modifier */ 00854 /* just kinda ignore the modifier, I guess -gmt */ 00855 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, typename, &new_dt) == -1); 00856 break; 00857 case '(': 00858 ptd->ptr--; 00859 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, typename, &new_dt) == -1); 00860 break; 00861 case 'a': 00862 PTS_ABORTIF(ptd, stabs_pts_read_array(ptd, &new_dt) == -1); 00863 break; 00864 case 'r': 00865 PTS_ABORTIF(ptd, stabs_pts_read_range(ptd, typename, &new_dt) == -1); 00866 assert(!*stabs_find_ref(filenr1, subnr1)); 00867 *stabs_find_ref(filenr1, subnr1) = new_dt; 00868 break; 00869 case 'f': 00870 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); 00871 new_dt = &symt_new_function_signature(ptd->module, ref_dt, -1)->symt; 00872 break; 00873 case 'e': 00874 stabs_get_basic(ptd, 1 /* int */, &ref_dt); 00875 new_dt = &symt_new_enum(ptd->module, typename, ref_dt)->symt; 00876 PTS_ABORTIF(ptd, stabs_pts_read_enum(ptd, (struct symt_enum*)new_dt) == -1); 00877 break; 00878 case 's': 00879 case 'u': 00880 { 00881 struct symt_udt* udt; 00882 enum UdtKind kind = (ptd->ptr[-1] == 's') ? UdtStruct : UdtUnion; 00883 /* udt can have been already defined in a forward definition */ 00884 udt = (struct symt_udt*)*stabs_find_ref(filenr1, subnr1); 00885 if (!udt) 00886 { 00887 udt = symt_new_udt(ptd->module, typename, 0, kind); 00888 /* we need to set it here, because a struct can hold a pointer 00889 * to itself 00890 */ 00891 new_dt = *stabs_find_ref(filenr1, subnr1) = &udt->symt; 00892 } 00893 else 00894 { 00895 unsigned l1, l2; 00896 if (udt->symt.tag != SymTagUDT) 00897 { 00898 ERR("Forward declaration (%p/%s) is not an aggregate (%u)\n", 00899 udt, symt_get_name(&udt->symt), udt->symt.tag); 00900 return -1; 00901 } 00902 /* FIXME: we currently don't correctly construct nested C++ 00903 * classes names. Therefore, we could be here with either: 00904 * - typename and udt->hash_elt.name being the same string 00905 * (non embedded case) 00906 * - typename being foo::bar while udt->hash_elt.name being 00907 * just bar 00908 * So, we twist the comparison to test both occurrences. When 00909 * we have proper C++ types in this file, this twist has to be 00910 * removed 00911 */ 00912 l1 = strlen(udt->hash_elt.name); 00913 l2 = strlen(typename); 00914 if (l1 > l2 || strcmp(udt->hash_elt.name, typename + l2 - l1)) 00915 ERR("Forward declaration name mismatch %s <> %s\n", 00916 udt->hash_elt.name, typename); 00917 new_dt = &udt->symt; 00918 } 00919 PTS_ABORTIF(ptd, stabs_pts_read_aggregate(ptd, udt) == -1); 00920 } 00921 break; 00922 case 'x': 00923 idx = ptd->idx; 00924 tmp = *ptd->ptr++; 00925 PTS_ABORTIF(ptd, stabs_pts_read_id(ptd) == -1); 00926 switch (tmp) 00927 { 00928 case 'e': 00929 stabs_get_basic(ptd, 1 /* int */, &ref_dt); 00930 new_dt = &symt_new_enum(ptd->module, ptd->buf + idx, ref_dt)->symt; 00931 break; 00932 case 's': 00933 new_dt = &symt_new_udt(ptd->module, ptd->buf + idx, 0, UdtStruct)->symt; 00934 break; 00935 case 'u': 00936 new_dt = &symt_new_udt(ptd->module, ptd->buf + idx, 0, UdtUnion)->symt; 00937 break; 00938 default: 00939 return -1; 00940 } 00941 ptd->idx = idx; 00942 break; 00943 case '-': 00944 { 00945 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &tmp) == -1); 00946 PTS_ABORTIF(ptd, stabs_get_basic(ptd, tmp, &new_dt) == -1); 00947 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); 00948 } 00949 break; 00950 case '#': 00951 if (*ptd->ptr == '#') 00952 { 00953 ptd->ptr++; 00954 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); 00955 new_dt = &symt_new_function_signature(ptd->module, ref_dt, -1)->symt; 00956 } 00957 else 00958 { 00959 struct symt* cls_dt; 00960 struct symt* pmt_dt; 00961 00962 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &cls_dt) == -1); 00963 PTS_ABORTIF(ptd, *ptd->ptr++ != ','); 00964 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); 00965 new_dt = &symt_new_function_signature(ptd->module, ref_dt, -1)->symt; 00966 while (*ptd->ptr == ',') 00967 { 00968 ptd->ptr++; 00969 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &pmt_dt) == -1); 00970 } 00971 } 00972 break; 00973 case 'R': 00974 { 00975 long type, len, unk; 00976 int basic; 00977 00978 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &type) == -1); 00979 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */ 00980 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &len) == -1); 00981 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */ 00982 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &unk) == -1); 00983 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */ 00984 00985 switch (type) /* see stabs_get_basic for the details */ 00986 { 00987 case 1: basic = 12; break; 00988 case 2: basic = 13; break; 00989 case 3: basic = 25; break; 00990 case 4: basic = 26; break; 00991 case 5: basic = 35; break; 00992 case 6: basic = 14; break; 00993 default: PTS_ABORTIF(ptd, 1); 00994 } 00995 PTS_ABORTIF(ptd, stabs_get_basic(ptd, basic, &new_dt) == -1); 00996 } 00997 break; 00998 default: 00999 ERR("Unknown type '%c'\n", ptd->ptr[-1]); 01000 return -1; 01001 } 01002 } 01003 01004 if (!new_dt) 01005 { 01006 /* is it a forward declaration that has been filled ? */ 01007 new_dt = *stabs_find_ref(filenr1, subnr1); 01008 /* if not, this should be void (which is defined as a ref to itself, but we 01009 * don't correctly catch it) 01010 */ 01011 if (!new_dt && typename) 01012 { 01013 new_dt = &symt_new_basic(ptd->module, btVoid, typename, 0)->symt; 01014 PTS_ABORTIF(ptd, strcmp(typename, "void")); 01015 } 01016 } 01017 01018 *stabs_find_ref(filenr1, subnr1) = *ret_dt = new_dt; 01019 01020 TRACE("Adding (%ld,%ld) %s\n", filenr1, subnr1, debugstr_a(typename)); 01021 01022 return 0; 01023 } 01024 01025 static int stabs_parse_typedef(struct module* module, const char* ptr, 01026 const char* typename) 01027 { 01028 struct ParseTypedefData ptd; 01029 struct symt* dt; 01030 int ret = -1; 01031 01032 /* check for already existing definition */ 01033 01034 TRACE("%s => %s\n", typename, debugstr_a(ptr)); 01035 ptd.module = module; 01036 ptd.idx = 0; 01037 #ifdef PTS_DEBUG 01038 ptd.err_idx = 0; 01039 #endif 01040 for (ptd.ptr = ptr - 1; ;) 01041 { 01042 ptd.ptr = strchr(ptd.ptr + 1, ':'); 01043 if (ptd.ptr == NULL || *++ptd.ptr != ':') break; 01044 } 01045 if (ptd.ptr) 01046 { 01047 if (*ptd.ptr != '(') ptd.ptr++; 01048 /* most of type definitions take one char, except Tt */ 01049 if (*ptd.ptr != '(') ptd.ptr++; 01050 ret = stabs_pts_read_type_def(&ptd, typename, &dt); 01051 } 01052 01053 if (ret == -1 || *ptd.ptr) 01054 { 01055 #ifdef PTS_DEBUG 01056 int i; 01057 TRACE("Failure on %s\n", debugstr_a(ptr)); 01058 if (ret == -1) 01059 { 01060 for (i = 0; i < ptd.err_idx; i++) 01061 { 01062 TRACE("[%d]: line %d => %s\n", 01063 i, ptd.errors[i].line, debugstr_a(ptd.errors[i].ptr)); 01064 } 01065 } 01066 else 01067 TRACE("[0]: => %s\n", debugstr_a(ptd.ptr)); 01068 01069 #else 01070 ERR("Failure on %s at %s\n", debugstr_a(ptr), debugstr_a(ptd.ptr)); 01071 #endif 01072 return FALSE; 01073 } 01074 01075 return TRUE; 01076 } 01077 01078 static struct symt* stabs_parse_type(const char* stab) 01079 { 01080 const char* c = stab - 1; 01081 01082 /* 01083 * Look through the stab definition, and figure out what struct symt 01084 * this represents. If we have something we know about, assign the 01085 * type. 01086 * According to "The \"stabs\" debug format" (Rev 2.130) the name may be 01087 * a C++ name and contain double colons e.g. foo::bar::baz:t5=*6. 01088 */ 01089 do 01090 { 01091 if ((c = strchr(c + 1, ':')) == NULL) return NULL; 01092 } while (*++c == ':'); 01093 01094 /* 01095 * The next characters say more about the type (i.e. data, function, etc) 01096 * of symbol. Skip them. (C++ for example may have Tt). 01097 * Actually this is a very weak description; I think Tt is the only 01098 * multiple combination we should see. 01099 */ 01100 while (*c && *c != '(' && !isdigit(*c)) 01101 c++; 01102 /* 01103 * The next is either an integer or a (integer,integer). 01104 * The stabs_read_type_enum() takes care that stab_types is large enough. 01105 */ 01106 return *stabs_read_type_enum(&c); 01107 } 01108 01109 enum pending_obj_kind 01110 { 01111 PENDING_VAR, 01112 PENDING_LINE, 01113 }; 01114 01115 struct pending_loc_var 01116 { 01117 char name[256]; 01118 struct symt* type; 01119 enum DataKind kind; 01120 struct location loc; 01121 }; 01122 01123 struct pending_line 01124 { 01125 int source_idx; 01126 int line_num; 01127 unsigned long offset; 01128 unsigned long load_offset; 01129 }; 01130 01131 struct pending_object 01132 { 01133 enum pending_obj_kind tag; 01134 union { 01135 struct pending_loc_var var; 01136 struct pending_line line; 01137 } u; 01138 }; 01139 01140 struct pending_list 01141 { 01142 struct pending_object* objs; 01143 unsigned num; 01144 unsigned allocated; 01145 }; 01146 01147 static inline void pending_make_room(struct pending_list* pending) 01148 { 01149 if (pending->num == pending->allocated) 01150 { 01151 if (!pending->objs) 01152 { 01153 pending->allocated = 8; 01154 pending->objs = HeapAlloc(GetProcessHeap(), 0, 01155 pending->allocated * sizeof(pending->objs[0])); 01156 } 01157 else 01158 { 01159 pending->allocated *= 2; 01160 pending->objs = HeapReAlloc(GetProcessHeap(), 0, pending->objs, 01161 pending->allocated * sizeof(pending->objs[0])); 01162 } 01163 } 01164 } 01165 01166 static inline void pending_add_var(struct pending_list* pending, const char* name, 01167 enum DataKind dt, const struct location* loc) 01168 { 01169 pending_make_room(pending); 01170 pending->objs[pending->num].tag = PENDING_VAR; 01171 stab_strcpy(pending->objs[pending->num].u.var.name, 01172 sizeof(pending->objs[pending->num].u.var.name), name); 01173 pending->objs[pending->num].u.var.type = stabs_parse_type(name); 01174 pending->objs[pending->num].u.var.kind = dt; 01175 pending->objs[pending->num].u.var.loc = *loc; 01176 pending->num++; 01177 } 01178 01179 static inline void pending_add_line(struct pending_list* pending, int source_idx, 01180 int line_num, unsigned long offset, 01181 unsigned long load_offset) 01182 { 01183 pending_make_room(pending); 01184 pending->objs[pending->num].tag = PENDING_LINE; 01185 pending->objs[pending->num].u.line.source_idx = source_idx; 01186 pending->objs[pending->num].u.line.line_num = line_num; 01187 pending->objs[pending->num].u.line.offset = offset; 01188 pending->objs[pending->num].u.line.load_offset = load_offset; 01189 pending->num++; 01190 } 01191 01192 static void pending_flush(struct pending_list* pending, struct module* module, 01193 struct symt_function* func, struct symt_block* block) 01194 { 01195 unsigned int i; 01196 01197 for (i = 0; i < pending->num; i++) 01198 { 01199 switch (pending->objs[i].tag) 01200 { 01201 case PENDING_VAR: 01202 symt_add_func_local(module, func, 01203 pending->objs[i].u.var.kind, &pending->objs[i].u.var.loc, 01204 block, pending->objs[i].u.var.type, pending->objs[i].u.var.name); 01205 break; 01206 case PENDING_LINE: 01207 if (module->type == DMT_MACHO) 01208 pending->objs[i].u.line.offset -= func->address - pending->objs[i].u.line.load_offset; 01209 symt_add_func_line(module, func, pending->objs[i].u.line.source_idx, 01210 pending->objs[i].u.line.line_num, pending->objs[i].u.line.offset); 01211 break; 01212 default: 01213 ERR("Unknown pending object tag %u\n", (unsigned)pending->objs[i].tag); 01214 break; 01215 } 01216 } 01217 pending->num = 0; 01218 } 01219 01220 /****************************************************************** 01221 * stabs_finalize_function 01222 * 01223 * Ends function creation: mainly: 01224 * - cleans up line number information 01225 * - tries to set up a debug-start tag (FIXME: heuristic to be enhanced) 01226 * - for stabs which have absolute address in them, initializes the size of the 01227 * function (assuming that current function ends where next function starts) 01228 */ 01229 static void stabs_finalize_function(struct module* module, struct symt_function* func, 01230 unsigned long size) 01231 { 01232 IMAGEHLP_LINE64 il; 01233 struct location loc; 01234 01235 if (!func) return; 01236 symt_normalize_function(module, func); 01237 /* To define the debug-start of the function, we use the second line number. 01238 * Not 100% bullet proof, but better than nothing 01239 */ 01240 if (symt_fill_func_line_info(module, func, func->address, &il) && 01241 symt_get_func_line_next(module, &il)) 01242 { 01243 loc.kind = loc_absolute; 01244 loc.offset = il.Address - func->address; 01245 symt_add_function_point(module, func, SymTagFuncDebugStart, 01246 &loc, NULL); 01247 } 01248 if (size) func->size = size; 01249 } 01250 01251 static inline void stabbuf_append(char **buf, unsigned *buf_size, const char *str) 01252 { 01253 unsigned str_len, buf_len; 01254 01255 str_len = strlen(str); 01256 buf_len = strlen(*buf); 01257 01258 if(str_len+buf_len >= *buf_size) { 01259 *buf_size += buf_len + str_len; 01260 *buf = HeapReAlloc(GetProcessHeap(), 0, *buf, *buf_size); 01261 } 01262 01263 strcpy(*buf+buf_len, str); 01264 } 01265 01266 BOOL stabs_parse(struct module* module, unsigned long load_offset, 01267 const void* pv_stab_ptr, int stablen, 01268 const char* strs, int strtablen, 01269 stabs_def_cb callback, void* user) 01270 { 01271 struct symt_function* curr_func = NULL; 01272 struct symt_block* block = NULL; 01273 struct symt_compiland* compiland = NULL; 01274 char* srcpath = NULL; 01275 int i; 01276 int nstab; 01277 const char* ptr; 01278 char* stabbuff; 01279 unsigned int stabbufflen; 01280 const struct stab_nlist* stab_ptr = pv_stab_ptr; 01281 const char* strs_end; 01282 int strtabinc; 01283 char symname[4096]; 01284 unsigned incl[32]; 01285 int incl_stk = -1; 01286 int source_idx = -1; 01287 struct pending_list pending_block; 01288 struct pending_list pending_func; 01289 BOOL ret = TRUE; 01290 struct location loc; 01291 unsigned char type; 01292 01293 nstab = stablen / sizeof(struct stab_nlist); 01294 strs_end = strs + strtablen; 01295 01296 memset(stabs_basic, 0, sizeof(stabs_basic)); 01297 memset(&pending_block, 0, sizeof(pending_block)); 01298 memset(&pending_func, 0, sizeof(pending_func)); 01299 01300 /* 01301 * Allocate a buffer into which we can build stab strings for cases 01302 * where the stab is continued over multiple lines. 01303 */ 01304 stabbufflen = 65536; 01305 stabbuff = HeapAlloc(GetProcessHeap(), 0, stabbufflen); 01306 01307 strtabinc = 0; 01308 stabbuff[0] = '\0'; 01309 for (i = 0; i < nstab; i++, stab_ptr++) 01310 { 01311 ptr = strs + stab_ptr->n_strx; 01312 if ((ptr > strs_end) || (ptr + strlen(ptr) > strs_end)) 01313 { 01314 WARN("Bad stabs string %p\n", ptr); 01315 continue; 01316 } 01317 if (*ptr != '\0' && (ptr[strlen(ptr) - 1] == '\\')) 01318 { 01319 /* 01320 * Indicates continuation. Append this to the buffer, and go onto the 01321 * next record. Repeat the process until we find a stab without the 01322 * '/' character, as this indicates we have the whole thing. 01323 */ 01324 stabbuf_append(&stabbuff, &stabbufflen, ptr); 01325 continue; 01326 } 01327 else if (stabbuff[0] != '\0') 01328 { 01329 stabbuf_append(&stabbuff, &stabbufflen, ptr); 01330 ptr = stabbuff; 01331 } 01332 01333 if (stab_ptr->n_type & N_STAB) 01334 type = stab_ptr->n_type; 01335 else 01336 type = (stab_ptr->n_type & N_TYPE); 01337 01338 /* only symbol entries contain a typedef */ 01339 switch (type) 01340 { 01341 case N_GSYM: 01342 case N_LCSYM: 01343 case N_STSYM: 01344 case N_RSYM: 01345 case N_LSYM: 01346 case N_ROSYM: 01347 case N_PSYM: 01348 if (strchr(ptr, '=') != NULL) 01349 { 01350 /* 01351 * The stabs aren't in writable memory, so copy it over so we are 01352 * sure we can scribble on it. 01353 */ 01354 if (ptr != stabbuff) 01355 { 01356 stabbuff[0] = 0; 01357 stabbuf_append(&stabbuff, &stabbufflen, ptr); 01358 ptr = stabbuff; 01359 } 01360 stab_strcpy(symname, sizeof(symname), ptr); 01361 if (!stabs_parse_typedef(module, ptr, symname)) 01362 { 01363 /* skip this definition */ 01364 stabbuff[0] = '\0'; 01365 continue; 01366 } 01367 } 01368 } 01369 01370 switch (type) 01371 { 01372 case N_GSYM: 01373 /* 01374 * These are useless with ELF. They have no value, and you have to 01375 * read the normal symbol table to get the address. Thus we 01376 * ignore them, and when we process the normal symbol table 01377 * we should do the right thing. 01378 * 01379 * With a.out or mingw, they actually do make some amount of sense. 01380 */ 01381 stab_strcpy(symname, sizeof(symname), ptr); 01382 loc.kind = loc_absolute; 01383 loc.reg = 0; 01384 loc.offset = load_offset + stab_ptr->n_value; 01385 symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */, 01386 loc, 0, stabs_parse_type(ptr)); 01387 break; 01388 case N_LCSYM: 01389 case N_STSYM: 01390 /* These are static symbols and BSS symbols. */ 01391 stab_strcpy(symname, sizeof(symname), ptr); 01392 loc.kind = loc_absolute; 01393 loc.reg = 0; 01394 loc.offset = load_offset + stab_ptr->n_value; 01395 symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */, 01396 loc, 0, stabs_parse_type(ptr)); 01397 break; 01398 case N_LBRAC: 01399 if (curr_func) 01400 { 01401 block = symt_open_func_block(module, curr_func, block, 01402 stab_ptr->n_value, 0); 01403 pending_flush(&pending_block, module, curr_func, block); 01404 } 01405 break; 01406 case N_RBRAC: 01407 if (curr_func) 01408 block = symt_close_func_block(module, curr_func, block, 01409 stab_ptr->n_value); 01410 break; 01411 case N_PSYM: 01412 /* These are function parameters. */ 01413 if (curr_func != NULL) 01414 { 01415 struct symt* param_type = stabs_parse_type(ptr); 01416 stab_strcpy(symname, sizeof(symname), ptr); 01417 loc.kind = loc_regrel; 01418 loc.reg = dbghelp_current_cpu->frame_regno; 01419 loc.offset = stab_ptr->n_value; 01420 symt_add_func_local(module, curr_func, 01421 (int)stab_ptr->n_value >= 0 ? DataIsParam : DataIsLocal, 01422 &loc, NULL, param_type, symname); 01423 symt_add_function_signature_parameter(module, 01424 (struct symt_function_signature*)curr_func->type, 01425 param_type); 01426 } 01427 break; 01428 case N_RSYM: 01429 /* These are registers (as local variables) */ 01430 if (curr_func != NULL) 01431 { 01432 loc.kind = loc_register; 01433 loc.offset = 0; 01434 01435 switch (stab_ptr->n_value) 01436 { 01437 case 0: loc.reg = CV_REG_EAX; break; 01438 case 1: loc.reg = CV_REG_ECX; break; 01439 case 2: loc.reg = CV_REG_EDX; break; 01440 case 3: loc.reg = CV_REG_EBX; break; 01441 case 4: loc.reg = CV_REG_ESP; break; 01442 case 5: loc.reg = CV_REG_EBP; break; 01443 case 6: loc.reg = CV_REG_ESI; break; 01444 case 7: loc.reg = CV_REG_EDI; break; 01445 case 11: 01446 case 12: 01447 case 13: 01448 case 14: 01449 case 15: 01450 case 16: 01451 case 17: 01452 case 18: 01453 case 19: loc.reg = CV_REG_ST0 + stab_ptr->n_value - 12; break; 01454 case 21: 01455 case 22: 01456 case 23: 01457 case 24: 01458 case 25: 01459 case 26: 01460 case 27: 01461 case 28: loc.reg = CV_REG_XMM0 + stab_ptr->n_value - 21; break; 01462 case 29: 01463 case 30: 01464 case 31: 01465 case 32: 01466 case 33: 01467 case 34: 01468 case 35: 01469 case 36: loc.reg = CV_REG_MM0 + stab_ptr->n_value - 29; break; 01470 default: 01471 FIXME("Unknown register value (%u)\n", stab_ptr->n_value); 01472 loc.reg = CV_REG_NONE; 01473 break; 01474 } 01475 stab_strcpy(symname, sizeof(symname), ptr); 01476 if (ptr[strlen(symname) + 1] == 'P') 01477 { 01478 struct symt* param_type = stabs_parse_type(ptr); 01479 stab_strcpy(symname, sizeof(symname), ptr); 01480 symt_add_func_local(module, curr_func, DataIsParam, &loc, 01481 NULL, param_type, symname); 01482 symt_add_function_signature_parameter(module, 01483 (struct symt_function_signature*)curr_func->type, 01484 param_type); 01485 } 01486 else 01487 pending_add_var(&pending_block, ptr, DataIsLocal, &loc); 01488 } 01489 break; 01490 case N_LSYM: 01491 /* These are local variables */ 01492 loc.kind = loc_regrel; 01493 loc.reg = dbghelp_current_cpu->frame_regno; 01494 loc.offset = stab_ptr->n_value; 01495 if (curr_func != NULL) pending_add_var(&pending_block, ptr, DataIsLocal, &loc); 01496 break; 01497 case N_SLINE: 01498 /* 01499 * This is a line number. These are always relative to the start 01500 * of the function (N_FUN), and this makes the lookup easier. 01501 */ 01502 assert(source_idx >= 0); 01503 if (curr_func != NULL) 01504 { 01505 unsigned long offset = stab_ptr->n_value; 01506 if (module->type == DMT_MACHO) 01507 offset -= curr_func->address - load_offset; 01508 symt_add_func_line(module, curr_func, source_idx, 01509 stab_ptr->n_desc, offset); 01510 } 01511 else pending_add_line(&pending_func, source_idx, stab_ptr->n_desc, 01512 stab_ptr->n_value, load_offset); 01513 break; 01514 case N_FUN: 01515 /* 01516 * For now, just declare the various functions. Later 01517 * on, we will add the line number information and the 01518 * local symbols. 01519 */ 01520 /* 01521 * Copy the string to a temp buffer so we 01522 * can kill everything after the ':'. We do 01523 * it this way because otherwise we end up dirtying 01524 * all of the pages related to the stabs, and that 01525 * sucks up swap space like crazy. 01526 */ 01527 stab_strcpy(symname, sizeof(symname), ptr); 01528 if (*symname) 01529 { 01530 struct symt_function_signature* func_type; 01531 01532 if (curr_func) 01533 { 01534 /* First, clean up the previous function we were working on. 01535 * Assume size of the func is the delta between current offset 01536 * and offset of last function 01537 */ 01538 stabs_finalize_function(module, curr_func, 01539 stab_ptr->n_value ? 01540 (load_offset + stab_ptr->n_value - curr_func->address) : 0); 01541 } 01542 func_type = symt_new_function_signature(module, 01543 stabs_parse_type(ptr), -1); 01544 curr_func = symt_new_function(module, compiland, symname, 01545 load_offset + stab_ptr->n_value, 0, 01546 &func_type->symt); 01547 pending_flush(&pending_func, module, curr_func, NULL); 01548 } 01549 else 01550 { 01551 /* some versions of GCC to use a N_FUN "" to mark the end of a function 01552 * and n_value contains the size of the func 01553 */ 01554 stabs_finalize_function(module, curr_func, stab_ptr->n_value); 01555 curr_func = NULL; 01556 } 01557 break; 01558 case N_SO: 01559 /* 01560 * This indicates a new source file. Append the records 01561 * together, to build the correct path name. 01562 */ 01563 if (*ptr == '\0') /* end of N_SO file */ 01564 { 01565 /* Nuke old path. */ 01566 HeapFree(GetProcessHeap(), 0, srcpath); 01567 srcpath = NULL; 01568 stabs_finalize_function(module, curr_func, 0); 01569 curr_func = NULL; 01570 source_idx = -1; 01571 incl_stk = -1; 01572 assert(block == NULL); 01573 compiland = NULL; 01574 } 01575 else 01576 { 01577 int len = strlen(ptr); 01578 if (ptr[len-1] != '/') 01579 { 01580 stabs_reset_includes(); 01581 source_idx = source_new(module, srcpath, ptr); 01582 compiland = symt_new_compiland(module, 0 /* FIXME */, source_idx); 01583 } 01584 else 01585 { 01586 srcpath = HeapAlloc(GetProcessHeap(), 0, len + 1); 01587 strcpy(srcpath, ptr); 01588 } 01589 } 01590 break; 01591 case N_SOL: 01592 source_idx = source_new(module, srcpath, ptr); 01593 break; 01594 case N_UNDF: 01595 strs += strtabinc; 01596 strtabinc = stab_ptr->n_value; 01597 /* I'm not sure this is needed, so trace it before we obsolete it */ 01598 if (curr_func) 01599 { 01600 FIXME("UNDF: curr_func %s\n", curr_func->hash_elt.name); 01601 stabs_finalize_function(module, curr_func, 0); /* FIXME */ 01602 curr_func = NULL; 01603 } 01604 break; 01605 case N_OPT: 01606 /* Ignore this. We don't care what it points to. */ 01607 break; 01608 case N_BINCL: 01609 stabs_add_include(stabs_new_include(ptr, stab_ptr->n_value)); 01610 assert(incl_stk < (int)(sizeof(incl) / sizeof(incl[0])) - 1); 01611 incl[++incl_stk] = source_idx; 01612 source_idx = source_new(module, NULL, ptr); 01613 break; 01614 case N_EINCL: 01615 assert(incl_stk >= 0); 01616 source_idx = incl[incl_stk--]; 01617 break; 01618 case N_EXCL: 01619 if (stabs_add_include(stabs_find_include(ptr, stab_ptr->n_value)) < 0) 01620 { 01621 ERR("Excluded header not found (%s,%d)\n", ptr, stab_ptr->n_value); 01622 module_reset_debug_info(module); 01623 ret = FALSE; 01624 goto done; 01625 } 01626 break; 01627 case N_MAIN: 01628 /* Always ignore these. GCC doesn't even generate them. */ 01629 break; 01630 case N_BNSYM: 01631 case N_ENSYM: 01632 case N_OSO: 01633 /* Always ignore these, they seem to be used only on Darwin. */ 01634 break; 01635 case N_ABS: 01636 #ifdef N_SECT 01637 case N_SECT: 01638 #endif 01639 /* FIXME: Other definition types (N_TEXT, N_DATA, N_BSS, ...)? */ 01640 if (callback) 01641 { 01642 BOOL is_public = (stab_ptr->n_type & N_EXT); 01643 BOOL is_global = is_public; 01644 01645 #ifdef N_PEXT 01646 /* "private extern"; shared among compilation units in a shared 01647 * library, but not accessible from outside the library. */ 01648 if (stab_ptr->n_type & N_PEXT) 01649 { 01650 is_public = FALSE; 01651 is_global = TRUE; 01652 } 01653 #endif 01654 01655 if (*ptr == '_') ptr++; 01656 stab_strcpy(symname, sizeof(symname), ptr); 01657 01658 callback(module, load_offset, symname, stab_ptr->n_value, 01659 is_public, is_global, stab_ptr->n_other, compiland, user); 01660 } 01661 break; 01662 default: 01663 ERR("Unknown stab type 0x%02x\n", type); 01664 break; 01665 } 01666 stabbuff[0] = '\0'; 01667 TRACE("0x%02x %x %s\n", 01668 stab_ptr->n_type, stab_ptr->n_value, debugstr_a(strs + stab_ptr->n_strx)); 01669 } 01670 module->module.SymType = SymDia; 01671 module->module.CVSig = 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24); 01672 /* FIXME: we could have a finer grain here */ 01673 module->module.LineNumbers = TRUE; 01674 module->module.GlobalSymbols = TRUE; 01675 module->module.TypeInfo = TRUE; 01676 module->module.SourceIndexed = TRUE; 01677 module->module.Publics = TRUE; 01678 done: 01679 HeapFree(GetProcessHeap(), 0, stabbuff); 01680 stabs_free_includes(); 01681 HeapFree(GetProcessHeap(), 0, pending_block.objs); 01682 HeapFree(GetProcessHeap(), 0, pending_func.objs); 01683 01684 return ret; 01685 } Generated on Thu May 24 2012 04:23:46 for ReactOS by
1.7.6.1
|