ReactOS 0.4.15-dev-7968-g24a56f8
stabs.c
Go to the documentation of this file.
1/*
2 * File stabs.c - read stabs information from the modules
3 *
4 * Copyright (C) 1996, Eric Youngdale.
5 * 1999-2005, Eric Pouech
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 *
21 *
22 * Maintenance Information
23 * -----------------------
24 *
25 * For documentation on the stabs format see for example
26 * The "stabs" debug format
27 * by Julia Menapace, Jim Kingdon, David Mackenzie
28 * of Cygnus Support
29 * available (hopefully) from http://sources.redhat.com/gdb/onlinedocs
30 */
31
32#include <sys/types.h>
33#include <fcntl.h>
34#include <limits.h>
35#include <stdint.h>
36#include <stdlib.h>
37#include <string.h>
38#include <stdio.h>
39#include <assert.h>
40#include <stdarg.h>
41
42#ifndef DBGHELP_STATIC_LIB
43#include "windef.h"
44#include "winbase.h"
45#include "winnls.h"
46#endif
47
48#include "dbghelp_private.h"
49#include "image_private.h"
50
51#ifndef DBGHELP_STATIC_LIB
52#include "wine/debug.h"
53#endif
54
56
57#ifndef DBGHELP_STATIC_LIB
58#define strtoull _strtoui64
59#endif
60
61/* Masks for n_type field */
62#define N_STAB 0xe0
63#define N_PEXT 0x10
64#define N_TYPE 0x1e
65#define N_EXT 0x01
66
67/* Values for (n_type & N_TYPE) */
68#define N_UNDF 0x00
69#define N_ABS 0x02
70#define N_INDR 0x0a
71#define N_SECT 0x0e
72
73#define N_GSYM 0x20
74#define N_FUN 0x24
75#define N_STSYM 0x26
76#define N_LCSYM 0x28
77#define N_MAIN 0x2a
78#define N_ROSYM 0x2c
79#define N_BNSYM 0x2e
80#define N_OPT 0x3c
81#define N_RSYM 0x40
82#define N_SLINE 0x44
83#define N_ENSYM 0x4e
84#define N_SO 0x64
85#define N_OSO 0x66
86#define N_LSYM 0x80
87#define N_BINCL 0x82
88#define N_SOL 0x84
89#define N_PSYM 0xa0
90#define N_EINCL 0xa2
91#define N_LBRAC 0xc0
92#define N_EXCL 0xc2
93#define N_RBRAC 0xe0
94
95static void stab_strcpy(char* dest, int sz, const char* source)
96{
97 char* ptr = dest;
98 /*
99 * A strcpy routine that stops when we hit the ':' character.
100 * Faster than copying the whole thing, and then nuking the
101 * ':'.
102 * Takes also care of (valid) a::b constructs
103 */
104 while (*source != '\0')
105 {
106 if (source[0] != ':' && sz-- > 0) *ptr++ = *source++;
107 else if (source[1] == ':' && (sz -= 2) > 0)
108 {
109 *ptr++ = *source++;
110 *ptr++ = *source++;
111 }
112 else break;
113 }
114 *ptr-- = '\0';
115 /* GCC emits, in some cases, a .<digit>+ suffix.
116 * This is used for static variable inside functions, so
117 * that we can have several such variables with same name in
118 * the same compilation unit
119 * We simply ignore that suffix when present (we also get rid
120 * of it in ELF symtab parsing)
121 */
122 if (ptr >= dest && isdigit(*ptr))
123 {
124 while (ptr > dest && isdigit(*ptr)) ptr--;
125 if (*ptr == '.') *ptr = '\0';
126 }
127 assert(sz > 0);
128}
129
130typedef struct
131{
132 char* name;
134 struct symt** vector;
137
138#define MAX_INCLUDES 5120
139
141static int num_include_def = 0;
144static int cu_include_stk_idx = 0;
145static struct symt** cu_vector = NULL;
146static int cu_nrofentries = 0;
147static struct symt_basic* stabs_basic[36];
148
149static int stabs_new_include(const char* file, ULONG_PTR val)
150{
152 {
153 if (!include_defs)
154 {
158 }
159 else
160 {
164 }
165 }
170
171 return num_include_def++;
172}
173
174static int stabs_find_include(const char* file, ULONG_PTR val)
175{
176 int i;
177
178 for (i = 0; i < num_include_def; i++)
179 {
180 if (val == include_defs[i].value &&
181 strcmp(file, include_defs[i].name) == 0)
182 return i;
183 }
184 return -1;
185}
186
187static int stabs_add_include(int idx)
188{
189 if (idx < 0) return -1;
191
192 /* if this happens, just bump MAX_INCLUDES */
193 /* we could also handle this as another dynarray */
196 return cu_include_stk_idx;
197}
198
199static void stabs_reset_includes(void)
200{
201 /*
202 * The struct symt:s that we would need to use are reset when
203 * we start a new file. (at least the ones in filenr == 0)
204 */
205 cu_include_stk_idx = 0;/* keep 0 as index for the .c file itself */
206 memset(cu_vector, 0, sizeof(cu_vector[0]) * cu_nrofentries);
207}
208
209static void stabs_free_includes(void)
210{
211 int i;
212
214 for (i = 0; i < num_include_def; i++)
215 {
218 }
221 num_include_def = 0;
224 cu_vector = NULL;
225 cu_nrofentries = 0;
226}
227
228static struct symt** stabs_find_ref(LONG_PTR filenr, LONG_PTR subnr)
229{
230 struct symt** ret;
231
232 /* FIXME: I could perhaps create a dummy include_def for each compilation
233 * unit which would allow not to handle those two cases separately
234 */
235 if (filenr == 0)
236 {
237 if (cu_nrofentries <= subnr)
238 {
239 cu_nrofentries = max( cu_nrofentries * 2, subnr + 1 );
240 if (!cu_vector)
242 sizeof(cu_vector[0]) * cu_nrofentries);
243 else
245 cu_vector, sizeof(cu_vector[0]) * cu_nrofentries);
246 }
247 ret = &cu_vector[subnr];
248 }
249 else
250 {
251 include_def* idef;
252
253 assert(filenr <= cu_include_stk_idx);
254 idef = &include_defs[cu_include_stack[filenr]];
255
256 if (idef->nrofentries <= subnr)
257 {
258 idef->nrofentries = max( idef->nrofentries * 2, subnr + 1 );
259 if (!idef->vector)
261 sizeof(idef->vector[0]) * idef->nrofentries);
262 else
264 idef->vector, sizeof(idef->vector[0]) * idef->nrofentries);
265 }
266 ret = &idef->vector[subnr];
267 }
268 TRACE("(%ld,%ld) => %p (%p)\n", filenr, subnr, ret, *ret);
269 return ret;
270}
271
272static struct symt** stabs_read_type_enum(const char** x)
273{
274 LONG_PTR filenr, subnr;
275 const char* iter;
276 char* end;
277
278 iter = *x;
279 if (*iter == '(')
280 {
281 ++iter; /* '(' */
282 filenr = strtol(iter, &end, 10); /* <int> */
283 iter = ++end; /* ',' */
284 subnr = strtol(iter, &end, 10); /* <int> */
285 iter = ++end; /* ')' */
286 }
287 else
288 {
289 filenr = 0;
290 subnr = strtol(iter, &end, 10); /* <int> */
291 iter = end;
292 }
293 *x = iter;
294 return stabs_find_ref(filenr, subnr);
295}
296
297#define PTS_DEBUG
299{
300 const char* ptr;
301 char buf[1024];
302 int idx;
303 struct module* module;
304#ifdef PTS_DEBUG
306 {
307 const char* ptr;
308 unsigned line;
309 } errors[16];
311#endif
312};
313
314#ifdef PTS_DEBUG
315static void stabs_pts_push(struct ParseTypedefData* ptd, unsigned line)
316{
317 assert(ptd->err_idx < ARRAY_SIZE(ptd->errors));
318 ptd->errors[ptd->err_idx].line = line;
319 ptd->errors[ptd->err_idx].ptr = ptd->ptr;
320 ptd->err_idx++;
321}
322#define PTS_ABORTIF(ptd, t) do { if (t) { stabs_pts_push((ptd), __LINE__); return -1;} } while (0)
323#else
324#define PTS_ABORTIF(ptd, t) do { if (t) return -1; } while (0)
325#endif
326
327static int stabs_get_basic(struct ParseTypedefData* ptd, unsigned basic, struct symt** symt)
328{
329 PTS_ABORTIF(ptd, basic >= ARRAY_SIZE(stabs_basic));
330
331 if (!stabs_basic[basic])
332 {
333 switch (basic)
334 {
335 case 1: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "int", 4); break;
336 case 2: stabs_basic[basic] = symt_new_basic(ptd->module, btChar, "char", 1); break;
337 case 3: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "short int", 2); break;
338 case 4: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "long int", 4); break;
339 case 5: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned char", 1); break;
340 case 6: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "signed char", 1); break;
341 case 7: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned short int", 2); break;
342 case 8: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned int", 4); break;
343 case 9: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned", 2); break;
344 case 10: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned long int", 2); break;
345 case 11: stabs_basic[basic] = symt_new_basic(ptd->module, btVoid, "void", 0); break;
346 case 12: stabs_basic[basic] = symt_new_basic(ptd->module, btFloat, "float", 4); break;
347 case 13: stabs_basic[basic] = symt_new_basic(ptd->module, btFloat, "double", 8); break;
348 case 14: stabs_basic[basic] = symt_new_basic(ptd->module, btFloat, "long double", 12); break;
349 case 15: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "integer", 4); break;
350 case 16: stabs_basic[basic] = symt_new_basic(ptd->module, btBool, "bool", 1); break;
351 /* case 17: short real */
352 /* case 18: real */
353 case 25: stabs_basic[basic] = symt_new_basic(ptd->module, btComplex, "float complex", 8); break;
354 case 26: stabs_basic[basic] = symt_new_basic(ptd->module, btComplex, "double complex", 16); break;
355 case 30: stabs_basic[basic] = symt_new_basic(ptd->module, btWChar, "wchar_t", 2); break;
356 case 31: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "long long int", 8); break;
357 case 32: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "long long unsigned", 8); break;
358 /* starting at 35 are wine extensions (especially for R implementation) */
359 case 35: stabs_basic[basic] = symt_new_basic(ptd->module, btComplex, "long double complex", 24); break;
360 default: PTS_ABORTIF(ptd, 1);
361 }
362 }
363 *symt = &stabs_basic[basic]->symt;
364 return 0;
365}
366
367static int stabs_pts_read_type_def(struct ParseTypedefData* ptd,
368 const char* typename, struct symt** dt);
369
370static int stabs_pts_read_id(struct ParseTypedefData* ptd)
371{
372 const char* first = ptd->ptr;
373 unsigned int template = 0;
374 char ch;
375
376 while ((ch = *ptd->ptr++) != '\0')
377 {
378 switch (ch)
379 {
380 case ':':
381 if (template == 0)
382 {
383 unsigned int len = ptd->ptr - first - 1;
384 PTS_ABORTIF(ptd, len >= sizeof(ptd->buf) - ptd->idx);
385 memcpy(ptd->buf + ptd->idx, first, len);
386 ptd->buf[ptd->idx + len] = '\0';
387 ptd->idx += len + 1;
388 return 0;
389 }
390 break;
391 case '<': template++; break;
392 case '>': PTS_ABORTIF(ptd, template == 0); template--; break;
393 }
394 }
395 return -1;
396}
397
399{
400 char* last;
401
402 *v = strtol(ptd->ptr, &last, 10);
403 PTS_ABORTIF(ptd, last == ptd->ptr);
404 ptd->ptr = last;
405 return 0;
406}
407
409 LONG_PTR* filenr, LONG_PTR* subnr)
410{
411 if (*ptd->ptr == '(')
412 {
413 /* '(' <int> ',' <int> ')' */
414 ptd->ptr++;
415 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, filenr) == -1);
416 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
417 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, subnr) == -1);
418 PTS_ABORTIF(ptd, *ptd->ptr++ != ')');
419 }
420 else
421 {
422 *filenr = 0;
423 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, subnr) == -1);
424 }
425 return 0;
426}
427
429{
431 int sign;
432};
433
435{
436 char* last;
437
438 switch (*ptd->ptr)
439 {
440 case '0':
441 while (*ptd->ptr == '0') ptd->ptr++;
442 if (*ptd->ptr >= '1' && *ptd->ptr <= '7')
443 {
444 switch (ptd->ptr[1])
445 {
446 case '0':
447 PTS_ABORTIF(ptd, ptd->ptr[0] != '1');
448 prv->sign = -1;
449 prv->val = 0;
450 while (isdigit(*ptd->ptr)) prv->val = (prv->val << 3) + *ptd->ptr++ - '0';
451 break;
452 case '7':
453 prv->sign = 1;
454 prv->val = 0;
455 while (isdigit(*ptd->ptr)) prv->val = (prv->val << 3) + *ptd->ptr++ - '0';
456 break;
457 default: PTS_ABORTIF(ptd, 1); break;
458 }
459 } else prv->sign = 0;
460 break;
461 case '-':
462 prv->sign = -1;
463 prv->val = strtoull(++ptd->ptr, &last, 10);
464 ptd->ptr = last;
465 break;
466 case '+':
467 default:
468 prv->sign = 1;
469 prv->val = strtoull(ptd->ptr, &last, 10);
470 ptd->ptr = last;
471 break;
472 }
473 return 0;
474}
475
476static int stabs_pts_read_range(struct ParseTypedefData* ptd, const char* typename,
477 struct symt** dt)
478{
479 struct symt* ref;
480 struct pts_range_value lo;
481 struct pts_range_value hi;
482 unsigned size;
483 enum BasicType bt;
484 int i;
485 ULONGLONG v;
486
487 /* type ';' <int> ';' <int> ';' */
488 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref) == -1);
489 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
490 PTS_ABORTIF(ptd, stabs_pts_read_range_value(ptd, &lo) == -1);
491 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
492 PTS_ABORTIF(ptd, stabs_pts_read_range_value(ptd, &hi) == -1);
493 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
494
495 /* basically, we don't use ref... in some cases, for example, float is declared
496 * as a derived type of int... which won't help us... so we guess the types
497 * from the various formats
498 */
499 if (lo.sign == 0 && hi.sign < 0)
500 {
501 bt = btUInt;
502 size = hi.val;
503 }
504 else if (lo.sign < 0 && hi.sign == 0)
505 {
506 bt = btUInt;
507 size = lo.val;
508 }
509 else if (lo.sign > 0 && hi.sign == 0)
510 {
511 bt = btFloat;
512 size = lo.val;
513 }
514 else if (lo.sign < 0 && hi.sign > 0)
515 {
516 v = 1 << 7;
517 for (i = 7; i < 64; i += 8)
518 {
519 if (lo.val == v && hi.val == v - 1)
520 {
521 bt = btInt;
522 size = (i + 1) / 8;
523 break;
524 }
525 v <<= 8;
526 }
527 PTS_ABORTIF(ptd, i >= 64);
528 }
529 else if (lo.sign == 0 && hi.sign > 0)
530 {
531 if (hi.val == 127) /* specific case for char... */
532 {
533 bt = btChar;
534 size = 1;
535 }
536 else
537 {
538 v = 1;
539 for (i = 8; i <= 64; i += 8)
540 {
541 v <<= 8;
542 if (hi.val + 1 == v)
543 {
544 bt = btUInt;
545 size = (i + 1) / 8;
546 break;
547 }
548 }
549 PTS_ABORTIF(ptd, i > 64);
550 }
551 }
552 else PTS_ABORTIF(ptd, 1);
553
554 *dt = &symt_new_basic(ptd->module, bt, typename, size)->symt;
555 return 0;
556}
557
558static inline int stabs_pts_read_method_info(struct ParseTypedefData* ptd)
559{
560 struct symt* dt;
561 const char* tmp;
562 char mthd;
563
564 do
565 {
566 /* get type of return value */
567 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1);
568 if (*ptd->ptr == ';') ptd->ptr++;
569
570 /* get types of parameters */
571 if (*ptd->ptr == ':')
572 {
573 PTS_ABORTIF(ptd, !(tmp = strchr(ptd->ptr + 1, ';')));
574 ptd->ptr = tmp + 1;
575 }
576 PTS_ABORTIF(ptd, !(*ptd->ptr >= '0' && *ptd->ptr <= '9'));
577 ptd->ptr++;
578 PTS_ABORTIF(ptd, !(ptd->ptr[0] >= 'A' && *ptd->ptr <= 'D'));
579 mthd = *++ptd->ptr;
580 PTS_ABORTIF(ptd, mthd != '.' && mthd != '?' && mthd != '*');
581 ptd->ptr++;
582 if (mthd == '*')
583 {
584 LONG_PTR ofs;
585
586 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &ofs) == -1);
587 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
588 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1);
589 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
590 }
591 } while (*ptd->ptr != ';');
592 ptd->ptr++;
593
594 return 0;
595}
596
597static inline int stabs_pts_read_aggregate(struct ParseTypedefData* ptd,
598 struct symt_udt* sdt)
599{
600 LONG_PTR sz, ofs;
601 struct symt* adt;
602 struct symt* dt = NULL;
603 int idx;
604 int doadd;
605
606 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &sz) == -1);
607
608 doadd = symt_set_udt_size(ptd->module, sdt, sz);
609 if (*ptd->ptr == '!') /* C++ inheritance */
610 {
611 LONG_PTR num_classes;
612
613 ptd->ptr++;
614 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &num_classes) == -1);
615 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
616 while (--num_classes >= 0)
617 {
618 ptd->ptr += 2; /* skip visibility and inheritance */
619 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &ofs) == -1);
620 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
621
622 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &adt) == -1);
623
624 if (doadd && adt)
625 {
626 char tmp[256];
628
629 strcpy(tmp, "__inherited_class_");
630 strcat(tmp, symt_get_name(adt));
631
632 /* FIXME: TI_GET_LENGTH will not always work, especially when adt
633 * has just been seen as a forward definition and not the real stuff
634 * yet.
635 * As we don't use much the size of members in structs, this may not
636 * be much of a problem
637 */
639 symt_add_udt_element(ptd->module, sdt, tmp, adt, ofs, (DWORD)size * 8);
640 }
641 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
642 }
643
644 }
645 /* if the structure has already been filled, just redo the parsing
646 * but don't store results into the struct
647 * FIXME: there's a quite ugly memory leak in there...
648 */
649
650 /* Now parse the individual elements of the structure/union. */
651 while (*ptd->ptr != ';')
652 {
653 /* agg_name : type ',' <int:offset> ',' <int:size> */
654 idx = ptd->idx;
655
656 if (ptd->ptr[0] == '$' && ptd->ptr[1] == 'v')
657 {
658 LONG_PTR x;
659
660 if (ptd->ptr[2] == 'f')
661 {
662 /* C++ virtual method table */
663 ptd->ptr += 3;
665 PTS_ABORTIF(ptd, *ptd->ptr++ != ':');
666 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1);
667 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
668 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &x) == -1);
669 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
670 ptd->idx = idx;
671 continue;
672 }
673 else if (ptd->ptr[2] == 'b')
674 {
675 ptd->ptr += 3;
676 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1);
677 PTS_ABORTIF(ptd, *ptd->ptr++ != ':');
678 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1);
679 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
680 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &x) == -1);
681 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
682 ptd->idx = idx;
683 continue;
684 }
685 }
686
687 PTS_ABORTIF(ptd, stabs_pts_read_id(ptd) == -1);
688 /* Ref. TSDF R2.130 Section 7.4. When the field name is a method name
689 * it is followed by two colons rather than one.
690 */
691 if (*ptd->ptr == ':')
692 {
693 ptd->ptr++;
695 ptd->idx = idx;
696 continue;
697 }
698 else
699 {
700 /* skip C++ member protection /0 /1 or /2 */
701 if (*ptd->ptr == '/') ptd->ptr += 2;
702 }
703 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &adt) == -1);
704
705 switch (*ptd->ptr++)
706 {
707 case ',':
708 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &ofs) == -1);
709 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
710 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &sz) == -1);
711 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
712
713 if (doadd) symt_add_udt_element(ptd->module, sdt, ptd->buf + idx, adt, ofs, sz);
714 break;
715 case ':':
716 {
717 const char* tmp;
718 /* method parameters... terminated by ';' */
719 PTS_ABORTIF(ptd, !(tmp = strchr(ptd->ptr, ';')));
720 ptd->ptr = tmp + 1;
721 }
722 break;
723 default:
724 PTS_ABORTIF(ptd, TRUE);
725 }
726 ptd->idx = idx;
727 }
728 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
729 if (*ptd->ptr == '~')
730 {
731 ptd->ptr++;
732 PTS_ABORTIF(ptd, *ptd->ptr++ != '%');
733 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &dt) == -1);
734 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
735 }
736 return 0;
737}
738
739static inline int stabs_pts_read_enum(struct ParseTypedefData* ptd,
740 struct symt_enum* edt)
741{
743 int idx;
744
745 while (*ptd->ptr != ';')
746 {
747 idx = ptd->idx;
748 PTS_ABORTIF(ptd, stabs_pts_read_id(ptd) == -1);
749 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &value) == -1);
750 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
751 symt_add_enum_element(ptd->module, edt, ptd->buf + idx, value);
752 ptd->idx = idx;
753 }
754 ptd->ptr++;
755 return 0;
756}
757
758static inline int stabs_pts_read_array(struct ParseTypedefData* ptd,
759 struct symt** adt)
760{
761 LONG_PTR lo, hi;
762 struct symt* range_dt;
763 struct symt* base_dt;
764
765 /* ar<typeinfo_nodef>;<int>;<int>;<typeinfo> */
766
767 PTS_ABORTIF(ptd, *ptd->ptr++ != 'r');
768
769 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &range_dt) == -1);
770 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
771 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &lo) == -1);
772 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
773 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &hi) == -1);
774 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
775
776 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &base_dt) == -1);
777
778 *adt = &symt_new_array(ptd->module, lo, hi, base_dt, range_dt)->symt;
779 return 0;
780}
781
782static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typename,
783 struct symt** ret_dt)
784{
785 int idx;
786 LONG_PTR sz = -1;
787 struct symt* new_dt = NULL; /* newly created data type */
788 struct symt* ref_dt; /* referenced data type (pointer...) */
789 LONG_PTR filenr1, subnr1, tmp;
790
791 /* things are a bit complicated because of the way the typedefs are stored inside
792 * the file, because addresses can change when realloc is done, so we must call
793 * over and over stabs_find_ref() to keep the correct values around
794 */
795 PTS_ABORTIF(ptd, stabs_pts_read_type_reference(ptd, &filenr1, &subnr1) == -1);
796
797 while (*ptd->ptr == '=')
798 {
799 ptd->ptr++;
800 PTS_ABORTIF(ptd, new_dt != NULL);
801
802 /* first handle attribute if any */
803 switch (*ptd->ptr)
804 {
805 case '@':
806 if (*++ptd->ptr == 's')
807 {
808 ptd->ptr++;
809 if (stabs_pts_read_number(ptd, &sz) == -1)
810 {
811 ERR("Not an attribute... NIY\n");
812 ptd->ptr -= 2;
813 return -1;
814 }
815 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
816 }
817 break;
818 }
819 /* then the real definitions */
820 switch (*ptd->ptr++)
821 {
822 case '*':
823 case '&':
824 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1);
825 new_dt = &symt_new_pointer(ptd->module, ref_dt, sizeof(void*))->symt;
826 break;
827 case 'k': /* 'const' modifier */
828 case 'B': /* 'volatile' modifier */
829 /* just kinda ignore the modifier, I guess -gmt */
830 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, typename, &new_dt) == -1);
831 break;
832 case '(':
833 ptd->ptr--;
834 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, typename, &new_dt) == -1);
835 break;
836 case 'a':
837 PTS_ABORTIF(ptd, stabs_pts_read_array(ptd, &new_dt) == -1);
838 break;
839 case 'r':
840 PTS_ABORTIF(ptd, stabs_pts_read_range(ptd, typename, &new_dt) == -1);
841 assert(!*stabs_find_ref(filenr1, subnr1));
842 *stabs_find_ref(filenr1, subnr1) = new_dt;
843 break;
844 case 'f':
845 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1);
846 new_dt = &symt_new_function_signature(ptd->module, ref_dt, -1)->symt;
847 break;
848 case 'e':
849 stabs_get_basic(ptd, 1 /* int */, &ref_dt);
850 new_dt = &symt_new_enum(ptd->module, typename, ref_dt)->symt;
851 PTS_ABORTIF(ptd, stabs_pts_read_enum(ptd, (struct symt_enum*)new_dt) == -1);
852 break;
853 case 's':
854 case 'u':
855 {
856 struct symt_udt* udt;
857 enum UdtKind kind = (ptd->ptr[-1] == 's') ? UdtStruct : UdtUnion;
858 /* udt can have been already defined in a forward definition */
859 udt = (struct symt_udt*)*stabs_find_ref(filenr1, subnr1);
860 if (!udt)
861 {
862 udt = symt_new_udt(ptd->module, typename, 0, kind);
863 /* we need to set it here, because a struct can hold a pointer
864 * to itself
865 */
866 new_dt = *stabs_find_ref(filenr1, subnr1) = &udt->symt;
867 }
868 else
869 {
870 unsigned l1, l2;
871 if (udt->symt.tag != SymTagUDT)
872 {
873 ERR("Forward declaration (%p/%s) is not an aggregate (%u)\n",
874 udt, symt_get_name(&udt->symt), udt->symt.tag);
875 return -1;
876 }
877 /* FIXME: we currently don't correctly construct nested C++
878 * classes names. Therefore, we could be here with either:
879 * - typename and udt->hash_elt.name being the same string
880 * (non embedded case)
881 * - typename being foo::bar while udt->hash_elt.name being
882 * just bar
883 * So, we twist the comparison to test both occurrences. When
884 * we have proper C++ types in this file, this twist has to be
885 * removed
886 */
887 l1 = strlen(udt->hash_elt.name);
888 l2 = strlen(typename);
889 if (l1 > l2 || strcmp(udt->hash_elt.name, typename + l2 - l1))
890 ERR("Forward declaration name mismatch %s <> %s\n",
891 udt->hash_elt.name, typename);
892 new_dt = &udt->symt;
893 }
894 PTS_ABORTIF(ptd, stabs_pts_read_aggregate(ptd, udt) == -1);
895 }
896 break;
897 case 'x':
898 idx = ptd->idx;
899 tmp = *ptd->ptr++;
900 PTS_ABORTIF(ptd, stabs_pts_read_id(ptd) == -1);
901 switch (tmp)
902 {
903 case 'e':
904 stabs_get_basic(ptd, 1 /* int */, &ref_dt);
905 new_dt = &symt_new_enum(ptd->module, ptd->buf + idx, ref_dt)->symt;
906 break;
907 case 's':
908 new_dt = &symt_new_udt(ptd->module, ptd->buf + idx, 0, UdtStruct)->symt;
909 break;
910 case 'u':
911 new_dt = &symt_new_udt(ptd->module, ptd->buf + idx, 0, UdtUnion)->symt;
912 break;
913 default:
914 return -1;
915 }
916 ptd->idx = idx;
917 break;
918 case '-':
919 {
920 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &tmp) == -1);
921 PTS_ABORTIF(ptd, stabs_get_basic(ptd, tmp, &new_dt) == -1);
922 PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
923 }
924 break;
925 case '#':
926 if (*ptd->ptr == '#')
927 {
928 ptd->ptr++;
929 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1);
930 new_dt = &symt_new_function_signature(ptd->module, ref_dt, -1)->symt;
931 }
932 else
933 {
934 struct symt* cls_dt;
935 struct symt* pmt_dt;
936
937 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &cls_dt) == -1);
938 PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
939 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1);
940 new_dt = &symt_new_function_signature(ptd->module, ref_dt, -1)->symt;
941 while (*ptd->ptr == ',')
942 {
943 ptd->ptr++;
944 PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &pmt_dt) == -1);
945 }
946 }
947 break;
948 case 'R':
949 {
950 LONG_PTR type, len, unk;
951 int basic;
952
953 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &type) == -1);
954 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
955 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &len) == -1);
956 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
957 PTS_ABORTIF(ptd, stabs_pts_read_number(ptd, &unk) == -1);
958 PTS_ABORTIF(ptd, *ptd->ptr++ != ';'); /* ';' */
959
960 switch (type) /* see stabs_get_basic for the details */
961 {
962 case 1: basic = 12; break;
963 case 2: basic = 13; break;
964 case 3: basic = 25; break;
965 case 4: basic = 26; break;
966 case 5: basic = 35; break;
967 case 6: basic = 14; break;
968 default: PTS_ABORTIF(ptd, 1);
969 }
970 PTS_ABORTIF(ptd, stabs_get_basic(ptd, basic, &new_dt) == -1);
971 }
972 break;
973 default:
974 ERR("Unknown type '%c'\n", ptd->ptr[-1]);
975 return -1;
976 }
977 }
978
979 if (!new_dt)
980 {
981 /* is it a forward declaration that has been filled ? */
982 new_dt = *stabs_find_ref(filenr1, subnr1);
983 /* if not, this should be void (which is defined as a ref to itself, but we
984 * don't correctly catch it)
985 */
986 if (!new_dt && typename)
987 {
988 new_dt = &symt_new_basic(ptd->module, btVoid, typename, 0)->symt;
989 PTS_ABORTIF(ptd, strcmp(typename, "void"));
990 }
991 }
992
993 *stabs_find_ref(filenr1, subnr1) = *ret_dt = new_dt;
994
995 TRACE("Adding (%ld,%ld) %s\n", filenr1, subnr1, debugstr_a(typename));
996
997 return 0;
998}
999
1000static int stabs_parse_typedef(struct module* module, const char* ptr,
1001 const char* typename)
1002{
1003 struct ParseTypedefData ptd;
1004 struct symt* dt;
1005 int ret = -1;
1006
1007 /* check for already existing definition */
1008
1009 TRACE("%s => %s\n", typename, debugstr_a(ptr));
1010 ptd.module = module;
1011 ptd.idx = 0;
1012#ifdef PTS_DEBUG
1013 ptd.err_idx = 0;
1014#endif
1015 for (ptd.ptr = ptr - 1; ;)
1016 {
1017 ptd.ptr = strchr(ptd.ptr + 1, ':');
1018 if (ptd.ptr == NULL || *++ptd.ptr != ':') break;
1019 }
1020 if (ptd.ptr)
1021 {
1022 if (*ptd.ptr != '(') ptd.ptr++;
1023 /* most of type definitions take one char, except Tt */
1024 if (*ptd.ptr != '(') ptd.ptr++;
1025 ret = stabs_pts_read_type_def(&ptd, typename, &dt);
1026 }
1027
1028 if (ret == -1 || *ptd.ptr)
1029 {
1030#ifdef PTS_DEBUG
1031 int i;
1032 TRACE("Failure on %s\n", debugstr_a(ptr));
1033 if (ret == -1)
1034 {
1035 for (i = 0; i < ptd.err_idx; i++)
1036 {
1037 TRACE("[%d]: line %d => %s\n",
1038 i, ptd.errors[i].line, debugstr_a(ptd.errors[i].ptr));
1039 }
1040 }
1041 else
1042 TRACE("[0]: => %s\n", debugstr_a(ptd.ptr));
1043
1044#else
1045 ERR("Failure on %s at %s\n", debugstr_a(ptr), debugstr_a(ptd.ptr));
1046#endif
1047 return FALSE;
1048 }
1049
1050 return TRUE;
1051}
1052
1053static struct symt* stabs_parse_type(const char* stab)
1054{
1055 const char* c = stab - 1;
1056
1057 /*
1058 * Look through the stab definition, and figure out what struct symt
1059 * this represents. If we have something we know about, assign the
1060 * type.
1061 * According to "The \"stabs\" debug format" (Rev 2.130) the name may be
1062 * a C++ name and contain double colons e.g. foo::bar::baz:t5=*6.
1063 */
1064 do
1065 {
1066 if ((c = strchr(c + 1, ':')) == NULL) return NULL;
1067 } while (*++c == ':');
1068
1069 /*
1070 * The next characters say more about the type (i.e. data, function, etc)
1071 * of symbol. Skip them. (C++ for example may have Tt).
1072 * Actually this is a very weak description; I think Tt is the only
1073 * multiple combination we should see.
1074 */
1075 while (*c && *c != '(' && !isdigit(*c))
1076 c++;
1077 /*
1078 * The next is either an integer or a (integer,integer).
1079 * The stabs_read_type_enum() takes care that stab_types is large enough.
1080 */
1081 return *stabs_read_type_enum(&c);
1082}
1083
1085{
1088};
1089
1091{
1092 char name[256];
1093 struct symt* type;
1096};
1097
1099{
1104};
1105
1107{
1109 union {
1112 } u;
1113};
1114
1116{
1118 unsigned num;
1119 unsigned allocated;
1120};
1121
1122static inline void pending_make_room(struct pending_list* pending)
1123{
1124 if (pending->num == pending->allocated)
1125 {
1126 if (!pending->objs)
1127 {
1128 pending->allocated = 8;
1129 pending->objs = HeapAlloc(GetProcessHeap(), 0,
1130 pending->allocated * sizeof(pending->objs[0]));
1131 }
1132 else
1133 {
1134 pending->allocated *= 2;
1135 pending->objs = HeapReAlloc(GetProcessHeap(), 0, pending->objs,
1136 pending->allocated * sizeof(pending->objs[0]));
1137 }
1138 }
1139}
1140
1141static inline void pending_add_var(struct pending_list* pending, const char* name,
1142 enum DataKind dt, const struct location* loc)
1143{
1144 pending_make_room(pending);
1145 pending->objs[pending->num].tag = PENDING_VAR;
1146 stab_strcpy(pending->objs[pending->num].u.var.name,
1147 sizeof(pending->objs[pending->num].u.var.name), name);
1148 pending->objs[pending->num].u.var.type = stabs_parse_type(name);
1149 pending->objs[pending->num].u.var.kind = dt;
1150 pending->objs[pending->num].u.var.loc = *loc;
1151 pending->num++;
1152}
1153
1154static inline void pending_add_line(struct pending_list* pending, int source_idx,
1155 int line_num, ULONG_PTR offset,
1156 ULONG_PTR load_offset)
1157{
1158 pending_make_room(pending);
1159 pending->objs[pending->num].tag = PENDING_LINE;
1160 pending->objs[pending->num].u.line.source_idx = source_idx;
1161 pending->objs[pending->num].u.line.line_num = line_num;
1162 pending->objs[pending->num].u.line.offset = offset;
1163 pending->objs[pending->num].u.line.load_offset = load_offset;
1164 pending->num++;
1165}
1166
1167static void pending_flush(struct pending_list* pending, struct module* module,
1168 struct symt_function* func, struct symt_block* block)
1169{
1170 unsigned int i;
1171
1172 for (i = 0; i < pending->num; i++)
1173 {
1174 switch (pending->objs[i].tag)
1175 {
1176 case PENDING_VAR:
1178 pending->objs[i].u.var.kind, &pending->objs[i].u.var.loc,
1179 block, pending->objs[i].u.var.type, pending->objs[i].u.var.name);
1180 break;
1181 case PENDING_LINE:
1182 if (module->type == DMT_MACHO)
1183 pending->objs[i].u.line.offset -= func->address - pending->objs[i].u.line.load_offset;
1184 symt_add_func_line(module, func, pending->objs[i].u.line.source_idx,
1185 pending->objs[i].u.line.line_num, pending->objs[i].u.line.offset);
1186 break;
1187 default:
1188 ERR("Unknown pending object tag %u\n", (unsigned)pending->objs[i].tag);
1189 break;
1190 }
1191 }
1192 pending->num = 0;
1193}
1194
1195/******************************************************************
1196 * stabs_finalize_function
1197 *
1198 * Ends function creation: mainly:
1199 * - cleans up line number information
1200 * - tries to set up a debug-start tag (FIXME: heuristic to be enhanced)
1201 * - for stabs which have absolute address in them, initializes the size of the
1202 * function (assuming that current function ends where next function starts)
1203 */
1206{
1207 IMAGEHLP_LINE64 il;
1208 struct location loc;
1209
1210 if (!func) return;
1212 /* To define the debug-start of the function, we use the second line number.
1213 * Not 100% bullet proof, but better than nothing
1214 */
1215 if (symt_fill_func_line_info(module, func, func->address, &il) &&
1217 {
1218 loc.kind = loc_absolute;
1219 loc.offset = il.Address - func->address;
1221 &loc, NULL);
1222 }
1223 if (size) func->size = size;
1224}
1225
1226static inline void stabbuf_append(char **buf, unsigned *buf_size, const char *str)
1227{
1228 unsigned str_len, buf_len;
1229
1230 str_len = strlen(str);
1231 buf_len = strlen(*buf);
1232
1233 if(str_len+buf_len >= *buf_size) {
1234 *buf_size += buf_len + str_len;
1235 *buf = HeapReAlloc(GetProcessHeap(), 0, *buf, *buf_size);
1236 }
1237
1238 strcpy(*buf+buf_len, str);
1239}
1240
1242 const char* pv_stab_ptr, size_t nstab, size_t stabsize,
1243 const char* strs, int strtablen,
1244 stabs_def_cb callback, void* user)
1245{
1246 struct symt_function* curr_func = NULL;
1247 struct symt_block* block = NULL;
1248 struct symt_compiland* compiland = NULL;
1249 char* srcpath = NULL;
1250 int i;
1251 const char* ptr;
1252 char* stabbuff;
1253 unsigned int stabbufflen;
1254 const struct stab_nlist* stab_ptr;
1255 const char* strs_end;
1256 int strtabinc;
1257 char symname[4096];
1258 unsigned incl[32];
1259 int incl_stk = -1;
1260 int source_idx = -1;
1261 struct pending_list pending_block;
1262 struct pending_list pending_func;
1263 BOOL ret = TRUE;
1264 struct location loc;
1265 unsigned char type;
1266 uint64_t n_value;
1267
1268 strs_end = strs + strtablen;
1269
1270 memset(stabs_basic, 0, sizeof(stabs_basic));
1271 memset(&pending_block, 0, sizeof(pending_block));
1272 memset(&pending_func, 0, sizeof(pending_func));
1273
1274 /*
1275 * Allocate a buffer into which we can build stab strings for cases
1276 * where the stab is continued over multiple lines.
1277 */
1278 stabbufflen = 65536;
1279 stabbuff = HeapAlloc(GetProcessHeap(), 0, stabbufflen);
1280
1281 strtabinc = 0;
1282 stabbuff[0] = '\0';
1283 for (i = 0; i < nstab; i++)
1284 {
1285 stab_ptr = (struct stab_nlist *)(pv_stab_ptr + i * stabsize);
1286 n_value = stabsize == sizeof(struct macho64_nlist) ? ((struct macho64_nlist *)stab_ptr)->n_value : stab_ptr->n_value;
1287 ptr = strs + stab_ptr->n_strx;
1288 if ((ptr > strs_end) || (ptr + strlen(ptr) > strs_end))
1289 {
1290 WARN("Bad stabs string %p\n", ptr);
1291 continue;
1292 }
1293 if (*ptr != '\0' && (ptr[strlen(ptr) - 1] == '\\'))
1294 {
1295 /*
1296 * Indicates continuation. Append this to the buffer, and go onto the
1297 * next record. Repeat the process until we find a stab without the
1298 * '/' character, as this indicates we have the whole thing.
1299 */
1300 stabbuf_append(&stabbuff, &stabbufflen, ptr);
1301 continue;
1302 }
1303 else if (stabbuff[0] != '\0')
1304 {
1305 stabbuf_append(&stabbuff, &stabbufflen, ptr);
1306 ptr = stabbuff;
1307 }
1308
1309 if (stab_ptr->n_type & N_STAB)
1310 type = stab_ptr->n_type;
1311 else
1312 {
1313 type = (stab_ptr->n_type & N_TYPE);
1314 if (module->type == DMT_MACHO) type &= ~N_PEXT;
1315 }
1316
1317 /* only symbol entries contain a typedef */
1318 switch (type)
1319 {
1320 case N_GSYM:
1321 case N_LCSYM:
1322 case N_STSYM:
1323 case N_RSYM:
1324 case N_LSYM:
1325 case N_ROSYM:
1326 case N_PSYM:
1327 if (strchr(ptr, '=') != NULL)
1328 {
1329 /*
1330 * The stabs aren't in writable memory, so copy it over so we are
1331 * sure we can scribble on it.
1332 */
1333 if (ptr != stabbuff)
1334 {
1335 stabbuff[0] = 0;
1336 stabbuf_append(&stabbuff, &stabbufflen, ptr);
1337 ptr = stabbuff;
1338 }
1339 stab_strcpy(symname, sizeof(symname), ptr);
1340 if (!stabs_parse_typedef(module, ptr, symname))
1341 {
1342 /* skip this definition */
1343 stabbuff[0] = '\0';
1344 continue;
1345 }
1346 }
1347 }
1348
1349 switch (type)
1350 {
1351 case N_GSYM:
1352 /*
1353 * These are useless with ELF. They have no value, and you have to
1354 * read the normal symbol table to get the address. Thus we
1355 * ignore them, and when we process the normal symbol table
1356 * we should do the right thing.
1357 *
1358 * With a.out or mingw, they actually do make some amount of sense.
1359 */
1360 stab_strcpy(symname, sizeof(symname), ptr);
1361 loc.kind = loc_absolute;
1362 loc.reg = 0;
1363 loc.offset = load_offset + n_value;
1364 symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
1365 loc, 0, stabs_parse_type(ptr));
1366 break;
1367 case N_LCSYM:
1368 case N_STSYM:
1369 /* These are static symbols and BSS symbols. */
1370 stab_strcpy(symname, sizeof(symname), ptr);
1371 loc.kind = loc_absolute;
1372 loc.reg = 0;
1373 loc.offset = load_offset + n_value;
1374 symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
1375 loc, 0, stabs_parse_type(ptr));
1376 break;
1377 case N_LBRAC:
1378 if (curr_func)
1379 {
1380 block = symt_open_func_block(module, curr_func, block,
1381 n_value, 0);
1382 pending_flush(&pending_block, module, curr_func, block);
1383 }
1384 break;
1385 case N_RBRAC:
1386 if (curr_func)
1388 n_value);
1389 break;
1390 case N_PSYM:
1391 /* These are function parameters. */
1392 if (curr_func != NULL)
1393 {
1394 struct symt* param_type = stabs_parse_type(ptr);
1395 stab_strcpy(symname, sizeof(symname), ptr);
1396 loc.kind = loc_regrel;
1397 loc.reg = dbghelp_current_cpu->frame_regno;
1398 loc.offset = n_value;
1399 symt_add_func_local(module, curr_func,
1400 (int)n_value >= 0 ? DataIsParam : DataIsLocal,
1401 &loc, NULL, param_type, symname);
1403 (struct symt_function_signature*)curr_func->type,
1404 param_type);
1405 }
1406 break;
1407 case N_RSYM:
1408 /* These are registers (as local variables) */
1409 if (curr_func != NULL)
1410 {
1411 loc.kind = loc_register;
1412 loc.offset = 0;
1413
1414 switch (n_value)
1415 {
1416 case 0: loc.reg = CV_REG_EAX; break;
1417 case 1: loc.reg = CV_REG_ECX; break;
1418 case 2: loc.reg = CV_REG_EDX; break;
1419 case 3: loc.reg = CV_REG_EBX; break;
1420 case 4: loc.reg = CV_REG_ESP; break;
1421 case 5: loc.reg = CV_REG_EBP; break;
1422 case 6: loc.reg = CV_REG_ESI; break;
1423 case 7: loc.reg = CV_REG_EDI; break;
1424 case 11:
1425 case 12:
1426 case 13:
1427 case 14:
1428 case 15:
1429 case 16:
1430 case 17:
1431 case 18:
1432 case 19: loc.reg = CV_REG_ST0 + n_value - 12; break;
1433 case 21:
1434 case 22:
1435 case 23:
1436 case 24:
1437 case 25:
1438 case 26:
1439 case 27:
1440 case 28: loc.reg = CV_REG_XMM0 + n_value - 21; break;
1441 case 29:
1442 case 30:
1443 case 31:
1444 case 32:
1445 case 33:
1446 case 34:
1447 case 35:
1448 case 36: loc.reg = CV_REG_MM0 + n_value - 29; break;
1449 default:
1450 FIXME("Unknown register value (%lu)\n", (ULONG_PTR)n_value);
1451 loc.reg = CV_REG_NONE;
1452 break;
1453 }
1454 stab_strcpy(symname, sizeof(symname), ptr);
1455 if (ptr[strlen(symname) + 1] == 'P')
1456 {
1457 struct symt* param_type = stabs_parse_type(ptr);
1458 stab_strcpy(symname, sizeof(symname), ptr);
1459 symt_add_func_local(module, curr_func, DataIsParam, &loc,
1460 NULL, param_type, symname);
1462 (struct symt_function_signature*)curr_func->type,
1463 param_type);
1464 }
1465 else
1466 pending_add_var(&pending_block, ptr, DataIsLocal, &loc);
1467 }
1468 break;
1469 case N_LSYM:
1470 /* These are local variables */
1471 loc.kind = loc_regrel;
1472 loc.reg = dbghelp_current_cpu->frame_regno;
1473 loc.offset = n_value;
1474 if (curr_func != NULL) pending_add_var(&pending_block, ptr, DataIsLocal, &loc);
1475 break;
1476 case N_SLINE:
1477 /*
1478 * This is a line number. These are always relative to the start
1479 * of the function (N_FUN), and this makes the lookup easier.
1480 */
1481 assert(source_idx >= 0);
1482 if (curr_func != NULL)
1483 {
1484 ULONG_PTR offset = n_value;
1485 if (module->type == DMT_MACHO)
1486 offset -= curr_func->address - load_offset;
1487 symt_add_func_line(module, curr_func, source_idx,
1488 stab_ptr->n_desc, offset);
1489 }
1490 else pending_add_line(&pending_func, source_idx, stab_ptr->n_desc,
1491 n_value, load_offset);
1492 break;
1493 case N_FUN:
1494 /*
1495 * For now, just declare the various functions. Later
1496 * on, we will add the line number information and the
1497 * local symbols.
1498 */
1499 /*
1500 * Copy the string to a temp buffer so we
1501 * can kill everything after the ':'. We do
1502 * it this way because otherwise we end up dirtying
1503 * all of the pages related to the stabs, and that
1504 * sucks up swap space like crazy.
1505 */
1506 stab_strcpy(symname, sizeof(symname), ptr);
1507 if (*symname)
1508 {
1509 struct symt_function_signature* func_type;
1510
1511 if (curr_func)
1512 {
1513 /* First, clean up the previous function we were working on.
1514 * Assume size of the func is the delta between current offset
1515 * and offset of last function
1516 */
1518 n_value ?
1519 (load_offset + n_value - curr_func->address) : 0);
1520 }
1522 stabs_parse_type(ptr), -1);
1523 curr_func = symt_new_function(module, compiland, symname,
1524 load_offset + n_value, 0,
1525 &func_type->symt);
1526 pending_flush(&pending_func, module, curr_func, NULL);
1527 }
1528 else
1529 {
1530 /* some versions of GCC to use a N_FUN "" to mark the end of a function
1531 * and n_value contains the size of the func
1532 */
1533 stabs_finalize_function(module, curr_func, n_value);
1534 curr_func = NULL;
1535 }
1536 break;
1537 case N_SO:
1538 /*
1539 * This indicates a new source file. Append the records
1540 * together, to build the correct path name.
1541 */
1542 if (*ptr == '\0') /* end of N_SO file */
1543 {
1544 /* Nuke old path. */
1545 HeapFree(GetProcessHeap(), 0, srcpath);
1546 srcpath = NULL;
1547 stabs_finalize_function(module, curr_func, 0);
1548 curr_func = NULL;
1549 source_idx = -1;
1550 incl_stk = -1;
1551 assert(block == NULL);
1552 compiland = NULL;
1553 }
1554 else
1555 {
1556 int len = strlen(ptr);
1557 if (ptr[len-1] != '/')
1558 {
1560 source_idx = source_new(module, srcpath, ptr);
1561 compiland = symt_new_compiland(module, 0 /* FIXME */, source_idx);
1562 }
1563 else
1564 {
1565 srcpath = HeapAlloc(GetProcessHeap(), 0, len + 1);
1566 strcpy(srcpath, ptr);
1567 }
1568 }
1569 break;
1570 case N_SOL:
1571 source_idx = source_new(module, srcpath, ptr);
1572 break;
1573 case N_UNDF:
1574 strs += strtabinc;
1575 strtabinc = n_value;
1576 /* I'm not sure this is needed, so trace it before we obsolete it */
1577 if (curr_func)
1578 {
1579 FIXME("UNDF: curr_func %s\n", curr_func->hash_elt.name);
1580 stabs_finalize_function(module, curr_func, 0); /* FIXME */
1581 curr_func = NULL;
1582 }
1583 break;
1584 case N_OPT:
1585 /* Ignore this. We don't care what it points to. */
1586 break;
1587 case N_BINCL:
1589 assert(incl_stk < (int) ARRAY_SIZE(incl) - 1);
1590 incl[++incl_stk] = source_idx;
1591 source_idx = source_new(module, NULL, ptr);
1592 break;
1593 case N_EINCL:
1594 assert(incl_stk >= 0);
1595 source_idx = incl[incl_stk--];
1596 break;
1597 case N_EXCL:
1598 if (stabs_add_include(stabs_find_include(ptr, n_value)) < 0)
1599 {
1600 ERR("Excluded header not found (%s,%ld)\n", ptr, (ULONG_PTR)n_value);
1602 ret = FALSE;
1603 goto done;
1604 }
1605 break;
1606 case N_MAIN:
1607 /* Always ignore these. GCC doesn't even generate them. */
1608 break;
1609 case N_BNSYM:
1610 case N_ENSYM:
1611 case N_OSO:
1612 case N_INDR:
1613 /* Always ignore these, they seem to be used only on Darwin. */
1614 break;
1615 case N_ABS:
1616 case N_SECT:
1617 /* FIXME: Other definition types (N_TEXT, N_DATA, N_BSS, ...)? */
1618 if (callback)
1619 {
1620 BOOL is_public = (stab_ptr->n_type & N_EXT);
1621 BOOL is_global = is_public;
1622
1623 /* "private extern"; shared among compilation units in a shared
1624 * library, but not accessible from outside the library. */
1625 if (stab_ptr->n_type & N_PEXT)
1626 {
1627 is_public = FALSE;
1628 is_global = TRUE;
1629 }
1630
1631 if (*ptr == '_') ptr++;
1632 stab_strcpy(symname, sizeof(symname), ptr);
1633
1634 callback(module, load_offset, symname, n_value,
1635 is_public, is_global, stab_ptr->n_other, compiland, user);
1636 }
1637 break;
1638 default:
1639 ERR("Unknown stab type 0x%02x\n", type);
1640 break;
1641 }
1642 stabbuff[0] = '\0';
1643 TRACE("0x%02x %lx %s\n",
1644 stab_ptr->n_type, (ULONG_PTR)n_value, debugstr_a(strs + stab_ptr->n_strx));
1645 }
1647 module->module.CVSig = 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24);
1648 /* FIXME: we could have a finer grain here */
1654done:
1655 HeapFree(GetProcessHeap(), 0, stabbuff);
1657 HeapFree(GetProcessHeap(), 0, pending_block.objs);
1658 HeapFree(GetProcessHeap(), 0, pending_func.objs);
1659 HeapFree(GetProcessHeap(), 0, srcpath);
1660
1661 return ret;
1662}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define isdigit(c)
Definition: acclib.h:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
struct symt_hierarchy_point * symt_add_function_point(struct module *module, struct symt_function *func, enum SymTagEnum point, const struct location *loc, const char *name) DECLSPEC_HIDDEN
Definition: symbol.c:452
struct symt_function * symt_new_function(struct module *module, struct symt_compiland *parent, const char *name, ULONG_PTR addr, ULONG_PTR size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:293
BOOL symt_get_info(struct module *module, const struct symt *type, IMAGEHLP_SYMBOL_TYPE_INFO req, void *pInfo) DECLSPEC_HIDDEN
Definition: type.c:536
struct symt_data * symt_add_func_local(struct module *module, struct symt_function *func, enum DataKind dt, const struct location *loc, struct symt_block *block, struct symt *type, const char *name) DECLSPEC_HIDDEN
Definition: symbol.c:378
struct symt_pointer * symt_new_pointer(struct module *module, struct symt *ref_type, ULONG_PTR size) DECLSPEC_HIDDEN
Definition: type.c:414
const char * symt_get_name(const struct symt *sym) DECLSPEC_HIDDEN
Definition: type.c:81
BOOL symt_add_enum_element(struct module *module, struct symt_enum *enum_type, const char *name, int value) DECLSPEC_HIDDEN
Definition: type.c:319
struct symt_udt * symt_new_udt(struct module *module, const char *typename, unsigned size, enum UdtKind kind) DECLSPEC_HIDDEN
Definition: type.c:219
unsigned source_new(struct module *module, const char *basedir, const char *source) DECLSPEC_HIDDEN
Definition: source.c:66
struct symt_function_signature * symt_new_function_signature(struct module *module, struct symt *ret_type, enum CV_call_e call_conv) DECLSPEC_HIDDEN
Definition: type.c:377
struct symt_block * symt_close_func_block(struct module *module, const struct symt_function *func, struct symt_block *block, unsigned pc) DECLSPEC_HIDDEN
Definition: symbol.c:440
struct symt_data * symt_new_global_variable(struct module *module, struct symt_compiland *parent, const char *name, unsigned is_static, struct location loc, ULONG_PTR size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:256
struct symt_enum * symt_new_enum(struct module *module, const char *typename, struct symt *basetype) DECLSPEC_HIDDEN
Definition: type.c:304
BOOL symt_set_udt_size(struct module *module, struct symt_udt *type, unsigned size) DECLSPEC_HIDDEN
Definition: type.c:242
struct symt_block * symt_open_func_block(struct module *module, struct symt_function *func, struct symt_block *block, unsigned pc, unsigned len) DECLSPEC_HIDDEN
Definition: symbol.c:413
void module_reset_debug_info(struct module *module) DECLSPEC_HIDDEN
Definition: module.c:1328
struct symt_array * symt_new_array(struct module *module, int min, int max, struct symt *base, struct symt *index) DECLSPEC_HIDDEN
Definition: type.c:345
struct symt_compiland * symt_new_compiland(struct module *module, ULONG_PTR address, unsigned src_idx) DECLSPEC_HIDDEN
Definition: symbol.c:207
BOOL symt_fill_func_line_info(const struct module *module, const struct symt_function *func, DWORD64 addr, IMAGEHLP_LINE64 *line) DECLSPEC_HIDDEN
Definition: symbol.c:1480
BOOL symt_add_function_signature_parameter(struct module *module, struct symt_function_signature *sig, struct symt *param) DECLSPEC_HIDDEN
Definition: type.c:394
BOOL symt_add_udt_element(struct module *module, struct symt_udt *udt_type, const char *name, struct symt *elt_type, unsigned offset, unsigned size) DECLSPEC_HIDDEN
Definition: type.c:264
void(* stabs_def_cb)(struct module *module, ULONG_PTR load_offset, const char *name, ULONG_PTR offset, BOOL is_public, BOOL is_global, unsigned char other, struct symt_compiland *compiland, void *user)
@ loc_regrel
@ loc_register
@ loc_absolute
struct symt_basic * symt_new_basic(struct module *module, enum BasicType, const char *typename, unsigned size) DECLSPEC_HIDDEN
Definition: type.c:192
void symt_add_func_line(struct module *module, struct symt_function *func, unsigned source_idx, int line_num, ULONG_PTR offset) DECLSPEC_HIDDEN
Definition: symbol.c:326
BOOL symt_normalize_function(struct module *module, const struct symt_function *func) DECLSPEC_HIDDEN
Definition: symbol.c:473
@ DMT_MACHO
BOOL symt_get_func_line_next(const struct module *module, PIMAGEHLP_LINE64 line) DECLSPEC_HIDDEN
Definition: symbol.c:1734
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT64 uint64_t
Definition: types.h:77
unsigned int idx
Definition: utils.c:41
#define GetProcessHeap()
Definition: compat.h:736
@ SymDia
Definition: compat.h:1063
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
@ TI_GET_LENGTH
Definition: compat.h:1417
@ SymTagFuncDebugStart
Definition: compat.h:1602
@ SymTagUDT
Definition: compat.h:1592
#define HeapFree(x, y, z)
Definition: compat.h:735
@ CV_REG_EBX
Definition: compat.h:1699
@ CV_REG_XMM0
Definition: compat.h:1744
@ CV_REG_ESI
Definition: compat.h:1702
@ CV_REG_ECX
Definition: compat.h:1697
@ CV_REG_ST0
Definition: compat.h:1732
@ CV_REG_EBP
Definition: compat.h:1701
@ CV_REG_EAX
Definition: compat.h:1696
@ CV_REG_EDI
Definition: compat.h:1703
@ CV_REG_MM0
Definition: compat.h:1743
@ CV_REG_ESP
Definition: compat.h:1700
@ CV_REG_EDX
Definition: compat.h:1698
@ CV_REG_NONE
Definition: compat.h:1679
DataKind
Definition: compat.h:1647
@ DataIsLocal
Definition: compat.h:1649
@ DataIsParam
Definition: compat.h:1651
BasicType
Definition: compat.h:1616
@ btVoid
Definition: compat.h:1618
@ btUInt
Definition: compat.h:1622
@ btChar
Definition: compat.h:1619
@ btComplex
Definition: compat.h:1631
@ btBool
Definition: compat.h:1625
@ btInt
Definition: compat.h:1621
@ btWChar
Definition: compat.h:1620
@ btFloat
Definition: compat.h:1623
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
UdtKind
Definition: compat.h:1639
@ UdtStruct
Definition: compat.h:1640
@ UdtUnion
Definition: compat.h:1642
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
const GLint * first
Definition: glext.h:5794
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
#define debugstr_a
Definition: kernel32.h:31
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static IPrintDialogCallback callback
Definition: printdlg.c:326
static UINT UINT last
Definition: font.c:45
static char * dest
Definition: rtl.c:135
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
const WCHAR * str
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
BOOL stabs_parse(struct module *module, ULONG_PTR load_offset, const char *pv_stab_ptr, size_t nstab, size_t stabsize, const char *strs, int strtablen, stabs_def_cb callback, void *user)
Definition: stabs.c:1241
static void stab_strcpy(char *dest, int sz, const char *source)
Definition: stabs.c:95
static int stabs_find_include(const char *file, ULONG_PTR val)
Definition: stabs.c:174
static void stabs_pts_push(struct ParseTypedefData *ptd, unsigned line)
Definition: stabs.c:315
static void pending_flush(struct pending_list *pending, struct module *module, struct symt_function *func, struct symt_block *block)
Definition: stabs.c:1167
static void stabs_finalize_function(struct module *module, struct symt_function *func, ULONG_PTR size)
Definition: stabs.c:1204
#define PTS_ABORTIF(ptd, t)
Definition: stabs.c:322
static int stabs_pts_read_enum(struct ParseTypedefData *ptd, struct symt_enum *edt)
Definition: stabs.c:739
static int stabs_pts_read_type_reference(struct ParseTypedefData *ptd, LONG_PTR *filenr, LONG_PTR *subnr)
Definition: stabs.c:408
#define N_EXT
Definition: stabs.c:65
#define N_OPT
Definition: stabs.c:80
static void stabs_free_includes(void)
Definition: stabs.c:209
static int num_alloc_include_def
Definition: stabs.c:142
static void stabs_reset_includes(void)
Definition: stabs.c:199
static int stabs_add_include(int idx)
Definition: stabs.c:187
#define N_SECT
Definition: stabs.c:71
#define N_PSYM
Definition: stabs.c:89
pending_obj_kind
Definition: stabs.c:1085
@ PENDING_VAR
Definition: stabs.c:1086
@ PENDING_LINE
Definition: stabs.c:1087
static include_def * include_defs
Definition: stabs.c:140
static int cu_include_stk_idx
Definition: stabs.c:144
#define N_STSYM
Definition: stabs.c:75
static void pending_make_room(struct pending_list *pending)
Definition: stabs.c:1122
#define N_ENSYM
Definition: stabs.c:83
static int stabs_parse_typedef(struct module *module, const char *ptr, const char *typename)
Definition: stabs.c:1000
#define MAX_INCLUDES
Definition: stabs.c:138
static int stabs_pts_read_range_value(struct ParseTypedefData *ptd, struct pts_range_value *prv)
Definition: stabs.c:434
#define N_SOL
Definition: stabs.c:88
#define N_BINCL
Definition: stabs.c:87
#define N_STAB
Definition: stabs.c:62
#define N_PEXT
Definition: stabs.c:63
#define N_SO
Definition: stabs.c:84
static struct symt ** stabs_read_type_enum(const char **x)
Definition: stabs.c:272
#define N_BNSYM
Definition: stabs.c:79
static int stabs_pts_read_number(struct ParseTypedefData *ptd, LONG_PTR *v)
Definition: stabs.c:398
#define N_GSYM
Definition: stabs.c:73
#define N_ABS
Definition: stabs.c:69
#define N_LBRAC
Definition: stabs.c:91
#define N_RBRAC
Definition: stabs.c:93
#define N_SLINE
Definition: stabs.c:82
#define N_FUN
Definition: stabs.c:74
#define N_EINCL
Definition: stabs.c:90
#define N_RSYM
Definition: stabs.c:81
#define N_INDR
Definition: stabs.c:70
static struct symt ** stabs_find_ref(LONG_PTR filenr, LONG_PTR subnr)
Definition: stabs.c:228
static struct symt ** cu_vector
Definition: stabs.c:145
#define N_LSYM
Definition: stabs.c:86
static void pending_add_var(struct pending_list *pending, const char *name, enum DataKind dt, const struct location *loc)
Definition: stabs.c:1141
static int num_include_def
Definition: stabs.c:141
#define N_UNDF
Definition: stabs.c:68
static struct symt * stabs_parse_type(const char *stab)
Definition: stabs.c:1053
#define N_ROSYM
Definition: stabs.c:78
static int stabs_pts_read_method_info(struct ParseTypedefData *ptd)
Definition: stabs.c:558
static int stabs_get_basic(struct ParseTypedefData *ptd, unsigned basic, struct symt **symt)
Definition: stabs.c:327
static int stabs_new_include(const char *file, ULONG_PTR val)
Definition: stabs.c:149
static int cu_nrofentries
Definition: stabs.c:146
#define N_EXCL
Definition: stabs.c:92
#define strtoull
Definition: stabs.c:58
static int stabs_pts_read_aggregate(struct ParseTypedefData *ptd, struct symt_udt *sdt)
Definition: stabs.c:597
#define N_OSO
Definition: stabs.c:85
#define N_TYPE
Definition: stabs.c:64
static struct symt_basic * stabs_basic[36]
Definition: stabs.c:147
static int stabs_pts_read_range(struct ParseTypedefData *ptd, const char *typename, struct symt **dt)
Definition: stabs.c:476
static int stabs_pts_read_type_def(struct ParseTypedefData *ptd, const char *typename, struct symt **dt)
Definition: stabs.c:782
static int cu_include_stack[MAX_INCLUDES]
Definition: stabs.c:143
static int stabs_pts_read_array(struct ParseTypedefData *ptd, struct symt **adt)
Definition: stabs.c:758
static void pending_add_line(struct pending_list *pending, int source_idx, int line_num, ULONG_PTR offset, ULONG_PTR load_offset)
Definition: stabs.c:1154
#define N_LCSYM
Definition: stabs.c:76
static void stabbuf_append(char **buf, unsigned *buf_size, const char *str)
Definition: stabs.c:1226
static int stabs_pts_read_id(struct ParseTypedefData *ptd)
Definition: stabs.c:370
#define N_MAIN
Definition: stabs.c:77
const char * ptr
Definition: stabs.c:300
struct module * module
Definition: stabs.c:303
char buf[1024]
Definition: stabs.c:301
struct ParseTypedefData::PTS_Error errors[16]
DWORD64 Address
Definition: compat.h:1099
SYM_TYPE SymType
Definition: compat.h:1075
Definition: fci.c:127
ULONG_PTR value
Definition: stabs.c:133
int nrofentries
Definition: stabs.c:135
struct symt ** vector
Definition: stabs.c:134
char * name
Definition: stabs.c:132
Definition: parser.c:49
ULONG_PTR offset
unsigned reg
unsigned kind
IMAGEHLP_MODULEW64 module
enum module_type type
Definition: name.c:39
ULONG_PTR offset
Definition: stabs.c:1102
ULONG_PTR load_offset
Definition: stabs.c:1103
int line_num
Definition: stabs.c:1101
int source_idx
Definition: stabs.c:1100
struct pending_object * objs
Definition: stabs.c:1117
unsigned allocated
Definition: stabs.c:1119
unsigned num
Definition: stabs.c:1118
struct symt * type
Definition: stabs.c:1093
struct location loc
Definition: stabs.c:1095
enum DataKind kind
Definition: stabs.c:1094
struct pending_line line
Definition: stabs.c:1111
struct pending_loc_var var
Definition: stabs.c:1110
enum pending_obj_kind tag
Definition: stabs.c:1108
ULONGLONG val
Definition: stabs.c:430
Definition: send.c:48
unsigned n_strx
unsigned char n_type
unsigned n_value
struct hash_table_elt hash_elt
struct symt * type
ULONG_PTR address
struct symt symt
struct hash_table_elt hash_elt
#define max(a, b)
Definition: svc.c:63
#define str_len
Definition: treelist.c:89
uint64_t DWORD64
Definition: typedefs.h:67
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint64_t ULONGLONG
Definition: typedefs.h:67
Definition: pdh_main.c:94
int ret
static unsigned int block
Definition: xmlmemory.c:101