ReactOS  0.4.15-dev-980-ge160524
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 
55 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_stabs);
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 
95 static 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 
130 typedef struct
131 {
132  char* name;
134  struct symt** vector;
136 } include_def;
137 
138 #define MAX_INCLUDES 5120
139 
141 static int num_include_def = 0;
142 static int num_alloc_include_def = 0;
144 static int cu_include_stk_idx = 0;
145 static struct symt** cu_vector = NULL;
146 static int cu_nrofentries = 0;
147 static struct symt_basic* stabs_basic[36];
148 
149 static int stabs_new_include(const char* file, ULONG_PTR val)
150 {
152  {
153  if (!include_defs)
154  {
155  num_alloc_include_def = 256;
157  sizeof(include_defs[0]) * num_alloc_include_def);
158  }
159  else
160  {
163  sizeof(include_defs[0]) * num_alloc_include_def);
164  }
165  }
170 
171  return num_include_def++;
172 }
173 
174 static 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 
187 static 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 
199 static 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 
209 static void stabs_free_includes(void)
210 {
211  int i;
212 
214  for (i = 0; i < num_include_def; i++)
215  {
218  }
220  include_defs = NULL;
221  num_include_def = 0;
224  cu_vector = NULL;
225  cu_nrofentries = 0;
226 }
227 
228 static 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 
272 static 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
305  struct PTS_Error
306  {
307  const char* ptr;
308  unsigned line;
309  } errors[16];
310  int err_idx;
311 #endif
312 };
313 
314 #ifdef PTS_DEBUG
315 static 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 
327 static 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 
367 static int stabs_pts_read_type_def(struct ParseTypedefData* ptd,
368  const char* typename, struct symt** dt);
369 
370 static 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 
434 static int stabs_pts_read_range_value(struct ParseTypedefData* ptd, struct pts_range_value* prv)
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 
476 static 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 
558 static 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 
597 static 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];
627  DWORD64 size;
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  */
638  symt_get_info(ptd->module, adt, TI_GET_LENGTH, &size);
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;
664  stabs_read_type_enum(&ptd->ptr);
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 
739 static inline int stabs_pts_read_enum(struct ParseTypedefData* ptd,
740  struct symt_enum* edt)
741 {
742  LONG_PTR value;
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 
758 static 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 
782 static 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 
1000 static 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 
1053 static 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;
1094  enum DataKind kind;
1095  struct location loc;
1096 };
1097 
1099 {
1104 };
1105 
1107 {
1109  union {
1112  } u;
1113 };
1114 
1116 {
1118  unsigned num;
1119  unsigned allocated;
1120 };
1121 
1122 static 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 
1141 static 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 
1154 static 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 
1167 static 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  */
1205  ULONG_PTR size)
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 
1226 static 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 
1241 BOOL stabs_parse(struct module* module, ULONG_PTR load_offset,
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)
1387  block = symt_close_func_block(module, curr_func, block,
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  */
1517  stabs_finalize_function(module, curr_func,
1518  n_value ?
1519  (load_offset + n_value - curr_func->address) : 0);
1520  }
1521  func_type = symt_new_function_signature(module,
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 */
1654 done:
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 }
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
static unsigned int block
Definition: xmlmemory.c:118
static int stabs_pts_read_method_info(struct ParseTypedefData *ptd)
Definition: stabs.c:558
static void stab_strcpy(char *dest, int sz, const char *source)
Definition: stabs.c:95
const char * var
Definition: shader.c:5666
BasicType
Definition: compat.h:1363
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_stabs)
GLenum func
Definition: glext.h:6028
static int num_alloc_include_def
Definition: stabs.c:142
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
static void stabs_finalize_function(struct module *module, struct symt_function *func, ULONG_PTR size)
Definition: stabs.c:1204
#define max(a, b)
Definition: svc.c:63
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
struct module * module
Definition: stabs.c:303
BOOL symt_set_udt_size(struct module *module, struct symt_udt *type, unsigned size) DECLSPEC_HIDDEN
Definition: type.c:242
HMODULE module
Definition: main.cpp:47
BOOL symt_add_enum_element(struct module *module, struct symt_enum *enum_type, const char *name, int value) DECLSPEC_HIDDEN
Definition: type.c:319
#define N_BINCL
Definition: stabs.c:87
Definition: compat.h:811
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
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
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
POINT last
Definition: font.c:46
#define TRUE
Definition: types.h:120
static int stabs_find_include(const char *file, ULONG_PTR val)
Definition: stabs.c:174
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
unsigned num
Definition: stabs.c:1118
static void pending_flush(struct pending_list *pending, struct module *module, struct symt_function *func, struct symt_block *block)
Definition: stabs.c:1167
static struct symt ** stabs_read_type_enum(const char **x)
Definition: stabs.c:272
#define PTS_ABORTIF(ptd, t)
Definition: stabs.c:322
const GLint * first
Definition: glext.h:5794
#define WARN(fmt,...)
Definition: debug.h:112
static void stabbuf_append(char **buf, unsigned *buf_size, const char *str)
Definition: stabs.c:1226
#define N_GSYM
Definition: stabs.c:73
GLintptr offset
Definition: glext.h:5920
#define str_len
Definition: treelist.c:89
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define assert(x)
Definition: debug.h:53
struct symt symt
#define N_PEXT
Definition: stabs.c:63
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static include_def * include_defs
Definition: stabs.c:140
#define N_ROSYM
Definition: stabs.c:78
GLuint GLuint end
Definition: gl.h:1545
static void pending_make_room(struct pending_list *pending)
Definition: stabs.c:1122
const char * symt_get_name(const struct symt *sym) DECLSPEC_HIDDEN
Definition: type.c:81
DataKind
Definition: compat.h:1394
ULONG_PTR load_offset
Definition: stabs.c:1103
Definition: send.c:48
static void stabs_pts_push(struct ParseTypedefData *ptd, unsigned line)
Definition: stabs.c:315
#define N_FUN
Definition: stabs.c:74
#define N_PSYM
Definition: stabs.c:89
enum module_type type
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define N_SECT
Definition: stabs.c:71
while(1)
Definition: macro.lex.yy.c:740
#define N_SOL
Definition: stabs.c:88
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
int source_idx
Definition: stabs.c:1100
void module_reset_debug_info(struct module *module) DECLSPEC_HIDDEN
Definition: module.c:1324
ULONG_PTR value
Definition: stabs.c:133
static int stabs_pts_read_enum(struct ParseTypedefData *ptd, struct symt_enum *edt)
Definition: stabs.c:739
#define FALSE
Definition: types.h:117
static int stabs_get_basic(struct ParseTypedefData *ptd, unsigned basic, struct symt **symt)
Definition: stabs.c:327
static int stabs_pts_read_range(struct ParseTypedefData *ptd, const char *typename, struct symt **dt)
Definition: stabs.c:476
unsigned int BOOL
Definition: ntddk_ex.h:94
static int stabs_pts_read_aggregate(struct ParseTypedefData *ptd, struct symt_udt *sdt)
Definition: stabs.c:597
struct symt ** vector
Definition: stabs.c:134
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:111
BOOL symt_add_function_signature_parameter(struct module *module, struct symt_function_signature *sig, struct symt *param) DECLSPEC_HIDDEN
Definition: type.c:394
static PVOID ptr
Definition: dispmode.c:27
#define N_EINCL
Definition: stabs.c:90
unsigned int idx
Definition: utils.c:41
const char * ptr
Definition: stabs.c:300
const WCHAR * str
static int stabs_pts_read_type_reference(struct ParseTypedefData *ptd, LONG_PTR *filenr, LONG_PTR *subnr)
Definition: stabs.c:408
smooth NULL
Definition: ftsmooth.c:416
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
UdtKind
Definition: compat.h:1386
ULONG_PTR offset
ULONGLONG val
Definition: stabs.c:430
Definition: parser.c:48
int nrofentries
Definition: stabs.c:135
static struct symt * stabs_parse_type(const char *stab)
Definition: stabs.c:1053
#define N_LSYM
Definition: stabs.c:86
#define N_EXCL
Definition: stabs.c:92
#define isdigit(c)
Definition: acclib.h:68
#define N_UNDF
Definition: stabs.c:68
struct symt_basic * symt_new_basic(struct module *module, enum BasicType, const char *typename, unsigned size) DECLSPEC_HIDDEN
Definition: type.c:192
GLuint GLfloat * val
Definition: glext.h:7180
struct symt_pointer * symt_new_pointer(struct module *module, struct symt *ref_type, ULONG_PTR size) DECLSPEC_HIDDEN
Definition: type.c:414
#define N_STSYM
Definition: stabs.c:75
MmuTrapHandler callback[0x30]
Definition: mmuobject.c:44
int line_num
Definition: stabs.c:1101
#define TRACE(s)
Definition: solgame.cpp:4
#define N_RBRAC
Definition: stabs.c:93
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static int num_include_def
Definition: stabs.c:141
#define strtoull
Definition: stabs.c:58
#define N_MAIN
Definition: stabs.c:77
#define N_TYPE
Definition: stabs.c:64
if(!(yy_init))
Definition: macro.lex.yy.c:714
static int stabs_pts_read_type_def(struct ParseTypedefData *ptd, const char *typename, struct symt **dt)
Definition: stabs.c:782
BOOL symt_get_func_line_next(const struct module *module, PIMAGEHLP_LINE64 line) DECLSPEC_HIDDEN
Definition: symbol.c:1734
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
#define debugstr_a
Definition: kernel32.h:31
static struct symt ** stabs_find_ref(LONG_PTR filenr, LONG_PTR subnr)
Definition: stabs.c:228
uint64_t ULONGLONG
Definition: typedefs.h:67
static int stabs_pts_read_array(struct ParseTypedefData *ptd, struct symt **adt)
Definition: stabs.c:758
#define N_SLINE
Definition: stabs.c:82
struct symt * type
const GLubyte * c
Definition: glext.h:8905
unsigned long DWORD
Definition: ntddk_ex.h:95
struct symt * type
Definition: stabs.c:1093
struct symt_enum * symt_new_enum(struct module *module, const char *typename, struct symt *basetype) DECLSPEC_HIDDEN
Definition: type.c:304
static int stabs_parse_typedef(struct module *module, const char *ptr, const char *typename)
Definition: stabs.c:1000
static int cu_nrofentries
Definition: stabs.c:146
unsigned reg
int ret
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
char line[200]
Definition: main.c:97
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
SYM_TYPE SymType
Definition: compat.h:823
#define N_RSYM
Definition: stabs.c:81
#define N_LCSYM
Definition: stabs.c:76
unsigned char n_type
static void stabs_free_includes(void)
Definition: stabs.c:209
#define N_OSO
Definition: stabs.c:85
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
static struct symt_basic * stabs_basic[36]
Definition: stabs.c:147
static void pending_add_var(struct pending_list *pending, const char *name, enum DataKind dt, const struct location *loc)
Definition: stabs.c:1141
struct pending_object * objs
Definition: stabs.c:1117
GLsizei const GLfloat * value
Definition: glext.h:6069
static int cu_include_stack[MAX_INCLUDES]
Definition: stabs.c:143
#define ERR(fmt,...)
Definition: debug.h:110
#define MAX_INCLUDES
Definition: stabs.c:138
unsigned kind
#define N_ENSYM
Definition: stabs.c:83
pending_obj_kind
Definition: stabs.c:1084
BOOL symt_normalize_function(struct module *module, const struct symt_function *func) DECLSPEC_HIDDEN
Definition: symbol.c:473
struct symt_udt * symt_new_udt(struct module *module, const char *typename, unsigned size, enum UdtKind kind) DECLSPEC_HIDDEN
Definition: type.c:219
#define N_BNSYM
Definition: stabs.c:79
#define N_EXT
Definition: stabs.c:65
#define N_SO
Definition: stabs.c:84
UINT64 uint64_t
Definition: types.h:77
BOOL symt_get_info(struct module *module, const struct symt *type, IMAGEHLP_SYMBOL_TYPE_INFO req, void *pInfo) DECLSPEC_HIDDEN
Definition: type.c:536
#define N_OPT
Definition: stabs.c:80
unsigned allocated
Definition: stabs.c:1119
uint64_t DWORD64
Definition: typedefs.h:67
const GLdouble * v
Definition: gl.h:2040
#define N_ABS
Definition: stabs.c:69
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)
#define ARRAY_SIZE(a)
Definition: main.h:24
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
ULONG_PTR address
#define HeapReAlloc
Definition: compat.h:482
unsigned n_strx
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
ULONG_PTR offset
Definition: stabs.c:1102
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
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 HEAP_ZERO_MEMORY
Definition: compat.h:134
static int stabs_pts_read_number(struct ParseTypedefData *ptd, LONG_PTR *v)
Definition: stabs.c:398
static int stabs_pts_read_range_value(struct ParseTypedefData *ptd, struct pts_range_value *prv)
Definition: stabs.c:434
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Definition: compat.h:1369
unsigned source_new(struct module *module, const char *basedir, const char *source) DECLSPEC_HIDDEN
Definition: source.c:66
static void stabs_reset_includes(void)
Definition: stabs.c:199
Definition: name.c:38
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
unsigned n_value
static int stabs_pts_read_id(struct ParseTypedefData *ptd)
Definition: stabs.c:370
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
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
#define N_INDR
Definition: stabs.c:70
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define N_STAB
Definition: stabs.c:62
static int cu_include_stk_idx
Definition: stabs.c:144
static int stabs_add_include(int idx)
Definition: stabs.c:187
static struct symt ** cu_vector
Definition: stabs.c:145
static char * dest
Definition: rtl.c:135
char * name
Definition: stabs.c:132
DWORD64 Address
Definition: compat.h:847
char buf[1024]
Definition: stabs.c:301
#define memset(x, y, z)
Definition: compat.h:39
IMAGEHLP_MODULEW64 module
void user(int argc, const char *argv[])
Definition: cmds.c:1350
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
#define HeapFree(x, y, z)
Definition: compat.h:483
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
#define N_LBRAC
Definition: stabs.c:91
static int stabs_new_include(const char *file, ULONG_PTR val)
Definition: stabs.c:149
struct hash_table_elt hash_elt
struct ParseTypedefData::PTS_Error errors[16]
struct symt_compiland * symt_new_compiland(struct module *module, ULONG_PTR address, unsigned src_idx) DECLSPEC_HIDDEN
Definition: symbol.c:207
Definition: fci.c:126
struct hash_table_elt hash_elt
char * tag
Definition: main.c:59