ReactOS 0.4.15-dev-7961-gdcf9eb0
stabs.c File Reference
#include <sys/types.h>
#include <fcntl.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "dbghelp_private.h"
#include "image_private.h"
#include "wine/debug.h"
Include dependency graph for stabs.c:

Go to the source code of this file.

Classes

struct  include_def
 
struct  ParseTypedefData
 
struct  ParseTypedefData::PTS_Error
 
struct  pts_range_value
 
struct  pending_loc_var
 
struct  pending_line
 
struct  pending_object
 
struct  pending_list
 

Macros

#define strtoull   _strtoui64
 
#define N_STAB   0xe0
 
#define N_PEXT   0x10
 
#define N_TYPE   0x1e
 
#define N_EXT   0x01
 
#define N_UNDF   0x00
 
#define N_ABS   0x02
 
#define N_INDR   0x0a
 
#define N_SECT   0x0e
 
#define N_GSYM   0x20
 
#define N_FUN   0x24
 
#define N_STSYM   0x26
 
#define N_LCSYM   0x28
 
#define N_MAIN   0x2a
 
#define N_ROSYM   0x2c
 
#define N_BNSYM   0x2e
 
#define N_OPT   0x3c
 
#define N_RSYM   0x40
 
#define N_SLINE   0x44
 
#define N_ENSYM   0x4e
 
#define N_SO   0x64
 
#define N_OSO   0x66
 
#define N_LSYM   0x80
 
#define N_BINCL   0x82
 
#define N_SOL   0x84
 
#define N_PSYM   0xa0
 
#define N_EINCL   0xa2
 
#define N_LBRAC   0xc0
 
#define N_EXCL   0xc2
 
#define N_RBRAC   0xe0
 
#define MAX_INCLUDES   5120
 
#define PTS_DEBUG
 
#define PTS_ABORTIF(ptd, t)   do { if (t) { stabs_pts_push((ptd), __LINE__); return -1;} } while (0)
 

Enumerations

enum  pending_obj_kind { PENDING_VAR , PENDING_LINE }
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (dbghelp_stabs)
 
static void stab_strcpy (char *dest, int sz, const char *source)
 
static int stabs_new_include (const char *file, ULONG_PTR val)
 
static int stabs_find_include (const char *file, ULONG_PTR val)
 
static int stabs_add_include (int idx)
 
static void stabs_reset_includes (void)
 
static void stabs_free_includes (void)
 
static struct symt ** stabs_find_ref (LONG_PTR filenr, LONG_PTR subnr)
 
static struct symt ** stabs_read_type_enum (const char **x)
 
static void stabs_pts_push (struct ParseTypedefData *ptd, unsigned line)
 
static int stabs_get_basic (struct ParseTypedefData *ptd, unsigned basic, struct symt **symt)
 
static int stabs_pts_read_type_def (struct ParseTypedefData *ptd, const char *typename, struct symt **dt)
 
static int stabs_pts_read_id (struct ParseTypedefData *ptd)
 
static int stabs_pts_read_number (struct ParseTypedefData *ptd, LONG_PTR *v)
 
static int stabs_pts_read_type_reference (struct ParseTypedefData *ptd, LONG_PTR *filenr, LONG_PTR *subnr)
 
static int stabs_pts_read_range_value (struct ParseTypedefData *ptd, struct pts_range_value *prv)
 
static int stabs_pts_read_range (struct ParseTypedefData *ptd, const char *typename, struct symt **dt)
 
static int stabs_pts_read_method_info (struct ParseTypedefData *ptd)
 
static int stabs_pts_read_aggregate (struct ParseTypedefData *ptd, struct symt_udt *sdt)
 
static int stabs_pts_read_enum (struct ParseTypedefData *ptd, struct symt_enum *edt)
 
static int stabs_pts_read_array (struct ParseTypedefData *ptd, struct symt **adt)
 
static int stabs_parse_typedef (struct module *module, const char *ptr, const char *typename)
 
static struct symtstabs_parse_type (const char *stab)
 
static void pending_make_room (struct pending_list *pending)
 
static void pending_add_var (struct pending_list *pending, const char *name, enum DataKind dt, const struct location *loc)
 
static void pending_add_line (struct pending_list *pending, int source_idx, int line_num, ULONG_PTR offset, ULONG_PTR load_offset)
 
static void pending_flush (struct pending_list *pending, struct module *module, struct symt_function *func, struct symt_block *block)
 
static void stabs_finalize_function (struct module *module, struct symt_function *func, ULONG_PTR size)
 
static void stabbuf_append (char **buf, unsigned *buf_size, const char *str)
 
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)
 

Variables

static include_definclude_defs = NULL
 
static int num_include_def = 0
 
static int num_alloc_include_def = 0
 
static int cu_include_stack [MAX_INCLUDES]
 
static int cu_include_stk_idx = 0
 
static struct symt ** cu_vector = NULL
 
static int cu_nrofentries = 0
 
static struct symt_basicstabs_basic [36]
 

Macro Definition Documentation

◆ MAX_INCLUDES

#define MAX_INCLUDES   5120

Definition at line 138 of file stabs.c.

◆ N_ABS

#define N_ABS   0x02

Definition at line 69 of file stabs.c.

◆ N_BINCL

#define N_BINCL   0x82

Definition at line 87 of file stabs.c.

◆ N_BNSYM

#define N_BNSYM   0x2e

Definition at line 79 of file stabs.c.

◆ N_EINCL

#define N_EINCL   0xa2

Definition at line 90 of file stabs.c.

◆ N_ENSYM

#define N_ENSYM   0x4e

Definition at line 83 of file stabs.c.

◆ N_EXCL

#define N_EXCL   0xc2

Definition at line 92 of file stabs.c.

◆ N_EXT

#define N_EXT   0x01

Definition at line 65 of file stabs.c.

◆ N_FUN

#define N_FUN   0x24

Definition at line 74 of file stabs.c.

◆ N_GSYM

#define N_GSYM   0x20

Definition at line 73 of file stabs.c.

◆ N_INDR

#define N_INDR   0x0a

Definition at line 70 of file stabs.c.

◆ N_LBRAC

#define N_LBRAC   0xc0

Definition at line 91 of file stabs.c.

◆ N_LCSYM

#define N_LCSYM   0x28

Definition at line 76 of file stabs.c.

◆ N_LSYM

#define N_LSYM   0x80

Definition at line 86 of file stabs.c.

◆ N_MAIN

#define N_MAIN   0x2a

Definition at line 77 of file stabs.c.

◆ N_OPT

#define N_OPT   0x3c

Definition at line 80 of file stabs.c.

◆ N_OSO

#define N_OSO   0x66

Definition at line 85 of file stabs.c.

◆ N_PEXT

#define N_PEXT   0x10

Definition at line 63 of file stabs.c.

◆ N_PSYM

#define N_PSYM   0xa0

Definition at line 89 of file stabs.c.

◆ N_RBRAC

#define N_RBRAC   0xe0

Definition at line 93 of file stabs.c.

◆ N_ROSYM

#define N_ROSYM   0x2c

Definition at line 78 of file stabs.c.

◆ N_RSYM

#define N_RSYM   0x40

Definition at line 81 of file stabs.c.

◆ N_SECT

#define N_SECT   0x0e

Definition at line 71 of file stabs.c.

◆ N_SLINE

#define N_SLINE   0x44

Definition at line 82 of file stabs.c.

◆ N_SO

#define N_SO   0x64

Definition at line 84 of file stabs.c.

◆ N_SOL

#define N_SOL   0x84

Definition at line 88 of file stabs.c.

◆ N_STAB

#define N_STAB   0xe0

Definition at line 62 of file stabs.c.

◆ N_STSYM

#define N_STSYM   0x26

Definition at line 75 of file stabs.c.

◆ N_TYPE

#define N_TYPE   0x1e

Definition at line 64 of file stabs.c.

◆ N_UNDF

#define N_UNDF   0x00

Definition at line 68 of file stabs.c.

◆ PTS_ABORTIF

#define PTS_ABORTIF (   ptd,
  t 
)    do { if (t) { stabs_pts_push((ptd), __LINE__); return -1;} } while (0)

Definition at line 322 of file stabs.c.

◆ PTS_DEBUG

#define PTS_DEBUG

Definition at line 297 of file stabs.c.

◆ strtoull

#define strtoull   _strtoui64

Definition at line 58 of file stabs.c.

Enumeration Type Documentation

◆ pending_obj_kind

Enumerator
PENDING_VAR 
PENDING_LINE 

Definition at line 1084 of file stabs.c.

1085{
1088};
@ PENDING_VAR
Definition: stabs.c:1086
@ PENDING_LINE
Definition: stabs.c:1087

Function Documentation

◆ pending_add_line()

static void pending_add_line ( struct pending_list pending,
int  source_idx,
int  line_num,
ULONG_PTR  offset,
ULONG_PTR  load_offset 
)
inlinestatic

Definition at line 1154 of file stabs.c.

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}
GLintptr offset
Definition: glext.h:5920
static void pending_make_room(struct pending_list *pending)
Definition: stabs.c:1122
struct pending_object * objs
Definition: stabs.c:1117
unsigned num
Definition: stabs.c:1118

Referenced by stabs_parse().

◆ pending_add_var()

static void pending_add_var ( struct pending_list pending,
const char name,
enum DataKind  dt,
const struct location loc 
)
inlinestatic

Definition at line 1141 of file stabs.c.

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}
static void stab_strcpy(char *dest, int sz, const char *source)
Definition: stabs.c:95
static struct symt * stabs_parse_type(const char *stab)
Definition: stabs.c:1053
Definition: name.c:39

Referenced by stabs_parse().

◆ pending_flush()

static void pending_flush ( struct pending_list pending,
struct module module,
struct symt_function func,
struct symt_block block 
)
static

Definition at line 1167 of file stabs.c.

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}
#define ERR(fmt,...)
Definition: debug.h:110
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
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
@ DMT_MACHO
GLenum func
Definition: glext.h:6028
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
enum module_type type
static unsigned int block
Definition: xmlmemory.c:101

Referenced by stabs_parse().

◆ pending_make_room()

static void pending_make_room ( struct pending_list pending)
inlinestatic

Definition at line 1122 of file stabs.c.

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}
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
unsigned allocated
Definition: stabs.c:1119

Referenced by pending_add_line(), and pending_add_var().

◆ stab_strcpy()

static void stab_strcpy ( char dest,
int  sz,
const char source 
)
static

Definition at line 95 of file stabs.c.

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}
#define isdigit(c)
Definition: acclib.h:68
#define assert(x)
Definition: debug.h:53
static PVOID ptr
Definition: dispmode.c:27
static char * dest
Definition: rtl.c:135

Referenced by pending_add_var(), and stabs_parse().

◆ stabbuf_append()

static void stabbuf_append ( char **  buf,
unsigned buf_size,
const char str 
)
inlinestatic

Definition at line 1226 of file stabs.c.

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}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
const WCHAR * str
#define str_len
Definition: treelist.c:89

Referenced by stabs_parse().

◆ stabs_add_include()

static int stabs_add_include ( int  idx)
static

Definition at line 187 of file stabs.c.

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}
unsigned int idx
Definition: utils.c:41
static int cu_include_stk_idx
Definition: stabs.c:144
#define MAX_INCLUDES
Definition: stabs.c:138
static int cu_include_stack[MAX_INCLUDES]
Definition: stabs.c:143

Referenced by stabs_parse().

◆ stabs_finalize_function()

static void stabs_finalize_function ( struct module module,
struct symt_function func,
ULONG_PTR  size 
)
static

Definition at line 1204 of file stabs.c.

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}
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
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
@ loc_absolute
BOOL symt_normalize_function(struct module *module, const struct symt_function *func) DECLSPEC_HIDDEN
Definition: symbol.c:473
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
@ SymTagFuncDebugStart
Definition: compat.h:1602
GLsizeiptr size
Definition: glext.h:5919
DWORD64 Address
Definition: compat.h:1099

Referenced by stabs_parse().

◆ stabs_find_include()

static int stabs_find_include ( const char file,
ULONG_PTR  val 
)
static

Definition at line 174 of file stabs.c.

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}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
GLuint GLfloat * val
Definition: glext.h:7180
static include_def * include_defs
Definition: stabs.c:140
static int num_include_def
Definition: stabs.c:141
Definition: fci.c:127
Definition: pdh_main.c:94

Referenced by stabs_parse().

◆ stabs_find_ref()

static struct symt ** stabs_find_ref ( LONG_PTR  filenr,
LONG_PTR  subnr 
)
static

Definition at line 228 of file stabs.c.

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}
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define TRACE(s)
Definition: solgame.cpp:4
static struct symt ** cu_vector
Definition: stabs.c:145
static int cu_nrofentries
Definition: stabs.c:146
int nrofentries
Definition: stabs.c:135
struct symt ** vector
Definition: stabs.c:134
#define max(a, b)
Definition: svc.c:63
int ret

Referenced by stabs_pts_read_type_def(), and stabs_read_type_enum().

◆ stabs_free_includes()

static void stabs_free_includes ( void  )
static

Definition at line 209 of file stabs.c.

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}
#define HeapFree(x, y, z)
Definition: compat.h:735
static int num_alloc_include_def
Definition: stabs.c:142
static void stabs_reset_includes(void)
Definition: stabs.c:199

Referenced by stabs_parse().

◆ stabs_get_basic()

static int stabs_get_basic ( struct ParseTypedefData ptd,
unsigned  basic,
struct symt **  symt 
)
static

Definition at line 327 of file stabs.c.

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}
#define ARRAY_SIZE(A)
Definition: main.h:33
struct symt_basic * symt_new_basic(struct module *module, enum BasicType, const char *typename, unsigned size) DECLSPEC_HIDDEN
Definition: type.c:192
@ 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 PTS_ABORTIF(ptd, t)
Definition: stabs.c:322
static struct symt_basic * stabs_basic[36]
Definition: stabs.c:147
struct module * module
Definition: stabs.c:303

Referenced by stabs_pts_read_type_def().

◆ stabs_new_include()

static int stabs_new_include ( const char file,
ULONG_PTR  val 
)
static

◆ stabs_parse()

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 at line 1241 of file stabs.c.

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 * strchr(const char *String, int ch)
Definition: utclib.c:501
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
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
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_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_compiland * symt_new_compiland(struct module *module, ULONG_PTR address, unsigned src_idx) DECLSPEC_HIDDEN
Definition: symbol.c:207
BOOL symt_add_function_signature_parameter(struct module *module, struct symt_function_signature *sig, struct symt *param) DECLSPEC_HIDDEN
Definition: type.c:394
@ loc_regrel
@ loc_register
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT64 uint64_t
Definition: types.h:77
@ SymDia
Definition: compat.h:1063
@ 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
@ DataIsLocal
Definition: compat.h:1649
@ DataIsParam
Definition: compat.h:1651
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
#define debugstr_a
Definition: kernel32.h:31
static IPrintDialogCallback callback
Definition: printdlg.c:326
#define memset(x, y, z)
Definition: compat.h:39
static int stabs_find_include(const char *file, ULONG_PTR val)
Definition: stabs.c:174
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 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 stabs_add_include(int idx)
Definition: stabs.c:187
#define N_SECT
Definition: stabs.c:71
#define N_PSYM
Definition: stabs.c:89
#define N_STSYM
Definition: stabs.c:75
#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 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
#define N_BNSYM
Definition: stabs.c:79
#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
#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
#define N_UNDF
Definition: stabs.c:68
#define N_ROSYM
Definition: stabs.c:78
static int stabs_new_include(const char *file, ULONG_PTR val)
Definition: stabs.c:149
#define N_EXCL
Definition: stabs.c:92
#define N_OSO
Definition: stabs.c:85
#define N_TYPE
Definition: stabs.c:64
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
#define N_MAIN
Definition: stabs.c:77
SYM_TYPE SymType
Definition: compat.h:1075
IMAGEHLP_MODULEW64 module
unsigned n_strx
unsigned char n_type
unsigned n_value
struct hash_table_elt hash_elt
struct symt * type
ULONG_PTR address
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by elf_load_debug_info_from_map(), macho_parse_symtab(), and pe_load_stabs().

◆ stabs_parse_type()

static struct symt * stabs_parse_type ( const char stab)
static

Definition at line 1053 of file stabs.c.

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}
const GLubyte * c
Definition: glext.h:8905
static struct symt ** stabs_read_type_enum(const char **x)
Definition: stabs.c:272

Referenced by pending_add_var(), and stabs_parse().

◆ stabs_parse_typedef()

static int stabs_parse_typedef ( struct module module,
const char ptr,
const char typename 
)
static

Definition at line 1000 of file stabs.c.

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}
static int stabs_pts_read_type_def(struct ParseTypedefData *ptd, const char *typename, struct symt **dt)
Definition: stabs.c:782

Referenced by stabs_parse().

◆ stabs_pts_push()

static void stabs_pts_push ( struct ParseTypedefData ptd,
unsigned  line 
)
static

Definition at line 315 of file stabs.c.

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}
const char * ptr
Definition: stabs.c:300
struct ParseTypedefData::PTS_Error errors[16]
Definition: parser.c:49

◆ stabs_pts_read_aggregate()

static int stabs_pts_read_aggregate ( struct ParseTypedefData ptd,
struct symt_udt sdt 
)
inlinestatic

Definition at line 597 of file stabs.c.

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}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
BOOL symt_get_info(struct module *module, const struct symt *type, IMAGEHLP_SYMBOL_TYPE_INFO req, void *pInfo) DECLSPEC_HIDDEN
Definition: type.c:536
const char * symt_get_name(const struct symt *sym) DECLSPEC_HIDDEN
Definition: type.c:81
BOOL symt_set_udt_size(struct module *module, struct symt_udt *type, unsigned size) DECLSPEC_HIDDEN
Definition: type.c:242
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
@ TI_GET_LENGTH
Definition: compat.h:1417
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static int stabs_pts_read_number(struct ParseTypedefData *ptd, LONG_PTR *v)
Definition: stabs.c:398
static int stabs_pts_read_method_info(struct ParseTypedefData *ptd)
Definition: stabs.c:558
static int stabs_pts_read_id(struct ParseTypedefData *ptd)
Definition: stabs.c:370
char buf[1024]
Definition: stabs.c:301
uint64_t DWORD64
Definition: typedefs.h:67

Referenced by stabs_pts_read_type_def().

◆ stabs_pts_read_array()

static int stabs_pts_read_array ( struct ParseTypedefData ptd,
struct symt **  adt 
)
inlinestatic

Definition at line 758 of file stabs.c.

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}
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

Referenced by stabs_pts_read_type_def().

◆ stabs_pts_read_enum()

static int stabs_pts_read_enum ( struct ParseTypedefData ptd,
struct symt_enum edt 
)
inlinestatic

Definition at line 739 of file stabs.c.

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}
BOOL symt_add_enum_element(struct module *module, struct symt_enum *enum_type, const char *name, int value) DECLSPEC_HIDDEN
Definition: type.c:319

Referenced by stabs_pts_read_type_def().

◆ stabs_pts_read_id()

static int stabs_pts_read_id ( struct ParseTypedefData ptd)
static

Definition at line 370 of file stabs.c.

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}
const GLint * first
Definition: glext.h:5794
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by stabs_pts_read_aggregate(), stabs_pts_read_enum(), and stabs_pts_read_type_def().

◆ stabs_pts_read_method_info()

static int stabs_pts_read_method_info ( struct ParseTypedefData ptd)
inlinestatic

Definition at line 558 of file stabs.c.

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}

Referenced by stabs_pts_read_aggregate().

◆ stabs_pts_read_number()

static int stabs_pts_read_number ( struct ParseTypedefData ptd,
LONG_PTR v 
)
static

Definition at line 398 of file stabs.c.

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}
const GLdouble * v
Definition: gl.h:2040
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
static UINT UINT last
Definition: font.c:45

Referenced by stabs_pts_read_aggregate(), stabs_pts_read_array(), stabs_pts_read_enum(), stabs_pts_read_method_info(), stabs_pts_read_type_def(), and stabs_pts_read_type_reference().

◆ stabs_pts_read_range()

static int stabs_pts_read_range ( struct ParseTypedefData ptd,
const char typename,
struct symt **  dt 
)
static

Definition at line 476 of file stabs.c.

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}
BasicType
Definition: compat.h:1616
static int stabs_pts_read_range_value(struct ParseTypedefData *ptd, struct pts_range_value *prv)
Definition: stabs.c:434
Definition: send.c:48
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by stabs_pts_read_type_def().

◆ stabs_pts_read_range_value()

static int stabs_pts_read_range_value ( struct ParseTypedefData ptd,
struct pts_range_value prv 
)
static

Definition at line 434 of file stabs.c.

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}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define strtoull
Definition: stabs.c:58
ULONGLONG val
Definition: stabs.c:430

Referenced by stabs_pts_read_range().

◆ stabs_pts_read_type_def()

static int stabs_pts_read_type_def ( struct ParseTypedefData ptd,
const char typename,
struct symt **  dt 
)
static

Definition at line 782 of file stabs.c.

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}
struct symt_pointer * symt_new_pointer(struct module *module, struct symt *ref_type, ULONG_PTR size) DECLSPEC_HIDDEN
Definition: type.c:414
struct symt_udt * symt_new_udt(struct module *module, const char *typename, unsigned size, enum UdtKind kind) DECLSPEC_HIDDEN
Definition: type.c:219
struct symt_enum * symt_new_enum(struct module *module, const char *typename, struct symt *basetype) DECLSPEC_HIDDEN
Definition: type.c:304
@ SymTagUDT
Definition: compat.h:1592
UdtKind
Definition: compat.h:1639
@ UdtStruct
Definition: compat.h:1640
@ UdtUnion
Definition: compat.h:1642
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
static struct symt ** stabs_find_ref(LONG_PTR filenr, LONG_PTR subnr)
Definition: stabs.c:228
static int stabs_get_basic(struct ParseTypedefData *ptd, unsigned basic, struct symt **symt)
Definition: stabs.c:327
static int stabs_pts_read_aggregate(struct ParseTypedefData *ptd, struct symt_udt *sdt)
Definition: stabs.c:597
static int stabs_pts_read_range(struct ParseTypedefData *ptd, const char *typename, struct symt **dt)
Definition: stabs.c:476
static int stabs_pts_read_array(struct ParseTypedefData *ptd, struct symt **adt)
Definition: stabs.c:758
struct symt symt
enum UdtKind kind
struct hash_table_elt hash_elt

Referenced by stabs_parse_typedef(), stabs_pts_read_aggregate(), stabs_pts_read_array(), stabs_pts_read_method_info(), stabs_pts_read_range(), and stabs_pts_read_type_def().

◆ stabs_pts_read_type_reference()

static int stabs_pts_read_type_reference ( struct ParseTypedefData ptd,
LONG_PTR filenr,
LONG_PTR subnr 
)
static

Definition at line 408 of file stabs.c.

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}

Referenced by stabs_pts_read_type_def().

◆ stabs_read_type_enum()

static struct symt ** stabs_read_type_enum ( const char **  x)
static

Definition at line 272 of file stabs.c.

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}
GLuint GLuint end
Definition: gl.h:1545

Referenced by stabs_parse_type(), and stabs_pts_read_aggregate().

◆ stabs_reset_includes()

static void stabs_reset_includes ( void  )
static

Definition at line 199 of file stabs.c.

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}

Referenced by stabs_free_includes(), and stabs_parse().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( dbghelp_stabs  )

Variable Documentation

◆ cu_include_stack

int cu_include_stack[MAX_INCLUDES]
static

Definition at line 143 of file stabs.c.

Referenced by stabs_add_include(), and stabs_find_ref().

◆ cu_include_stk_idx

int cu_include_stk_idx = 0
static

Definition at line 144 of file stabs.c.

Referenced by stabs_add_include(), stabs_find_ref(), and stabs_reset_includes().

◆ cu_nrofentries

int cu_nrofentries = 0
static

Definition at line 146 of file stabs.c.

Referenced by stabs_find_ref(), stabs_free_includes(), and stabs_reset_includes().

◆ cu_vector

struct symt** cu_vector = NULL
static

Definition at line 145 of file stabs.c.

Referenced by stabs_find_ref(), stabs_free_includes(), and stabs_reset_includes().

◆ include_defs

include_def* include_defs = NULL
static

◆ num_alloc_include_def

int num_alloc_include_def = 0
static

Definition at line 142 of file stabs.c.

Referenced by stabs_free_includes(), and stabs_new_include().

◆ num_include_def

int num_include_def = 0
static

Definition at line 141 of file stabs.c.

Referenced by stabs_find_include(), stabs_free_includes(), and stabs_new_include().

◆ stabs_basic

struct symt_basic* stabs_basic[36]
static

Definition at line 147 of file stabs.c.

Referenced by stabs_get_basic(), and stabs_parse().