1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
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
31 * available (hopefully) from http:\\sources.redhat.com\gdb\onlinedocs
36 #include <sys/types.h>
39 #ifdef HAVE_SYS_MMAN_H
50 #define PATH_MAX MAX_PATH
55 #if defined(__svr4__) || defined(__sun)
59 #include "wine/debug.h"
61 WINE_DEFAULT_DEBUG_CHANNEL(winedbg_stabs
);
93 struct stab_nlist
*n_next
;
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
109 while(*source
!= '\0' && *source
!= ':' && sz
-- > 0)
119 struct datatype
** vector
;
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;
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
++;
153 DEBUG_FindInclude(const char* file
, unsigned long val
)
157 for (i
= 0; i
< num_include_def
; i
++)
159 if (val
== include_defs
[i
].value
&&
160 strcmp(file
, include_defs
[i
].name
) == 0)
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
;
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
);
194 DEBUG_FreeIncludes(void)
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
);
208 num_alloc_include_def
= 0;
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
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
];
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
);
257 DEBUG_ReadTypeEnum(LPCSTR
*x
)
263 filenr
=strtol(*x
,(char**)x
,10); /* <int> */
265 subnr
=strtol(*x
,(char**)x
,10); /* <int> */
269 subnr
= strtol(*x
,(char**)x
,10); /* <int> */
271 return DEBUG_FileSubNr2StabEnum(filenr
,subnr
);
274 /*#define PTS_DEBUG*/
275 struct ParseTypedefData
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
;
298 #define PTS_ABORTIF(ptd, t) do { if (t) { PTS_Push((ptd), __LINE__); return -1;} } while (0)
300 #define PTS_ABORTIF(ptd, t) do { if (t) return -1; } while (0)
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
;
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';
317 ptd
->ptr
++; /* ':' */
321 static int DEBUG_PTS_ReadNum(struct ParseTypedefData
* ptd
, int* v
)
325 *v
= strtol(ptd
->ptr
, &last
, 10);
326 PTS_ABORTIF(ptd
, last
== ptd
->ptr
);
331 static int DEBUG_PTS_ReadTypeReference(struct ParseTypedefData
* ptd
,
332 int* filenr
, int* subnr
)
334 if (*ptd
->ptr
== '(') {
335 /* '(' <int> ',' <int> ')' */
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
++ != ')');
343 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadNum(ptd
, subnr
) == -1);
348 static int DEBUG_PTS_ReadRange(struct ParseTypedefData
* ptd
, struct datatype
** dt
,
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
++ != ';'); /* ';' */
361 static inline int DEBUG_PTS_ReadMethodInfo(struct ParseTypedefData
* ptd
)
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, ';')));
379 PTS_ABORTIF(ptd
, !(*ptd
->ptr
>= '0' && *ptd
->ptr
<= '9'));
381 PTS_ABORTIF(ptd
, !(ptd
->ptr
[0] >= 'A' && *ptd
->ptr
<= 'D'));
383 PTS_ABORTIF(ptd
, mthd
!= '.' && mthd
!= '?' && mthd
!= '*');
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
!= ';');
401 static inline int DEBUG_PTS_ReadAggregate(struct ParseTypedefData
* ptd
,
402 struct datatype
* sdt
)
405 struct datatype
* adt
;
406 struct datatype
* dt
= NULL
;
410 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadNum(ptd
, &sz
) == -1);
412 doadd
= DEBUG_SetStructSize(sdt
, sz
);
413 if (*ptd
->ptr
== '!') /* C++ inheritence */
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> */
451 if (ptd
->ptr
[0] == '$' && ptd
->ptr
[1] == 'v')
455 if (ptd
->ptr
[2] == 'f')
457 /* C++ virtual method table */
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
++ != ';');
468 else if (ptd
->ptr
[2] == 'b')
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
++ != ';');
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
== ':')
489 DEBUG_PTS_ReadMethodInfo(ptd
);
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);
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
);
513 /* method parameters... terminated by ';' */
514 PTS_ABORTIF(ptd
, !(tmp
= strchr(ptd
->ptr
, ';')));
519 PTS_ABORTIF(ptd
, TRUE
);
523 PTS_ABORTIF(ptd
, *ptd
->ptr
++ != ';');
524 if (*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
++ != ';');
534 static inline int DEBUG_PTS_ReadEnum(struct ParseTypedefData
* ptd
,
535 struct datatype
* edt
)
540 while (*ptd
->ptr
!= ';') {
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);
552 static inline int DEBUG_PTS_ReadArray(struct ParseTypedefData
* ptd
,
553 struct datatype
* adt
)
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
);
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 */
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
== '=') {
589 PTS_ABORTIF(ptd
, new_dt
!= NULL
);
591 /* first handle attribute if any */
594 if (*++ptd
->ptr
== 's') {
596 if (DEBUG_PTS_ReadNum(ptd
, &sz
) == -1) {
597 WINE_ERR("Not an attribute... NIY\n");
601 PTS_ABORTIF(ptd
, *ptd
->ptr
++ != ';');
605 /* then the real definitions */
606 switch (*ptd
->ptr
++) {
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
);
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);
620 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadTypedef(ptd
, typename
, &new_dt
) == -1);
623 new_dt
= DEBUG_NewDataType(DT_ARRAY
, NULL
);
624 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadArray(ptd
, new_dt
) == -1);
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... */
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
);
639 new_dt
= DEBUG_NewDataType(DT_ENUM
, NULL
);
640 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadEnum(ptd
, new_dt
) == -1);
644 /* dt1 can have been already defined in a forward definition */
645 dt1
= *DEBUG_FileSubNr2StabEnum(filenr1
, subnr1
);
646 dt2
= DEBUG_TypeCast(DT_STRUCT
, typename
);
648 new_dt
= DEBUG_NewDataType(DT_STRUCT
, typename
);
649 /* we need to set it here, because a struct can hold a pointer
652 *DEBUG_FileSubNr2StabEnum(filenr1
, subnr1
) = new_dt
;
654 if (DEBUG_GetType(dt1
) != DT_STRUCT
) {
655 WINE_ERR("Forward declaration is not an aggregate\n");
659 /* should check typename is the same too */
662 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadAggregate(ptd
, new_dt
) == -1);
665 switch (*ptd
->ptr
++) {
666 case 'e': lo
= DT_ENUM
; break;
667 case 's': case 'u': lo
= DT_STRUCT
; break;
672 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadID(ptd
) == -1);
673 new_dt
= DEBUG_NewDataType(lo
, ptd
->buf
+ idx
);
678 enum debug_type_basic basic
= DT_BASIC_LAST
;
680 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadNum(ptd
, &lo
) == -1);
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; */
701 case 32: basic
= DT_BASIC_BOOL1
; break;
702 case 16: basic
= DT_BASIC_BOOL2
; break;
703 case 8: basic
= DT_BASIC_BOOL4
; 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;
716 PTS_ABORTIF(ptd
, !(new_dt
= DEBUG_GetBasicType(basic
)));
717 PTS_ABORTIF(ptd
, *ptd
->ptr
++ != ';');
721 new_dt
= DEBUG_NewDataType(DT_FUNC
, NULL
);
722 if (*ptd
->ptr
== '#')
725 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadTypedef(ptd
, NULL
, &ref_dt
) == -1);
726 DEBUG_SetPointerType(new_dt
, ref_dt
);
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
== ',')
740 PTS_ABORTIF(ptd
, DEBUG_PTS_ReadTypedef(ptd
, NULL
, &pmt_dt
) == -1);
746 enum debug_type_basic basic
= DT_BASIC_LAST
;
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
++ != ';'); /* ';' */
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
)));
770 WINE_ERR("Unknown type '%c'\n", ptd
->ptr
[-1]);
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 */
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
);
795 static int DEBUG_ParseTypedefStab(const char* ptr
, const char* typename
)
797 struct ParseTypedefData ptd
;
801 /* check for already existing definition */
807 for (ptd
.ptr
= ptr
- 1; ;)
809 ptd
.ptr
= strchr(ptd
.ptr
+ 1, ':');
810 if (ptd
.ptr
== NULL
|| *++ptd
.ptr
!= ':') break;
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
) {
824 WINE_TRACE("Failure on %s\n", ptr
);
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
);
834 WINE_TRACE("[0]: => %s\n", ptd
.ptr
);
837 WINE_ERR("Failure on %s at %s\n", ptr
, ptd
.ptr
);
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
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
))
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
];
886 int in_external_file
= FALSE
;
893 unsigned int stabbufflen
;
894 const struct stab_nlist
* stab_ptr
;
897 const char* subpath
= NULL
;
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.
911 stabbuff
= (char *) DBG_alloc(stabbufflen
);
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.
926 if( strlen(stabbuff
) + len
> stabbufflen
)
928 stabbufflen
+= 65536;
929 stabbuff
= (char *) DBG_realloc(stabbuff
, stabbufflen
);
931 strncat(stabbuff
, ptr
, len
- 1);
934 else if( stabbuff
[0] != '\0' )
936 strcat( stabbuff
, ptr
);
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
);
951 stab_strcpy(symname
, sizeof(symname
), ptr
);
952 if (!DEBUG_ParseTypedefStab(ptr
, symname
)) {
953 /* skip this definition */
959 switch(stab_ptr
->n_type
)
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
);
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
);
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
);
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.
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
);
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
) );
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,
1028 DEBUG_SetLocalSymbolType( curr_loc
, DEBUG_ParseStabType(ptr
) );
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
) );
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
)
1048 DEBUG_AddLineNumber(curr_func
, stab_ptr
->n_desc
,
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
);
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
1074 if( !in_external_file
)
1076 stab_strcpy(symname
, sizeof(symname
), ptr
);
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.
1091 curr_func
= DEBUG_AddSymbol( symname
, &new_value
, currpath
,
1092 SYM_WINE
| SYM_FUNC
| SYM_INVALID
);
1094 curr_func
= DEBUG_AddSymbol( symname
, &new_value
, currpath
,
1095 SYM_WINE
| SYM_FUNC
);
1100 /* some GCC seem to use a N_FUN "" to mark the end of a function */
1107 * Don't add line number information for this function
1115 * This indicates a new source file. Append the records
1116 * together, to build the correct path name.
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 )
1127 DEBUG_Normalize(curr_func
);
1132 if( *ptr
== '\0' ) /* end of N_SO file */
1138 DEBUG_Normalize(curr_func
);
1144 strcat(currpath
, ptr
);
1146 strcpy(currpath
, ptr
);
1148 DEBUG_ResetIncludes();
1154 * This indicates we are including stuff from an include file.
1155 * If this is the main source, enable the debug stuff, otherwise
1158 in_external_file
= !(subpath
== NULL
|| strcmp(ptr
, subpath
) == 0);
1159 in_external_file
= FALSE
; /* FIXME EPP hack FIXME */;
1163 strtabinc
= stab_ptr
->n_value
;
1164 DEBUG_Normalize(curr_func
);
1169 * Ignore this. We don't care what it points to.
1173 DEBUG_AddInclude(DEBUG_CreateInclude(ptr
, stab_ptr
->n_value
));
1178 DEBUG_AddInclude(DEBUG_FindInclude(ptr
, stab_ptr
->n_value
));
1182 * Always ignore these. GCC doesn't even generate them.
1186 WINE_ERR("Unknown stab type 0x%02x\n", stab_ptr
->n_type
);
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();