- now detecting Dwarf debug information in ELF modules (but don't load
[wine.git] / programs / winedbg / stabs.c
blobdd0a8d7e5f7646b1e7fd4de9db04b1825d12e3a3
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * File stabs.c - read stabs information from the wine executable itself.
6 * Copyright (C) 1996, Eric Youngdale.
7 * 1999-2003 Eric Pouech
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * Maintenance Information
25 * -----------------------
27 * For documentation on the stabs format see for example
28 * The "stabs" debug format
29 * by Julia Menapace, Jim Kingdon, David Mackenzie
30 * of Cygnus Support
31 * available (hopefully) from http:\\sources.redhat.com\gdb\onlinedocs
34 #include "config.h"
36 #include <sys/types.h>
37 #include <fcntl.h>
38 #include <sys/stat.h>
39 #ifdef HAVE_SYS_MMAN_H
40 #include <sys/mman.h>
41 #endif
42 #include <limits.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #ifdef HAVE_UNISTD_H
46 # include <unistd.h>
47 #endif
48 #include <stdio.h>
49 #ifndef PATH_MAX
50 #define PATH_MAX MAX_PATH
51 #endif
53 #include "debugger.h"
55 #if defined(__svr4__) || defined(__sun)
56 #define __ELF__
57 #endif
59 #include "wine/debug.h"
61 WINE_DEFAULT_DEBUG_CHANNEL(winedbg_stabs);
63 #ifndef N_UNDF
64 #define N_UNDF 0x00
65 #endif
67 #ifndef STN_UNDEF
68 # define STN_UNDEF 0
69 #endif
71 #define N_GSYM 0x20
72 #define N_FUN 0x24
73 #define N_STSYM 0x26
74 #define N_LCSYM 0x28
75 #define N_MAIN 0x2a
76 #define N_ROSYM 0x2c
77 #define N_OPT 0x3c
78 #define N_RSYM 0x40
79 #define N_SLINE 0x44
80 #define N_SO 0x64
81 #define N_LSYM 0x80
82 #define N_BINCL 0x82
83 #define N_SOL 0x84
84 #define N_PSYM 0xa0
85 #define N_EINCL 0xa2
86 #define N_LBRAC 0xc0
87 #define N_EXCL 0xc2
88 #define N_RBRAC 0xe0
90 struct stab_nlist {
91 union {
92 char *n_name;
93 struct stab_nlist *n_next;
94 long n_strx;
95 } n_un;
96 unsigned char n_type;
97 char n_other;
98 short n_desc;
99 unsigned long n_value;
102 static void stab_strcpy(char * dest, int sz, const char * source)
105 * A strcpy routine that stops when we hit the ':' character.
106 * Faster than copying the whole thing, and then nuking the
107 * ':'.
109 while(*source != '\0' && *source != ':' && sz-- > 0)
110 *dest++ = *source++;
111 *dest = '\0';
112 assert(sz > 0);
115 typedef struct {
116 char* name;
117 unsigned long value;
118 int idx;
119 struct datatype** vector;
120 int nrofentries;
121 } include_def;
123 #define MAX_INCLUDES 5120
125 static include_def* include_defs = NULL;
126 static int num_include_def = 0;
127 static int num_alloc_include_def = 0;
128 static int cu_include_stack[MAX_INCLUDES];
129 static int cu_include_stk_idx = 0;
130 static struct datatype** cu_vector = NULL;
131 static int cu_nrofentries = 0;
133 static
135 DEBUG_CreateInclude(const char* file, unsigned long val)
137 if (num_include_def == num_alloc_include_def)
139 num_alloc_include_def += 256;
140 include_defs = DBG_realloc(include_defs, sizeof(include_defs[0])*num_alloc_include_def);
141 memset(include_defs+num_include_def, 0, sizeof(include_defs[0])*256);
143 include_defs[num_include_def].name = DBG_strdup(file);
144 include_defs[num_include_def].value = val;
145 include_defs[num_include_def].vector = NULL;
146 include_defs[num_include_def].nrofentries = 0;
148 return num_include_def++;
151 static
153 DEBUG_FindInclude(const char* file, unsigned long val)
155 int i;
157 for (i = 0; i < num_include_def; i++)
159 if (val == include_defs[i].value &&
160 strcmp(file, include_defs[i].name) == 0)
161 return i;
163 return -1;
166 static
168 DEBUG_AddInclude(int idx)
170 ++cu_include_stk_idx;
172 /* is this happen, just bump MAX_INCLUDES */
173 /* we could also handle this as another dynarray */
174 assert(cu_include_stk_idx < MAX_INCLUDES);
176 cu_include_stack[cu_include_stk_idx] = idx;
177 return cu_include_stk_idx;
180 static
181 void
182 DEBUG_ResetIncludes(void)
185 * The datatypes that we would need to use are reset when
186 * we start a new file. (at least the ones in filenr == 0
188 cu_include_stk_idx = 0;/* keep 0 as index for the .c file itself */
189 memset(cu_vector, 0, sizeof(cu_vector[0]) * cu_nrofentries);
192 static
193 void
194 DEBUG_FreeIncludes(void)
196 int i;
198 DEBUG_ResetIncludes();
200 for (i = 0; i < num_include_def; i++)
202 DBG_free(include_defs[i].name);
203 DBG_free(include_defs[i].vector);
205 DBG_free(include_defs);
206 include_defs = NULL;
207 num_include_def = 0;
208 num_alloc_include_def = 0;
209 DBG_free(cu_vector);
210 cu_vector = NULL;
211 cu_nrofentries = 0;
214 static
215 struct datatype**
216 DEBUG_FileSubNr2StabEnum(int filenr, int subnr)
218 struct datatype** ret;
220 WINE_TRACE("creating type id for (%d,%d)\n", filenr, subnr);
222 /* FIXME: I could perhaps create a dummy include_def for each compilation
223 * unit which would allow not to handle those two cases separately
225 if (filenr == 0)
227 if (cu_nrofentries <= subnr)
229 cu_vector = DBG_realloc(cu_vector, sizeof(cu_vector[0])*(subnr+1));
230 memset(cu_vector+cu_nrofentries, 0, sizeof(cu_vector[0])*(subnr+1-cu_nrofentries));
231 cu_nrofentries = subnr + 1;
233 ret = &cu_vector[subnr];
235 else
237 include_def* idef;
239 assert(filenr <= cu_include_stk_idx);
241 idef = &include_defs[cu_include_stack[filenr]];
243 if (idef->nrofentries <= subnr)
245 idef->vector = DBG_realloc(idef->vector, sizeof(idef->vector[0])*(subnr+1));
246 memset(idef->vector + idef->nrofentries, 0, sizeof(idef->vector[0])*(subnr+1-idef->nrofentries));
247 idef->nrofentries = subnr + 1;
249 ret = &idef->vector[subnr];
251 WINE_TRACE("(%d,%d) is %p\n",filenr,subnr,ret);
252 return ret;
255 static
256 struct datatype**
257 DEBUG_ReadTypeEnum(LPCSTR *x)
259 int filenr,subnr;
261 if (**x=='(') {
262 (*x)++; /* '(' */
263 filenr=strtol(*x,(char**)x,10); /* <int> */
264 (*x)++; /* ',' */
265 subnr=strtol(*x,(char**)x,10); /* <int> */
266 (*x)++; /* ')' */
267 } else {
268 filenr = 0;
269 subnr = strtol(*x,(char**)x,10); /* <int> */
271 return DEBUG_FileSubNr2StabEnum(filenr,subnr);
274 /*#define PTS_DEBUG*/
275 struct ParseTypedefData
277 const char* ptr;
278 char buf[1024];
279 int idx;
280 #ifdef PTS_DEBUG
281 struct PTS_Error
283 char* ptr;
284 unsigned line;
285 } errors[16];
286 int err_idx;
287 #endif
290 #ifdef PTS_DEBUG
291 static void PTS_Push(struct ParseTypedefData* ptd, unsigned line)
293 assert(ptd->err_idx < sizeof(ptd->errors) / sizeof(ptd->errors[0]));
294 ptd->errors[ptd->err_idx].line = line;
295 ptd->errors[ptd->err_idx].ptr = ptd->ptr;
296 ptd->err_idx++;
298 #define PTS_ABORTIF(ptd, t) do { if (t) { PTS_Push((ptd), __LINE__); return -1;} } while (0)
299 #else
300 #define PTS_ABORTIF(ptd, t) do { if (t) return -1; } while (0)
301 #endif
303 static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typename,
304 struct datatype** dt);
306 static int DEBUG_PTS_ReadID(struct ParseTypedefData* ptd)
308 const char* first = ptd->ptr;
309 unsigned int len;
311 PTS_ABORTIF(ptd, (ptd->ptr = strchr(ptd->ptr, ':')) == NULL);
312 len = ptd->ptr - first;
313 PTS_ABORTIF(ptd, len >= sizeof(ptd->buf) - ptd->idx);
314 memcpy(ptd->buf + ptd->idx, first, len);
315 ptd->buf[ptd->idx + len] = '\0';
316 ptd->idx += len + 1;
317 ptd->ptr++; /* ':' */
318 return 0;
321 static int DEBUG_PTS_ReadNum(struct ParseTypedefData* ptd, int* v)
323 char* last;
325 *v = strtol(ptd->ptr, &last, 10);
326 PTS_ABORTIF(ptd, last == ptd->ptr);
327 ptd->ptr = last;
328 return 0;
331 static int DEBUG_PTS_ReadTypeReference(struct ParseTypedefData* ptd,
332 int* filenr, int* subnr)
334 if (*ptd->ptr == '(') {
335 /* '(' <int> ',' <int> ')' */
336 ptd->ptr++;
337 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, filenr) == -1);
338 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
339 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, subnr) == -1);
340 PTS_ABORTIF(ptd, *ptd->ptr++ != ')');
341 } else {
342 *filenr = 0;
343 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, subnr) == -1);
345 return 0;
348 static int DEBUG_PTS_ReadRange(struct ParseTypedefData* ptd, struct datatype** dt,
349 int* lo, int* hi)
351 /* type ';' <int> ';' <int> ';' */
352 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, dt) == -1);
353 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
354 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, lo) == -1);
355 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
356 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, hi) == -1);
357 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
358 return 0;
361 static inline int DEBUG_PTS_ReadMethodInfo(struct ParseTypedefData* ptd)
363 struct datatype* dt;
364 char* tmp;
365 char mthd;
369 /* get type of return value */
370 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &dt) == -1);
371 if (*ptd->ptr == ';') ptd->ptr++;
373 /* get types of parameters */
374 if (*ptd->ptr == ':')
376 PTS_ABORTIF(ptd, !(tmp = strchr(ptd->ptr + 1, ';')));
377 ptd->ptr = tmp + 1;
379 PTS_ABORTIF(ptd, !(*ptd->ptr >= '0' && *ptd->ptr <= '9'));
380 ptd->ptr++;
381 PTS_ABORTIF(ptd, !(ptd->ptr[0] >= 'A' && *ptd->ptr <= 'D'));
382 mthd = *++ptd->ptr;
383 PTS_ABORTIF(ptd, mthd != '.' && mthd != '?' && mthd != '*');
384 ptd->ptr++;
385 if (mthd == '*')
387 int ofs;
388 struct datatype* dt;
390 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &ofs) == -1);
391 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
392 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &dt) == -1);
393 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
395 } while (*ptd->ptr != ';');
396 ptd->ptr++;
398 return 0;
401 static inline int DEBUG_PTS_ReadAggregate(struct ParseTypedefData* ptd,
402 struct datatype* sdt)
404 int sz, ofs;
405 struct datatype* adt;
406 struct datatype* dt = NULL;
407 int idx;
408 int doadd;
410 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &sz) == -1);
412 doadd = DEBUG_SetStructSize(sdt, sz);
413 if (*ptd->ptr == '!') /* C++ inheritence */
415 int num_classes;
416 char tmp[256];
418 ptd->ptr++;
419 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &num_classes) == -1);
420 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
421 while (--num_classes >= 0)
423 ptd->ptr += 2; /* skip visibility and inheritence */
424 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &ofs) == -1);
425 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
427 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &adt) == -1);
429 snprintf(tmp, sizeof(tmp), "__inherited_class_%s", DEBUG_GetName(adt));
430 /* FIXME: DEBUG_GetObjectSize will not always work, especially when adt
431 * has just been seen as a forward definition and not the real stuff yet.
432 * As we don't use much the size of members in structs, this may not
433 * be much of a problem
435 if (doadd) DEBUG_AddStructElement(sdt, tmp, adt, ofs, DEBUG_GetObjectSize(adt) * 8);
436 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
440 /* if the structure has already been filled, just redo the parsing
441 * but don't store results into the struct
442 * FIXME: there's a quite ugly memory leak in there...
445 /* Now parse the individual elements of the structure/union. */
446 while (*ptd->ptr != ';')
448 /* agg_name : type ',' <int:offset> ',' <int:size> */
449 idx = ptd->idx;
451 if (ptd->ptr[0] == '$' && ptd->ptr[1] == 'v')
453 int x;
455 if (ptd->ptr[2] == 'f')
457 /* C++ virtual method table */
458 ptd->ptr += 3;
459 DEBUG_ReadTypeEnum(&ptd->ptr);
460 PTS_ABORTIF(ptd, *ptd->ptr++ != ':');
461 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &dt) == -1);
462 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
463 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &x) == -1);
464 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
465 ptd->idx = idx;
466 continue;
468 else if (ptd->ptr[2] == 'b')
470 ptd->ptr += 3;
471 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &dt) == -1);
472 PTS_ABORTIF(ptd, *ptd->ptr++ != ':');
473 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &dt) == -1);
474 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
475 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &x) == -1);
476 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
477 ptd->idx = idx;
478 continue;
482 PTS_ABORTIF(ptd, DEBUG_PTS_ReadID(ptd) == -1);
483 /* Ref. TSDF R2.130 Section 7.4. When the field name is a method name
484 * it is followed by two colons rather than one.
486 if (*ptd->ptr == ':')
488 ptd->ptr++;
489 DEBUG_PTS_ReadMethodInfo(ptd);
490 ptd->idx = idx;
491 continue;
493 else
495 /* skip C++ member protection /0 /1 or /2 */
496 if (*ptd->ptr == '/') ptd->ptr += 2;
498 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &adt) == -1);
500 switch (*ptd->ptr++)
502 case ',':
503 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &ofs) == -1);
504 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
505 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &sz) == -1);
506 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
508 if (doadd) DEBUG_AddStructElement(sdt, ptd->buf + idx, adt, ofs, sz);
509 break;
510 case ':':
512 char* tmp;
513 /* method parameters... terminated by ';' */
514 PTS_ABORTIF(ptd, !(tmp = strchr(ptd->ptr, ';')));
515 ptd->ptr = tmp + 1;
517 break;
518 default:
519 PTS_ABORTIF(ptd, TRUE);
521 ptd->idx = idx;
523 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
524 if (*ptd->ptr == '~')
526 ptd->ptr++;
527 PTS_ABORTIF(ptd, *ptd->ptr++ != '%');
528 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &dt) == -1);
529 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
531 return 0;
534 static inline int DEBUG_PTS_ReadEnum(struct ParseTypedefData* ptd,
535 struct datatype* edt)
537 int ofs;
538 int idx;
540 while (*ptd->ptr != ';') {
541 idx = ptd->idx;
542 PTS_ABORTIF(ptd, DEBUG_PTS_ReadID(ptd) == -1);
543 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &ofs) == -1);
544 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
545 DEBUG_AddStructElement(edt, ptd->buf + idx, NULL, ofs, 0);
546 ptd->idx = idx;
548 ptd->ptr++;
549 return 0;
552 static inline int DEBUG_PTS_ReadArray(struct ParseTypedefData* ptd,
553 struct datatype* adt)
555 int lo, hi;
556 struct datatype* rdt;
558 /* ar<typeinfo_nodef>;<int>;<int>;<typeinfo> */
560 PTS_ABORTIF(ptd, *ptd->ptr++ != 'r');
561 /* FIXME: range type is lost, always assume int */
562 PTS_ABORTIF(ptd, DEBUG_PTS_ReadRange(ptd, &rdt, &lo, &hi) == -1);
563 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &rdt) == -1);
565 DEBUG_SetArrayParams(adt, lo, hi, rdt);
566 return 0;
569 static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typename,
570 struct datatype** ret_dt)
572 int idx, lo, hi, sz = -1;
573 struct datatype* new_dt = NULL; /* newly created data type */
574 struct datatype* ref_dt; /* referenced data type (pointer...) */
575 struct datatype* dt1; /* intermediate data type (scope is limited) */
576 struct datatype* dt2; /* intermediate data type: t1=t2=new_dt */
577 int filenr1, subnr1;
579 /* things are a bit complicated because of the way the typedefs are stored inside
580 * the file (we cannot keep the struct datatype** around, because address can
581 * change when realloc is done, so we must call over and over
582 * DEBUG_FileSubNr2StabEnum to keep the correct values around
583 * (however, keeping struct datatype* is valid))
585 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypeReference(ptd, &filenr1, &subnr1) == -1);
587 while (*ptd->ptr == '=') {
588 ptd->ptr++;
589 PTS_ABORTIF(ptd, new_dt != NULL);
591 /* first handle attribute if any */
592 switch (*ptd->ptr) {
593 case '@':
594 if (*++ptd->ptr == 's') {
595 ptd->ptr++;
596 if (DEBUG_PTS_ReadNum(ptd, &sz) == -1) {
597 WINE_ERR("Not an attribute... NIY\n");
598 ptd->ptr -= 2;
599 return -1;
601 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
603 break;
605 /* then the real definitions */
606 switch (*ptd->ptr++) {
607 case '*':
608 case '&':
609 new_dt = DEBUG_NewDataType(DT_POINTER, NULL);
610 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1);
611 DEBUG_SetPointerType(new_dt, ref_dt);
612 break;
613 case 'k': /* 'const' modifier */
614 case 'B': /* 'volatile' modifier */
615 /* just kinda ignore the modifier, I guess -gmt */
616 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, typename, &new_dt) == -1);
617 break;
618 case '(':
619 ptd->ptr--;
620 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, typename, &new_dt) == -1);
621 break;
622 case 'a':
623 new_dt = DEBUG_NewDataType(DT_ARRAY, NULL);
624 PTS_ABORTIF(ptd, DEBUG_PTS_ReadArray(ptd, new_dt) == -1);
625 break;
626 case 'r':
627 new_dt = DEBUG_NewDataType(DT_BASIC, typename);
628 assert(!*DEBUG_FileSubNr2StabEnum(filenr1, subnr1));
629 *DEBUG_FileSubNr2StabEnum(filenr1, subnr1) = new_dt;
630 PTS_ABORTIF(ptd, DEBUG_PTS_ReadRange(ptd, &ref_dt, &lo, &hi) == -1);
631 /* should perhaps do more here... */
632 break;
633 case 'f':
634 new_dt = DEBUG_NewDataType(DT_FUNC, NULL);
635 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1);
636 DEBUG_SetPointerType(new_dt, ref_dt);
637 break;
638 case 'e':
639 new_dt = DEBUG_NewDataType(DT_ENUM, NULL);
640 PTS_ABORTIF(ptd, DEBUG_PTS_ReadEnum(ptd, new_dt) == -1);
641 break;
642 case 's':
643 case 'u':
644 /* dt1 can have been already defined in a forward definition */
645 dt1 = *DEBUG_FileSubNr2StabEnum(filenr1, subnr1);
646 dt2 = DEBUG_TypeCast(DT_STRUCT, typename);
647 if (!dt1) {
648 new_dt = DEBUG_NewDataType(DT_STRUCT, typename);
649 /* we need to set it here, because a struct can hold a pointer
650 * to itself
652 *DEBUG_FileSubNr2StabEnum(filenr1, subnr1) = new_dt;
653 } else {
654 if (DEBUG_GetType(dt1) != DT_STRUCT) {
655 WINE_ERR("Forward declaration is not an aggregate\n");
656 return -1;
659 /* should check typename is the same too */
660 new_dt = dt1;
662 PTS_ABORTIF(ptd, DEBUG_PTS_ReadAggregate(ptd, new_dt) == -1);
663 break;
664 case 'x':
665 switch (*ptd->ptr++) {
666 case 'e': lo = DT_ENUM; break;
667 case 's': case 'u': lo = DT_STRUCT; break;
668 default: return -1;
671 idx = ptd->idx;
672 PTS_ABORTIF(ptd, DEBUG_PTS_ReadID(ptd) == -1);
673 new_dt = DEBUG_NewDataType(lo, ptd->buf + idx);
674 ptd->idx = idx;
675 break;
676 case '-':
678 enum debug_type_basic basic = DT_BASIC_LAST;
680 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &lo) == -1);
682 switch (lo)
684 case 1: basic = DT_BASIC_INT; break;
685 case 2: basic = DT_BASIC_CHAR; break;
686 case 3: basic = DT_BASIC_SHORTINT; break;
687 case 4: basic = DT_BASIC_LONGINT; break;
688 case 5: basic = DT_BASIC_UCHAR; break;
689 case 6: basic = DT_BASIC_SCHAR; break;
690 case 7: basic = DT_BASIC_USHORTINT; break;
691 case 8: basic = DT_BASIC_UINT; break;
692 /* case 9: basic = DT_BASIC_UINT"; */
693 case 10: basic = DT_BASIC_ULONGINT; break;
694 case 11: basic = DT_BASIC_VOID; break;
695 case 12: basic = DT_BASIC_FLOAT; break;
696 case 13: basic = DT_BASIC_DOUBLE; break;
697 case 14: basic = DT_BASIC_LONGDOUBLE; break;
698 /* case 15: basic = DT_BASIC_INT; break; */
699 case 16:
700 switch (sz) {
701 case 32: basic = DT_BASIC_BOOL1; break;
702 case 16: basic = DT_BASIC_BOOL2; break;
703 case 8: basic = DT_BASIC_BOOL4; break;
705 break;
706 /* case 17: basic = DT_BASIC_SHORT real; break; */
707 /* case 18: basic = DT_BASIC_REAL; break; */
708 case 25: basic = DT_BASIC_CMPLX_FLOAT; break;
709 case 26: basic = DT_BASIC_CMPLX_DOUBLE; break;
710 /* case 30: basic = DT_BASIC_wchar"; break; */
711 case 31: basic = DT_BASIC_LONGLONGINT; break;
712 case 32: basic = DT_BASIC_ULONGLONGINT; break;
713 default:
714 PTS_ABORTIF(ptd, 1);
716 PTS_ABORTIF(ptd, !(new_dt = DEBUG_GetBasicType(basic)));
717 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
719 break;
720 case '#':
721 new_dt = DEBUG_NewDataType(DT_FUNC, NULL);
722 if (*ptd->ptr == '#')
724 ptd->ptr++;
725 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1);
726 DEBUG_SetPointerType(new_dt, ref_dt);
728 else
730 struct datatype* cls_dt;
731 struct datatype* pmt_dt;
733 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &cls_dt) == -1);
734 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
735 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1);
736 DEBUG_SetPointerType(new_dt, ref_dt);
737 while (*ptd->ptr == ',')
739 ptd->ptr++;
740 PTS_ABORTIF(ptd, DEBUG_PTS_ReadTypedef(ptd, NULL, &pmt_dt) == -1);
743 break;
744 case 'R':
746 enum debug_type_basic basic = DT_BASIC_LAST;
747 int type, len, unk;
749 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &type) == -1);
750 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
751 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &len) == -1);
752 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
753 PTS_ABORTIF(ptd, DEBUG_PTS_ReadNum(ptd, &unk) == -1);
754 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
756 switch (type)
758 case 1: basic = DT_BASIC_FLOAT; break;
759 case 2: basic = DT_BASIC_DOUBLE; break;
760 case 3: basic = DT_BASIC_CMPLX_FLOAT; break;
761 case 4: basic = DT_BASIC_CMPLX_DOUBLE; break;
762 case 5: basic = DT_BASIC_CMPLX_LONGDOUBLE; break;
763 case 6: basic = DT_BASIC_LONGDOUBLE; break;
764 default: PTS_ABORTIF(ptd, 1);
766 PTS_ABORTIF(ptd, !(new_dt = DEBUG_GetBasicType(basic)));
768 break;
769 default:
770 WINE_ERR("Unknown type '%c'\n", ptd->ptr[-1]);
771 return -1;
775 if (!new_dt)
777 /* is it a forward declaration that has been filled ? */
778 new_dt = *DEBUG_FileSubNr2StabEnum(filenr1, subnr1);
779 /* if not, this should then be a basic type: define it, or even void */
780 if (!new_dt)
781 new_dt = DEBUG_NewDataType(DT_BASIC, typename);
784 *DEBUG_FileSubNr2StabEnum(filenr1, subnr1) = *ret_dt = new_dt;
786 if (typename && WINE_TRACE_ON(winedbg_stabs)) {
787 DEBUG_Printf("Adding (%d,%d) %s => ", filenr1, subnr1, typename);
788 DEBUG_PrintTypeCast(new_dt);
789 DEBUG_Printf("\n");
792 return 0;
795 static int DEBUG_ParseTypedefStab(const char* ptr, const char* typename)
797 struct ParseTypedefData ptd;
798 struct datatype* dt;
799 int ret = -1;
801 /* check for already existing definition */
803 ptd.idx = 0;
804 #ifdef PTS_DEBUG
805 ptd.err_idx = 0;
806 #endif
807 for (ptd.ptr = ptr - 1; ;)
809 ptd.ptr = strchr(ptd.ptr + 1, ':');
810 if (ptd.ptr == NULL || *++ptd.ptr != ':') break;
813 if (ptd.ptr)
815 if (*ptd.ptr != '(') ptd.ptr++;
816 /* most of type definitions take one char, except Tt */
817 if (*ptd.ptr != '(') ptd.ptr++;
818 ret = DEBUG_PTS_ReadTypedef(&ptd, typename, &dt);
821 if (ret == -1 || *ptd.ptr) {
822 #ifdef PTS_DEBUG
823 int i;
824 WINE_TRACE("Failure on %s\n", ptr);
825 if (ret == -1)
827 for (i = 0; i < ptd.err_idx; i++)
829 WINE_TRACE("[%d]: line %d => %s\n",
830 i, ptd.errors[i].line, ptd.errors[i].ptr);
833 else
834 WINE_TRACE("[0]: => %s\n", ptd.ptr);
836 #else
837 WINE_ERR("Failure on %s at %s\n", ptr, ptd.ptr);
838 #endif
839 return FALSE;
842 return TRUE;
845 static struct datatype*
846 DEBUG_ParseStabType(const char* stab)
848 const char* c = stab - 1;
851 * Look through the stab definition, and figure out what datatype
852 * this represents. If we have something we know about, assign the
853 * type.
854 * According to "The \"stabs\" debug format" (Rev 2.130) the name may be
855 * a C++ name and contain double colons e.g. foo::bar::baz:t5=*6.
859 if ((c = strchr(c + 1, ':')) == NULL) return NULL;
860 } while (*++c == ':');
863 * The next characters say more about the type (i.e. data, function, etc)
864 * of symbol. Skip them. (C++ for example may have Tt).
865 * Actually this is a very weak description; I think Tt is the only
866 * multiple combination we should see.
868 while (*c && *c != '(' && !isdigit(*c))
869 c++;
871 * The next is either an integer or a (integer,integer).
872 * The DEBUG_ReadTypeEnum takes care that stab_types is large enough.
874 return *DEBUG_ReadTypeEnum(&c);
877 enum DbgInfoLoad DEBUG_ParseStabs(const char* addr, void* load_offset,
878 unsigned int staboff, int stablen,
879 unsigned int strtaboff, int strtablen)
881 struct name_hash* curr_func = NULL;
882 struct wine_locals* curr_loc = NULL;
883 struct name_hash* curr_sym = NULL;
884 char currpath[PATH_MAX];
885 int i;
886 int in_external_file = FALSE;
887 int last_nso = -1;
888 unsigned int len;
889 DBG_VALUE new_value;
890 int nstab;
891 const char* ptr;
892 char* stabbuff;
893 unsigned int stabbufflen;
894 const struct stab_nlist* stab_ptr;
895 const char* strs;
896 int strtabinc;
897 const char* subpath = NULL;
898 char symname[4096];
900 nstab = stablen / sizeof(struct stab_nlist);
901 stab_ptr = (struct stab_nlist *) (addr + staboff);
902 strs = (char *) (addr + strtaboff);
904 memset(currpath, 0, sizeof(currpath));
907 * Allocate a buffer into which we can build stab strings for cases
908 * where the stab is continued over multiple lines.
910 stabbufflen = 65536;
911 stabbuff = (char *) DBG_alloc(stabbufflen);
913 strtabinc = 0;
914 stabbuff[0] = '\0';
915 for (i = 0; i < nstab; i++, stab_ptr++)
917 ptr = strs + (unsigned int) stab_ptr->n_un.n_name;
918 if( ptr[strlen(ptr) - 1] == '\\' )
921 * Indicates continuation. Append this to the buffer, and go onto the
922 * next record. Repeat the process until we find a stab without the
923 * '/' character, as this indicates we have the whole thing.
925 len = strlen(ptr);
926 if( strlen(stabbuff) + len > stabbufflen )
928 stabbufflen += 65536;
929 stabbuff = (char *) DBG_realloc(stabbuff, stabbufflen);
931 strncat(stabbuff, ptr, len - 1);
932 continue;
934 else if( stabbuff[0] != '\0' )
936 strcat( stabbuff, ptr);
937 ptr = stabbuff;
940 if( strchr(ptr, '=') != NULL )
943 * The stabs aren't in writable memory, so copy it over so we are
944 * sure we can scribble on it.
946 if( ptr != stabbuff )
948 strcpy(stabbuff, ptr);
949 ptr = stabbuff;
951 stab_strcpy(symname, sizeof(symname), ptr);
952 if (!DEBUG_ParseTypedefStab(ptr, symname)) {
953 /* skip this definition */
954 stabbuff[0] = '\0';
955 continue;
959 switch(stab_ptr->n_type)
961 case N_GSYM:
963 * These are useless with ELF. They have no value, and you have to
964 * read the normal symbol table to get the address. Thus we
965 * ignore them, and when we process the normal symbol table
966 * we should do the right thing.
968 * With a.out or mingw, they actually do make some amount of sense.
970 new_value.type = DEBUG_ParseStabType(ptr);
971 new_value.addr.seg = 0;
972 new_value.cookie = DV_TARGET;
974 stab_strcpy(symname, sizeof(symname), ptr);
975 #ifdef __ELF__
976 /* EPP used to be: new_value.addr.off = 0; */
977 new_value.addr.off = (unsigned long)load_offset + stab_ptr->n_value;
978 curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
979 SYM_WINE | SYM_DATA | SYM_INVALID );
980 #else
981 new_value.addr.off = (unsigned long)load_offset + stab_ptr->n_value;
982 curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
983 SYM_WINE | SYM_DATA );
984 #endif
985 break;
986 case N_RBRAC:
987 case N_LBRAC:
989 * We need to keep track of these so we get symbol scoping
990 * right for local variables. For now, we just ignore them.
991 * The hooks are already there for dealing with this however,
992 * so all we need to do is to keep count of the nesting level,
993 * and find the RBRAC for each matching LBRAC.
995 break;
996 case N_LCSYM:
997 case N_STSYM:
999 * These are static symbols and BSS symbols.
1001 new_value.addr.seg = 0;
1002 new_value.type = DEBUG_ParseStabType(ptr);
1003 new_value.addr.off = (unsigned long)load_offset + stab_ptr->n_value;
1004 new_value.cookie = DV_TARGET;
1006 stab_strcpy(symname, sizeof(symname), ptr);
1007 curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
1008 SYM_WINE | SYM_DATA );
1009 break;
1010 case N_PSYM:
1012 * These are function parameters.
1014 if( curr_func != NULL && !in_external_file )
1016 stab_strcpy(symname, sizeof(symname), ptr);
1017 curr_loc = DEBUG_AddLocal( curr_func, 0,
1018 stab_ptr->n_value, 0, 0, symname );
1019 DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
1021 break;
1022 case N_RSYM:
1023 if( curr_func != NULL && !in_external_file )
1025 stab_strcpy(symname, sizeof(symname), ptr);
1026 curr_loc = DEBUG_AddLocal( curr_func, stab_ptr->n_value + 1,
1027 0, 0, 0, symname );
1028 DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
1030 break;
1031 case N_LSYM:
1032 if( curr_func != NULL && !in_external_file )
1034 stab_strcpy(symname, sizeof(symname), ptr);
1035 curr_loc = DEBUG_AddLocal( curr_func, 0,
1036 stab_ptr->n_value, 0, 0, symname );
1037 DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
1039 break;
1040 case N_SLINE:
1042 * This is a line number. These are always relative to the start
1043 * of the function (N_FUN), and this makes the lookup easier.
1045 if( curr_func != NULL && !in_external_file )
1047 #ifdef __ELF__
1048 DEBUG_AddLineNumber(curr_func, stab_ptr->n_desc,
1049 stab_ptr->n_value);
1050 #else
1051 #if 0
1053 * This isn't right. The order of the stabs is different under
1054 * a.out, and as a result we would end up attaching the line
1055 * number to the wrong function.
1057 DEBUG_AddLineNumber(curr_func, stab_ptr->n_desc,
1058 stab_ptr->n_value - curr_func->addr.off);
1059 #endif
1060 #endif
1062 break;
1063 case N_FUN:
1065 * First, clean up the previous function we were working on.
1067 DEBUG_Normalize(curr_func);
1070 * For now, just declare the various functions. Later
1071 * on, we will add the line number information and the
1072 * local symbols.
1074 if( !in_external_file)
1076 stab_strcpy(symname, sizeof(symname), ptr);
1077 if (*symname)
1079 new_value.addr.seg = 0;
1080 new_value.type = DEBUG_ParseStabType(ptr);
1081 new_value.addr.off = (unsigned long)load_offset + stab_ptr->n_value;
1082 new_value.cookie = DV_TARGET;
1084 * Copy the string to a temp buffer so we
1085 * can kill everything after the ':'. We do
1086 * it this way because otherwise we end up dirtying
1087 * all of the pages related to the stabs, and that
1088 * sucks up swap space like crazy.
1090 #ifdef __ELF__
1091 curr_func = DEBUG_AddSymbol( symname, &new_value, currpath,
1092 SYM_WINE | SYM_FUNC | SYM_INVALID );
1093 #else
1094 curr_func = DEBUG_AddSymbol( symname, &new_value, currpath,
1095 SYM_WINE | SYM_FUNC );
1096 #endif
1098 else
1100 /* some GCC seem to use a N_FUN "" to mark the end of a function */
1101 curr_func = NULL;
1104 else
1107 * Don't add line number information for this function
1108 * any more.
1110 curr_func = NULL;
1112 break;
1113 case N_SO:
1115 * This indicates a new source file. Append the records
1116 * together, to build the correct path name.
1118 #ifndef __ELF__
1120 * With a.out, there is no NULL string N_SO entry at the end of
1121 * the file. Thus when we find non-consecutive entries,
1122 * we consider that a new file is started.
1124 if( last_nso < i-1 )
1126 currpath[0] = '\0';
1127 DEBUG_Normalize(curr_func);
1128 curr_func = NULL;
1130 #endif
1132 if( *ptr == '\0' ) /* end of N_SO file */
1135 * Nuke old path.
1137 currpath[0] = '\0';
1138 DEBUG_Normalize(curr_func);
1139 curr_func = NULL;
1141 else
1143 if (*ptr != '/')
1144 strcat(currpath, ptr);
1145 else
1146 strcpy(currpath, ptr);
1147 subpath = ptr;
1148 DEBUG_ResetIncludes();
1150 last_nso = i;
1151 break;
1152 case N_SOL:
1154 * This indicates we are including stuff from an include file.
1155 * If this is the main source, enable the debug stuff, otherwise
1156 * ignore it.
1158 in_external_file = !(subpath == NULL || strcmp(ptr, subpath) == 0);
1159 in_external_file = FALSE; /* FIXME EPP hack FIXME */;
1160 break;
1161 case N_UNDF:
1162 strs += strtabinc;
1163 strtabinc = stab_ptr->n_value;
1164 DEBUG_Normalize(curr_func);
1165 curr_func = NULL;
1166 break;
1167 case N_OPT:
1169 * Ignore this. We don't care what it points to.
1171 break;
1172 case N_BINCL:
1173 DEBUG_AddInclude(DEBUG_CreateInclude(ptr, stab_ptr->n_value));
1174 break;
1175 case N_EINCL:
1176 break;
1177 case N_EXCL:
1178 DEBUG_AddInclude(DEBUG_FindInclude(ptr, stab_ptr->n_value));
1179 break;
1180 case N_MAIN:
1182 * Always ignore these. GCC doesn't even generate them.
1184 break;
1185 default:
1186 WINE_ERR("Unknown stab type 0x%02x\n", stab_ptr->n_type);
1187 break;
1190 stabbuff[0] = '\0';
1192 WINE_TRACE("0x%02x %x %s\n", stab_ptr->n_type,
1193 (unsigned int) stab_ptr->n_value,
1194 strs + (unsigned int) stab_ptr->n_un.n_name);
1197 DEBUG_FreeIncludes();
1199 return DIL_LOADED;