blob: c661ce08c8f94028655f817ed192bf1137513032 [file] [log] [blame]
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001/*
2 * File msc.c - read VC++ debug information from COFF and eventually
3 * from PDB files.
4 *
5 * Copyright (C) 1996, Eric Youngdale.
Ulrich Weigand6011e982000-11-07 20:29:20 +00006 * Copyright (C) 1999, 2000, Ulrich Weigand.
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00007 *
8 * Note - this handles reading debug information for 32 bit applications
9 * that run under Windows-NT for example. I doubt that this would work well
10 * for 16 bit applications, but I don't think it really matters since the
11 * file format is different, and we should never get in here in such cases.
Alexandre Julliardc6c09441997-01-12 18:32:19 +000012 *
13 * TODO:
14 * Get 16 bit CV stuff working.
15 * Add symbol size to internal symbol table.
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000016 */
17
Marcus Meissnerb0d52b01999-02-28 19:59:00 +000018#include "config.h"
Alexandre Julliardc6c09441997-01-12 18:32:19 +000019#include <stdlib.h>
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000020
Alexandre Julliardc6c09441997-01-12 18:32:19 +000021#include <string.h>
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000022#include <unistd.h>
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +000023#ifndef PATH_MAX
24#define PATH_MAX _MAX_PATH
25#endif
Marcus Meissner317af321999-02-17 13:51:06 +000026#include "debugger.h"
Alexandre Julliard638f1691999-01-17 16:32:32 +000027#include "file.h"
Alexandre Julliardc6c09441997-01-12 18:32:19 +000028
Ulrich Weigand6011e982000-11-07 20:29:20 +000029typedef struct
30{
31 DWORD from;
32 DWORD to;
33
34} OMAP_DATA;
35
Eric Poueche9392062000-11-15 22:16:26 +000036typedef struct tagMSC_DBG_INFO
Ulrich Weigand6011e982000-11-07 20:29:20 +000037{
38 int nsect;
39 PIMAGE_SECTION_HEADER sectp;
40
41 int nomap;
42 OMAP_DATA * omapp;
43
Eric Pouechac11a682000-03-26 13:37:39 +000044} MSC_DBG_INFO;
45
Ulrich Weigand6011e982000-11-07 20:29:20 +000046/*========================================================================
47 * Debug file access helper routines
48 */
49
50
51/***********************************************************************
52 * DEBUG_LocateDebugInfoFile
53 *
54 * NOTE: dbg_filename must be at least MAX_PATHNAME_LEN bytes in size
Eric Pouechac11a682000-03-26 13:37:39 +000055 */
Eric Poueche5efa0c2000-04-13 19:31:58 +000056static void DEBUG_LocateDebugInfoFile(const char *filename, char *dbg_filename)
Sergey Turchanovd72e2de1999-01-24 09:46:21 +000057{
Eric Poueche5efa0c2000-04-13 19:31:58 +000058 char *str1 = DBG_alloc(MAX_PATHNAME_LEN);
59 char *str2 = DBG_alloc(MAX_PATHNAME_LEN*10);
60 const char *file;
Sergey Turchanovd72e2de1999-01-24 09:46:21 +000061 char *name_part;
Sergey Turchanovd72e2de1999-01-24 09:46:21 +000062
63 file = strrchr(filename, '\\');
64 if( file == NULL ) file = filename; else file++;
65
Eric Poueche5efa0c2000-04-13 19:31:58 +000066 if ((GetEnvironmentVariable("_NT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
67 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
68 (GetEnvironmentVariable("_NT_ALT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
69 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
70 (SearchPath(NULL, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part)))
71 lstrcpyn(dbg_filename, str2, MAX_PATHNAME_LEN);
Sergey Turchanovd72e2de1999-01-24 09:46:21 +000072 else
Eric Poueche5efa0c2000-04-13 19:31:58 +000073 lstrcpyn(dbg_filename, filename, MAX_PATHNAME_LEN);
Ove Kaavendda17c61999-04-25 12:24:42 +000074 DBG_free(str1);
75 DBG_free(str2);
Eric Poueche5efa0c2000-04-13 19:31:58 +000076}
77
78/***********************************************************************
79 * DEBUG_MapDebugInfoFile
80 */
81static void* DEBUG_MapDebugInfoFile(const char* name, DWORD offset, DWORD size,
82 HANDLE* hFile, HANDLE* hMap)
83{
Eric Poueche5efa0c2000-04-13 19:31:58 +000084 DWORD g_offset; /* offset aligned on map granuality */
85 DWORD g_size; /* size to map, with offset aligned */
86 char* ret;
87
88 *hMap = 0;
89
90 if (name != NULL) {
91 char filename[MAX_PATHNAME_LEN];
92
93 DEBUG_LocateDebugInfoFile(name, filename);
François Gougetd5042c42000-12-29 05:38:00 +000094 if ((*hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
Eric Poueche5efa0c2000-04-13 19:31:58 +000095 return NULL;
96 }
97
98 if (!size) {
99 DWORD file_size = GetFileSize(*hFile, NULL);
100 if (file_size == (DWORD)-1) return NULL;
101 size = file_size - offset;
102 }
103
104 g_offset = offset & ~0xFFFF; /* FIXME: is granularity portable ? */
105 g_size = offset + size - g_offset;
106
107 if ((*hMap = CreateFileMapping(*hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == 0)
108 return NULL;
109
110 if ((ret = MapViewOfFile(*hMap, FILE_MAP_READ, 0, g_offset, g_size)) != NULL)
111 ret += offset - g_offset;
112 return ret;
113}
114
115/***********************************************************************
116 * DEBUG_UnmapDebugInfoFile
117 */
118static void DEBUG_UnmapDebugInfoFile(HANDLE hFile, HANDLE hMap, void* addr)
119{
120 if (addr) UnmapViewOfFile(addr);
121 if (hMap) CloseHandle(hMap);
122 if (hFile) CloseHandle(hFile);
Sergey Turchanovd72e2de1999-01-24 09:46:21 +0000123}
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000124
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000125
Ulrich Weigand6011e982000-11-07 20:29:20 +0000126
127/*========================================================================
128 * Process COFF debug information.
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000129 */
Ulrich Weigand6011e982000-11-07 20:29:20 +0000130
Eric Pouech5394ab82000-11-12 03:40:55 +0000131struct CoffFile
Ulrich Weigand6011e982000-11-07 20:29:20 +0000132{
133 unsigned int startaddr;
134 unsigned int endaddr;
Eric Pouech5394ab82000-11-12 03:40:55 +0000135 const char *filename;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000136 int linetab_offset;
137 int linecnt;
138 struct name_hash **entries;
139 int neps;
140 int neps_alloc;
141};
142
Eric Pouech5394ab82000-11-12 03:40:55 +0000143struct CoffFileSet
Ulrich Weigand6011e982000-11-07 20:29:20 +0000144{
Eric Pouech5394ab82000-11-12 03:40:55 +0000145 struct CoffFile *files;
146 int nfiles;
147 int nfiles_alloc;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000148};
149
Eric Pouech5394ab82000-11-12 03:40:55 +0000150static const char* DEBUG_GetCoffName( PIMAGE_SYMBOL coff_sym, const char* coff_strtab )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000151{
Eric Pouech5394ab82000-11-12 03:40:55 +0000152 static char namebuff[9];
153 const char* nampnt;
154
155 if( coff_sym->N.Name.Short )
156 {
157 memcpy(namebuff, coff_sym->N.ShortName, 8);
158 namebuff[8] = '\0';
159 nampnt = &namebuff[0];
160 }
161 else
162 {
163 nampnt = coff_strtab + coff_sym->N.Name.Long;
164 }
165
166 if( nampnt[0] == '_' )
167 nampnt++;
168 return nampnt;
169}
170
171static int DEBUG_AddCoffFile( struct CoffFileSet* coff_files, const char* filename )
172{
173 struct CoffFile* file;
174
175 if( coff_files->nfiles + 1 >= coff_files->nfiles_alloc )
176 {
177 coff_files->nfiles_alloc += 10;
178 coff_files->files = (struct CoffFile *) DBG_realloc(coff_files->files,
179 coff_files->nfiles_alloc * sizeof(struct CoffFile));
180 }
181 file = coff_files->files + coff_files->nfiles;
182 file->startaddr = 0xffffffff;
183 file->endaddr = 0;
184 file->filename = filename;
185 file->linetab_offset = -1;
186 file->linecnt = 0;
187 file->entries = NULL;
188 file->neps = file->neps_alloc = 0;
189
190 return coff_files->nfiles++;
191}
192
193static void DEBUG_AddCoffSymbol( struct CoffFile* coff_file, struct name_hash* sym )
194{
195 if( coff_file->neps + 1 >= coff_file->neps_alloc )
196 {
197 coff_file->neps_alloc += 10;
198 coff_file->entries = (struct name_hash **)
199 DBG_realloc(coff_file->entries,
200 coff_file->neps_alloc * sizeof(struct name_hash *));
201 }
202 coff_file->entries[coff_file->neps++] = sym;
203}
Ulrich Weigand6011e982000-11-07 20:29:20 +0000204
Eric Poueche9392062000-11-15 22:16:26 +0000205static enum DbgInfoLoad DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000206{
Eric Pouech5394ab82000-11-12 03:40:55 +0000207 PIMAGE_AUX_SYMBOL aux;
208 PIMAGE_COFF_SYMBOLS_HEADER coff;
209 PIMAGE_LINENUMBER coff_linetab;
210 PIMAGE_LINENUMBER linepnt;
211 char * coff_strtab;
212 PIMAGE_SYMBOL coff_sym;
213 PIMAGE_SYMBOL coff_symbols;
214 struct CoffFileSet coff_files;
215 int curr_file_idx = -1;
Joerg Mayerd18140c2000-12-26 01:28:51 +0000216 unsigned int i;
217 int j;
218 int k;
219 int l;
Eric Pouech5394ab82000-11-12 03:40:55 +0000220 int linetab_indx;
221 const char * nampnt;
222 int naux;
223 DBG_VALUE new_value;
Eric Poueche9392062000-11-15 22:16:26 +0000224 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000225
226 DEBUG_Printf(DBG_CHN_TRACE, "Processing COFF symbols...\n");
227
Eric Pouech5394ab82000-11-12 03:40:55 +0000228 assert(sizeof(IMAGE_SYMBOL) == IMAGE_SIZEOF_SYMBOL);
229 assert(sizeof(IMAGE_LINENUMBER) == IMAGE_SIZEOF_LINENUMBER);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000230
Eric Pouech5394ab82000-11-12 03:40:55 +0000231 coff_files.files = NULL;
232 coff_files.nfiles = coff_files.nfiles_alloc = 0;
233
234 coff = (PIMAGE_COFF_SYMBOLS_HEADER) root;
235
236 coff_symbols = (PIMAGE_SYMBOL) ((unsigned int) coff + coff->LvaToFirstSymbol);
237 coff_linetab = (PIMAGE_LINENUMBER) ((unsigned int) coff + coff->LvaToFirstLinenumber);
238 coff_strtab = (char *) (coff_symbols + coff->NumberOfSymbols);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000239
240 linetab_indx = 0;
241
242 new_value.cookie = DV_TARGET;
243 new_value.type = NULL;
244
Eric Pouech5394ab82000-11-12 03:40:55 +0000245 for(i=0; i < coff->NumberOfSymbols; i++ )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000246 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000247 coff_sym = coff_symbols + i;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000248 naux = coff_sym->NumberOfAuxSymbols;
249
250 if( coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE )
251 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000252 curr_file_idx = DEBUG_AddCoffFile( &coff_files, (char *) (coff_sym + 1) );
253 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000254 i += naux;
255 continue;
256 }
257
Eric Pouech5394ab82000-11-12 03:40:55 +0000258 if (curr_file_idx < 0) {
259 assert(coff_files.nfiles == 0 && coff_files.nfiles_alloc == 0);
260 curr_file_idx = DEBUG_AddCoffFile( &coff_files, "<none>" );
261 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
262 }
263
Ulrich Weigand6011e982000-11-07 20:29:20 +0000264 /*
265 * This guy marks the size and location of the text section
266 * for the current file. We need to keep track of this so
267 * we can figure out what file the different global functions
268 * go with.
269 */
270 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
271 && (naux != 0)
272 && (coff_sym->Type == 0)
273 && (coff_sym->SectionNumber == 1) )
274 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000275 aux = (PIMAGE_AUX_SYMBOL) (coff_sym + 1);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000276
Eric Pouech5394ab82000-11-12 03:40:55 +0000277 if( coff_files.files[curr_file_idx].linetab_offset != -1 )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000278 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000279 /*
280 * Save this so we can still get the old name.
281 */
282 const char* fn = coff_files.files[curr_file_idx].filename;
283
284#ifdef MORE_DBG
285 DEBUG_Printf(DBG_CHN_TRACE, "Duplicating sect from %s: %lx %x %x %d %d\n",
286 coff_files.files[curr_file_idx].filename,
287 aux->Section.Length,
288 aux->Section.NumberOfRelocations,
289 aux->Section.NumberOfLinenumbers,
290 aux->Section.Number,
291 aux->Section.Selection);
292 DEBUG_Printf(DBG_CHN_TRACE, "More sect %d %s %08lx %d %d %d\n",
Ulrich Weigand6011e982000-11-07 20:29:20 +0000293 coff_sym->SectionNumber,
Eric Pouech5394ab82000-11-12 03:40:55 +0000294 DEBUG_GetCoffName( coff_sym, coff_strtab ),
Ulrich Weigand6011e982000-11-07 20:29:20 +0000295 coff_sym->Value,
296 coff_sym->Type,
297 coff_sym->StorageClass,
298 coff_sym->NumberOfAuxSymbols);
299#endif
300
301 /*
Ulrich Weigand6011e982000-11-07 20:29:20 +0000302 * Duplicate the file entry. We have no way to describe
303 * multiple text sections in our current way of handling things.
304 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000305 DEBUG_AddCoffFile( &coff_files, fn );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000306 }
Eric Pouech5394ab82000-11-12 03:40:55 +0000307#ifdef MORE_DBG
Ulrich Weigand6011e982000-11-07 20:29:20 +0000308 else
309 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000310 DEBUG_Printf(DBG_CHN_TRACE, "New text sect from %s: %lx %x %x %d %d\n",
311 coff_files.files[curr_file_idx].filename,
312 aux->Section.Length,
313 aux->Section.NumberOfRelocations,
314 aux->Section.NumberOfLinenumbers,
315 aux->Section.Number,
316 aux->Section.Selection);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000317 }
318#endif
319
Eric Pouech5394ab82000-11-12 03:40:55 +0000320 if( coff_files.files[curr_file_idx].startaddr > coff_sym->Value )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000321 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000322 coff_files.files[curr_file_idx].startaddr = coff_sym->Value;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000323 }
324
Eric Pouech5394ab82000-11-12 03:40:55 +0000325 if( coff_files.files[curr_file_idx].endaddr < coff_sym->Value + aux->Section.Length )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000326 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000327 coff_files.files[curr_file_idx].endaddr = coff_sym->Value + aux->Section.Length;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000328 }
329
Eric Pouech5394ab82000-11-12 03:40:55 +0000330 coff_files.files[curr_file_idx].linetab_offset = linetab_indx;
331 coff_files.files[curr_file_idx].linecnt = aux->Section.NumberOfLinenumbers;
332 linetab_indx += aux->Section.NumberOfLinenumbers;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000333 i += naux;
334 continue;
335 }
336
337 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
338 && (naux == 0)
339 && (coff_sym->SectionNumber == 1) )
340 {
Eric Poueche9392062000-11-15 22:16:26 +0000341 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000342 /*
343 * This is a normal static function when naux == 0.
344 * Just register it. The current file is the correct
345 * one in this instance.
346 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000347 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000348
349 new_value.addr.seg = 0;
Eric Pouech5394ab82000-11-12 03:40:55 +0000350 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000351
Eric Pouech5394ab82000-11-12 03:40:55 +0000352#ifdef MORE_DBG
Ulrich Weigand6011e982000-11-07 20:29:20 +0000353 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding static symbol %s\n", nampnt);
354#endif
Eric Pouech5394ab82000-11-12 03:40:55 +0000355
356 /* FIXME: was adding symbol to this_file ??? */
357 DEBUG_AddCoffSymbol( &coff_files.files[curr_file_idx],
358 DEBUG_AddSymbol( nampnt, &new_value,
359 coff_files.files[curr_file_idx].filename,
360 SYM_WIN32 | SYM_FUNC ) );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000361 i += naux;
362 continue;
363 }
364
365 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
366 && ISFCN(coff_sym->Type)
367 && (coff_sym->SectionNumber > 0) )
368 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000369 const char* this_file = NULL;
Eric Poueche9392062000-11-15 22:16:26 +0000370 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
Eric Pouech5394ab82000-11-12 03:40:55 +0000371 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000372
373 new_value.addr.seg = 0;
Eric Pouech5394ab82000-11-12 03:40:55 +0000374 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000375
Eric Pouech5394ab82000-11-12 03:40:55 +0000376#ifdef MORE_DBG
377 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000378
Eric Pouech5394ab82000-11-12 03:40:55 +0000379 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global symbol %s (sect=%s)\n",
380 nampnt, MSC_INFO(module)->sectp[coff_sym->SectionNumber - 1].Name);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000381#endif
382
383 /*
384 * Now we need to figure out which file this guy belongs to.
385 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000386 for(j=0; j < coff_files.nfiles; j++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000387 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000388 if( coff_files.files[j].startaddr <= base + coff_sym->Value
389 && coff_files.files[j].endaddr > base + coff_sym->Value )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000390 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000391 this_file = coff_files.files[j].filename;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000392 break;
393 }
394 }
Eric Pouech5394ab82000-11-12 03:40:55 +0000395 if (j < coff_files.nfiles) {
396 DEBUG_AddCoffSymbol( &coff_files.files[j],
397 DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 | SYM_FUNC ) );
398 } else {
399 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_FUNC );
400 }
Ulrich Weigand6011e982000-11-07 20:29:20 +0000401 i += naux;
402 continue;
403 }
404
405 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
406 && (coff_sym->SectionNumber > 0) )
407 {
Eric Poueche9392062000-11-15 22:16:26 +0000408 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000409 /*
410 * Similar to above, but for the case of data symbols.
411 * These aren't treated as entrypoints.
412 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000413 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000414
415 new_value.addr.seg = 0;
Eric Pouech5394ab82000-11-12 03:40:55 +0000416 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000417
Eric Pouech5394ab82000-11-12 03:40:55 +0000418#ifdef MORE_DBG
419 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000420
421 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global data symbol %s\n", nampnt);
422#endif
423
424 /*
425 * Now we need to figure out which file this guy belongs to.
426 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000427 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_DATA );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000428 i += naux;
429 continue;
430 }
431
432 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
433 && (naux == 0) )
434 {
435 /*
436 * Ignore these. They don't have anything to do with
437 * reality.
438 */
439 i += naux;
440 continue;
441 }
442
Eric Pouech5394ab82000-11-12 03:40:55 +0000443#ifdef MORE_DBG
444 DEBUG_Printf(DBG_CHN_TRACE,"Skipping unknown entry '%s' %d %d %d\n",
445 DEBUG_GetCoffName( coff_sym, coff_strtab ),
446 coff_sym->StorageClass, coff_sym->SectionNumber, naux);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000447#endif
448
449 /*
450 * For now, skip past the aux entries.
451 */
452 i += naux;
453
454 }
455
456 /*
457 * OK, we now should have a list of files, and we should have a list
458 * of entrypoints. We need to sort the entrypoints so that we are
459 * able to tie the line numbers with the given functions within the
460 * file.
461 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000462 if( coff_files.files != NULL )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000463 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000464 for(j=0; j < coff_files.nfiles; j++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000465 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000466 if( coff_files.files[j].entries != NULL )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000467 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000468 qsort(coff_files.files[j].entries, coff_files.files[j].neps,
Ulrich Weigand6011e982000-11-07 20:29:20 +0000469 sizeof(struct name_hash *), DEBUG_cmp_sym);
470 }
471 }
472
473 /*
474 * Now pick apart the line number tables, and attach the entries
475 * to the given functions.
476 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000477 for(j=0; j < coff_files.nfiles; j++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000478 {
Joerg Mayerd18140c2000-12-26 01:28:51 +0000479 l = 0;
Eric Pouech5394ab82000-11-12 03:40:55 +0000480 if( coff_files.files[j].neps != 0 )
481 for(k=0; k < coff_files.files[j].linecnt; k++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000482 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000483 linepnt = coff_linetab + coff_files.files[j].linetab_offset + k;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000484 /*
485 * If we have spilled onto the next entrypoint, then
486 * bump the counter..
487 */
488 while(TRUE)
489 {
Joerg Mayerd18140c2000-12-26 01:28:51 +0000490 if (l+1 >= coff_files.files[j].neps) break;
491 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l+1], &new_value.addr);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000492 if( (((unsigned int)module->load_addr +
Eric Pouech5394ab82000-11-12 03:40:55 +0000493 linepnt->Type.VirtualAddress) >= new_value.addr.off) )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000494 {
Joerg Mayerd18140c2000-12-26 01:28:51 +0000495 l++;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000496 } else break;
497 }
498
499 /*
500 * Add the line number. This is always relative to the
501 * start of the function, so we need to subtract that offset
502 * first.
503 */
Joerg Mayerd18140c2000-12-26 01:28:51 +0000504 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l], &new_value.addr);
505 DEBUG_AddLineNumber(coff_files.files[j].entries[l],
Eric Pouech5394ab82000-11-12 03:40:55 +0000506 linepnt->Linenumber,
Ulrich Weigand6011e982000-11-07 20:29:20 +0000507 (unsigned int) module->load_addr
Eric Pouech5394ab82000-11-12 03:40:55 +0000508 + linepnt->Type.VirtualAddress
Ulrich Weigand6011e982000-11-07 20:29:20 +0000509 - new_value.addr.off);
510 }
511 }
512 }
513
Eric Poueche9392062000-11-15 22:16:26 +0000514 dil = DIL_LOADED;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000515
Eric Pouech5394ab82000-11-12 03:40:55 +0000516 if( coff_files.files != NULL )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000517 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000518 for(j=0; j < coff_files.nfiles; j++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000519 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000520 if( coff_files.files[j].entries != NULL )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000521 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000522 DBG_free(coff_files.files[j].entries);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000523 }
524 }
Eric Pouech5394ab82000-11-12 03:40:55 +0000525 DBG_free(coff_files.files);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000526 }
527
Eric Poueche9392062000-11-15 22:16:26 +0000528 return dil;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000529
530}
531
532
533
534/*========================================================================
535 * Process CodeView type information.
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000536 */
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000537
538union codeview_type
539{
540 struct
541 {
542 short int len;
543 short int id;
544 } generic;
545
546 struct
547 {
548 short int len;
549 short int id;
550 short int attribute;
551 short int datatype;
552 unsigned char variant[1];
553 } pointer;
554
555 struct
556 {
557 short int len;
558 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000559 unsigned int datatype;
560 unsigned int attribute;
561 unsigned char variant[1];
562 } pointer32;
563
564 struct
565 {
566 short int len;
567 short int id;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000568 unsigned char nbits;
569 unsigned char bitoff;
570 unsigned short type;
571 } bitfield;
572
573 struct
574 {
575 short int len;
576 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000577 unsigned int type;
578 unsigned char nbits;
579 unsigned char bitoff;
580 } bitfield32;
581
582 struct
583 {
584 short int len;
585 short int id;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000586 short int elemtype;
587 short int idxtype;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000588 unsigned short int arrlen; /* numeric leaf */
589#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000590 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000591#endif
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000592 } array;
593
594 struct
595 {
596 short int len;
597 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000598 unsigned int elemtype;
599 unsigned int idxtype;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000600 unsigned short int arrlen; /* numeric leaf */
601#if 0
Ulrich Weigand8142a161999-12-10 03:43:53 +0000602 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000603#endif
Ulrich Weigand8142a161999-12-10 03:43:53 +0000604 } array32;
605
606 struct
607 {
608 short int len;
609 short int id;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000610 short int n_element;
611 short int fieldlist;
612 short int property;
613 short int derived;
614 short int vshape;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000615 unsigned short int structlen; /* numeric leaf */
616#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000617 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000618#endif
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000619 } structure;
620
621 struct
622 {
623 short int len;
624 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000625 short int n_element;
626 short int property;
627 unsigned int fieldlist;
628 unsigned int derived;
629 unsigned int vshape;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000630 unsigned short int structlen; /* numeric leaf */
631#if 0
Ulrich Weigand8142a161999-12-10 03:43:53 +0000632 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000633#endif
Ulrich Weigand8142a161999-12-10 03:43:53 +0000634 } structure32;
635
636 struct
637 {
638 short int len;
639 short int id;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000640 short int count;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000641 short int fieldlist;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000642 short int property;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000643 unsigned short int un_len; /* numeric leaf */
644#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000645 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000646#endif
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000647 } t_union;
648
649 struct
650 {
651 short int len;
652 short int id;
653 short int count;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000654 short int property;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000655 unsigned int fieldlist;
656 unsigned short int un_len; /* numeric leaf */
657#if 0
Ulrich Weigand8142a161999-12-10 03:43:53 +0000658 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000659#endif
Ulrich Weigand8142a161999-12-10 03:43:53 +0000660 } t_union32;
661
662 struct
663 {
664 short int len;
665 short int id;
666 short int count;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000667 short int type;
668 short int field;
669 short int property;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000670 unsigned char name[1];
671 } enumeration;
672
673 struct
674 {
Ulrich Weigand8142a161999-12-10 03:43:53 +0000675 short int len;
676 short int id;
677 short int count;
678 short int property;
679 unsigned int type;
680 unsigned int field;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000681 unsigned char name[1];
682 } enumeration32;
683
684 struct
685 {
Ulrich Weigand164bac92000-04-25 19:53:49 +0000686 short int len;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000687 short int id;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000688 unsigned char list[1];
689 } fieldlist;
690};
691
692union codeview_fieldtype
693{
694 struct
695 {
696 short int id;
697 } generic;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000698
699 struct
700 {
701 short int id;
702 short int type;
703 short int attribute;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000704 unsigned short int offset; /* numeric leaf */
705 } bclass;
706
707 struct
708 {
709 short int id;
710 short int attribute;
711 unsigned int type;
712 unsigned short int offset; /* numeric leaf */
713 } bclass32;
714
715 struct
716 {
717 short int id;
718 short int btype;
719 short int vbtype;
720 short int attribute;
721 unsigned short int vbpoff; /* numeric leaf */
722#if 0
723 unsigned short int vboff; /* numeric leaf */
724#endif
725 } vbclass;
726
727 struct
728 {
729 short int id;
730 short int attribute;
731 unsigned int btype;
732 unsigned int vbtype;
733 unsigned short int vbpoff; /* numeric leaf */
734#if 0
735 unsigned short int vboff; /* numeric leaf */
736#endif
737 } vbclass32;
738
739 struct
740 {
741 short int id;
742 short int attribute;
743 unsigned short int value; /* numeric leaf */
744#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000745 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000746#endif
747 } enumerate;
748
749 struct
750 {
751 short int id;
752 short int type;
753 unsigned char name[1];
754 } friendfcn;
755
756 struct
757 {
758 short int id;
759 short int _pad0;
760 unsigned int type;
761 unsigned char name[1];
762 } friendfcn32;
763
764 struct
765 {
766 short int id;
767 short int type;
768 short int attribute;
769 unsigned short int offset; /* numeric leaf */
770#if 0
771 unsigned char name[1];
772#endif
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000773 } member;
774
775 struct
776 {
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000777 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000778 short int attribute;
779 unsigned int type;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000780 unsigned short int offset; /* numeric leaf */
781#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000782 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000783#endif
Ulrich Weigand8142a161999-12-10 03:43:53 +0000784 } member32;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000785
786 struct
787 {
788 short int id;
789 short int type;
790 short int attribute;
791 unsigned char name[1];
792 } stmember;
793
794 struct
795 {
796 short int id;
797 short int attribute;
798 unsigned int type;
799 unsigned char name[1];
800 } stmember32;
801
802 struct
803 {
804 short int id;
805 short int count;
806 short int mlist;
807 unsigned char name[1];
808 } method;
809
810 struct
811 {
812 short int id;
813 short int count;
814 unsigned int mlist;
815 unsigned char name[1];
816 } method32;
817
818 struct
819 {
820 short int id;
821 short int index;
822 unsigned char name[1];
823 } nesttype;
824
825 struct
826 {
827 short int id;
828 short int _pad0;
829 unsigned int index;
830 unsigned char name[1];
831 } nesttype32;
832
833 struct
834 {
835 short int id;
836 short int type;
837 } vfunctab;
838
839 struct
840 {
841 short int id;
842 short int _pad0;
843 unsigned int type;
844 } vfunctab32;
845
846 struct
847 {
848 short int id;
849 short int type;
850 } friendcls;
851
852 struct
853 {
854 short int id;
855 short int _pad0;
856 unsigned int type;
857 } friendcls32;
858
859
860 struct
861 {
862 short int id;
863 short int attribute;
864 short int type;
865 unsigned char name[1];
866 } onemethod;
867 struct
868 {
869 short int id;
870 short int attribute;
871 short int type;
872 unsigned int vtab_offset;
873 unsigned char name[1];
874 } onemethod_virt;
875
876 struct
877 {
878 short int id;
879 short int attribute;
880 unsigned int type;
881 unsigned char name[1];
882 } onemethod32;
883 struct
884 {
885 short int id;
886 short int attribute;
887 unsigned int type;
888 unsigned int vtab_offset;
889 unsigned char name[1];
890 } onemethod32_virt;
891
892 struct
893 {
894 short int id;
895 short int type;
896 unsigned int offset;
897 } vfuncoff;
898
899 struct
900 {
901 short int id;
902 short int _pad0;
903 unsigned int type;
904 unsigned int offset;
905 } vfuncoff32;
906
907 struct
908 {
909 short int id;
910 short int attribute;
911 short int index;
912 unsigned char name[1];
913 } nesttypeex;
914
915 struct
916 {
917 short int id;
918 short int attribute;
919 unsigned int index;
920 unsigned char name[1];
921 } nesttypeex32;
922
923 struct
924 {
925 short int id;
926 short int attribute;
927 unsigned int type;
928 unsigned char name[1];
929 } membermodify;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000930};
931
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000932
933/*
934 * This covers the basic datatypes that VC++ seems to be using these days.
935 * 32 bit mode only. There are additional numbers for the pointers in 16
936 * bit mode. There are many other types listed in the documents, but these
937 * are apparently not used by the compiler, or represent pointer types
938 * that are not used.
939 */
940#define T_NOTYPE 0x0000 /* Notype */
941#define T_ABS 0x0001 /* Abs */
942#define T_VOID 0x0003 /* Void */
943#define T_CHAR 0x0010 /* signed char */
944#define T_SHORT 0x0011 /* short */
945#define T_LONG 0x0012 /* long */
946#define T_QUAD 0x0013 /* long long */
947#define T_UCHAR 0x0020 /* unsigned char */
948#define T_USHORT 0x0021 /* unsigned short */
949#define T_ULONG 0x0022 /* unsigned long */
950#define T_UQUAD 0x0023 /* unsigned long long */
951#define T_REAL32 0x0040 /* float */
952#define T_REAL64 0x0041 /* double */
953#define T_RCHAR 0x0070 /* real char */
954#define T_WCHAR 0x0071 /* wide char */
955#define T_INT4 0x0074 /* int */
956#define T_UINT4 0x0075 /* unsigned int */
957
958#define T_32PVOID 0x0403 /* 32 bit near pointer to void */
959#define T_32PCHAR 0x0410 /* 16:32 near pointer to signed char */
960#define T_32PSHORT 0x0411 /* 16:32 near pointer to short */
961#define T_32PLONG 0x0412 /* 16:32 near pointer to int */
962#define T_32PQUAD 0x0413 /* 16:32 near pointer to long long */
963#define T_32PUCHAR 0x0420 /* 16:32 near pointer to unsigned char */
964#define T_32PUSHORT 0x0421 /* 16:32 near pointer to unsigned short */
965#define T_32PULONG 0x0422 /* 16:32 near pointer to unsigned int */
966#define T_32PUQUAD 0x0423 /* 16:32 near pointer to long long */
967#define T_32PREAL32 0x0440 /* 16:32 near pointer to float */
968#define T_32PREAL64 0x0441 /* 16:32 near pointer to float */
969#define T_32PRCHAR 0x0470 /* 16:32 near pointer to real char */
970#define T_32PWCHAR 0x0471 /* 16:32 near pointer to real char */
971#define T_32PINT4 0x0474 /* 16:32 near pointer to int */
972#define T_32PUINT4 0x0475 /* 16:32 near pointer to unsigned int */
973
Ulrich Weigand6011e982000-11-07 20:29:20 +0000974
Ulrich Weigand8142a161999-12-10 03:43:53 +0000975#define LF_MODIFIER 0x0001
976#define LF_POINTER 0x0002
977#define LF_ARRAY 0x0003
978#define LF_CLASS 0x0004
979#define LF_STRUCTURE 0x0005
980#define LF_UNION 0x0006
981#define LF_ENUM 0x0007
982#define LF_PROCEDURE 0x0008
983#define LF_MFUNCTION 0x0009
984#define LF_VTSHAPE 0x000a
985#define LF_COBOL0 0x000b
986#define LF_COBOL1 0x000c
987#define LF_BARRAY 0x000d
988#define LF_LABEL 0x000e
989#define LF_NULL 0x000f
990#define LF_NOTTRAN 0x0010
991#define LF_DIMARRAY 0x0011
992#define LF_VFTPATH 0x0012
993#define LF_PRECOMP 0x0013
994#define LF_ENDPRECOMP 0x0014
995#define LF_OEM 0x0015
996#define LF_TYPESERVER 0x0016
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000997
Ulrich Weigand8142a161999-12-10 03:43:53 +0000998#define LF_MODIFIER_32 0x1001 /* variants with new 32-bit type indices */
999#define LF_POINTER_32 0x1002
1000#define LF_ARRAY_32 0x1003
1001#define LF_CLASS_32 0x1004
1002#define LF_STRUCTURE_32 0x1005
1003#define LF_UNION_32 0x1006
1004#define LF_ENUM_32 0x1007
1005#define LF_PROCEDURE_32 0x1008
1006#define LF_MFUNCTION_32 0x1009
1007#define LF_COBOL0_32 0x100a
1008#define LF_BARRAY_32 0x100b
1009#define LF_DIMARRAY_32 0x100c
1010#define LF_VFTPATH_32 0x100d
1011#define LF_PRECOMP_32 0x100e
1012#define LF_OEM_32 0x100f
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001013
Ulrich Weigand8142a161999-12-10 03:43:53 +00001014#define LF_SKIP 0x0200
1015#define LF_ARGLIST 0x0201
1016#define LF_DEFARG 0x0202
1017#define LF_LIST 0x0203
1018#define LF_FIELDLIST 0x0204
1019#define LF_DERIVED 0x0205
1020#define LF_BITFIELD 0x0206
1021#define LF_METHODLIST 0x0207
1022#define LF_DIMCONU 0x0208
1023#define LF_DIMCONLU 0x0209
1024#define LF_DIMVARU 0x020a
1025#define LF_DIMVARLU 0x020b
1026#define LF_REFSYM 0x020c
1027
1028#define LF_SKIP_32 0x1200 /* variants with new 32-bit type indices */
1029#define LF_ARGLIST_32 0x1201
1030#define LF_DEFARG_32 0x1202
1031#define LF_FIELDLIST_32 0x1203
1032#define LF_DERIVED_32 0x1204
1033#define LF_BITFIELD_32 0x1205
1034#define LF_METHODLIST_32 0x1206
1035#define LF_DIMCONU_32 0x1207
1036#define LF_DIMCONLU_32 0x1208
1037#define LF_DIMVARU_32 0x1209
1038#define LF_DIMVARLU_32 0x120a
1039
1040#define LF_BCLASS 0x0400
1041#define LF_VBCLASS 0x0401
1042#define LF_IVBCLASS 0x0402
1043#define LF_ENUMERATE 0x0403
1044#define LF_FRIENDFCN 0x0404
1045#define LF_INDEX 0x0405
1046#define LF_MEMBER 0x0406
1047#define LF_STMEMBER 0x0407
1048#define LF_METHOD 0x0408
1049#define LF_NESTTYPE 0x0409
1050#define LF_VFUNCTAB 0x040a
1051#define LF_FRIENDCLS 0x040b
1052#define LF_ONEMETHOD 0x040c
1053#define LF_VFUNCOFF 0x040d
1054#define LF_NESTTYPEEX 0x040e
1055#define LF_MEMBERMODIFY 0x040f
1056
1057#define LF_BCLASS_32 0x1400 /* variants with new 32-bit type indices */
1058#define LF_VBCLASS_32 0x1401
1059#define LF_IVBCLASS_32 0x1402
1060#define LF_FRIENDFCN_32 0x1403
1061#define LF_INDEX_32 0x1404
1062#define LF_MEMBER_32 0x1405
1063#define LF_STMEMBER_32 0x1406
1064#define LF_METHOD_32 0x1407
1065#define LF_NESTTYPE_32 0x1408
1066#define LF_VFUNCTAB_32 0x1409
1067#define LF_FRIENDCLS_32 0x140a
1068#define LF_ONEMETHOD_32 0x140b
1069#define LF_VFUNCOFF_32 0x140c
1070#define LF_NESTTYPEEX_32 0x140d
1071
Ulrich Weigand164bac92000-04-25 19:53:49 +00001072#define LF_NUMERIC 0x8000 /* numeric leaf types */
1073#define LF_CHAR 0x8000
1074#define LF_SHORT 0x8001
1075#define LF_USHORT 0x8002
1076#define LF_LONG 0x8003
1077#define LF_ULONG 0x8004
1078#define LF_REAL32 0x8005
1079#define LF_REAL64 0x8006
1080#define LF_REAL80 0x8007
1081#define LF_REAL128 0x8008
1082#define LF_QUADWORD 0x8009
1083#define LF_UQUADWORD 0x800a
1084#define LF_REAL48 0x800b
1085#define LF_COMPLEX32 0x800c
1086#define LF_COMPLEX64 0x800d
1087#define LF_COMPLEX80 0x800e
1088#define LF_COMPLEX128 0x800f
1089#define LF_VARSTRING 0x8010
Ulrich Weigand8142a161999-12-10 03:43:53 +00001090
1091
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001092
1093#define MAX_BUILTIN_TYPES 0x480
1094static struct datatype * cv_basic_types[MAX_BUILTIN_TYPES];
Joerg Mayerd18140c2000-12-26 01:28:51 +00001095static unsigned int num_cv_defined_types = 0;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001096static struct datatype **cv_defined_types = NULL;
1097
Ulrich Weigand6011e982000-11-07 20:29:20 +00001098void
1099DEBUG_InitCVDataTypes(void)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001100{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001101 /*
1102 * These are the common builtin types that are used by VC++.
1103 */
1104 cv_basic_types[T_NOTYPE] = NULL;
1105 cv_basic_types[T_ABS] = NULL;
1106 cv_basic_types[T_VOID] = DEBUG_NewDataType(DT_BASIC, "void");
1107 cv_basic_types[T_CHAR] = DEBUG_NewDataType(DT_BASIC, "char");
1108 cv_basic_types[T_SHORT] = DEBUG_NewDataType(DT_BASIC, "short int");
1109 cv_basic_types[T_LONG] = DEBUG_NewDataType(DT_BASIC, "long int");
1110 cv_basic_types[T_QUAD] = DEBUG_NewDataType(DT_BASIC, "long long int");
1111 cv_basic_types[T_UCHAR] = DEBUG_NewDataType(DT_BASIC, "unsigned char");
1112 cv_basic_types[T_USHORT] = DEBUG_NewDataType(DT_BASIC, "short unsigned int");
1113 cv_basic_types[T_ULONG] = DEBUG_NewDataType(DT_BASIC, "long unsigned int");
1114 cv_basic_types[T_UQUAD] = DEBUG_NewDataType(DT_BASIC, "long long unsigned int");
1115 cv_basic_types[T_REAL32] = DEBUG_NewDataType(DT_BASIC, "float");
1116 cv_basic_types[T_REAL64] = DEBUG_NewDataType(DT_BASIC, "double");
1117 cv_basic_types[T_RCHAR] = DEBUG_NewDataType(DT_BASIC, "char");
1118 cv_basic_types[T_WCHAR] = DEBUG_NewDataType(DT_BASIC, "short");
1119 cv_basic_types[T_INT4] = DEBUG_NewDataType(DT_BASIC, "int");
1120 cv_basic_types[T_UINT4] = DEBUG_NewDataType(DT_BASIC, "unsigned int");
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001121
Ulrich Weigand6011e982000-11-07 20:29:20 +00001122 cv_basic_types[T_32PVOID] = DEBUG_FindOrMakePointerType(cv_basic_types[T_VOID]);
1123 cv_basic_types[T_32PCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_CHAR]);
1124 cv_basic_types[T_32PSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_SHORT]);
1125 cv_basic_types[T_32PLONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_LONG]);
1126 cv_basic_types[T_32PQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_QUAD]);
1127 cv_basic_types[T_32PUCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UCHAR]);
1128 cv_basic_types[T_32PUSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_USHORT]);
1129 cv_basic_types[T_32PULONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_ULONG]);
1130 cv_basic_types[T_32PUQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UQUAD]);
1131 cv_basic_types[T_32PREAL32] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL32]);
1132 cv_basic_types[T_32PREAL64] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL64]);
1133 cv_basic_types[T_32PRCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_RCHAR]);
1134 cv_basic_types[T_32PWCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_WCHAR]);
1135 cv_basic_types[T_32PINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_INT4]);
1136 cv_basic_types[T_32PUINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UINT4]);
1137}
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001138
Ulrich Weigand164bac92000-04-25 19:53:49 +00001139
1140static int
1141numeric_leaf( int *value, unsigned short int *leaf )
1142{
1143 unsigned short int type = *leaf++;
1144 int length = 2;
1145
1146 if ( type < LF_NUMERIC )
1147 {
1148 *value = type;
1149 }
1150 else
1151 {
1152 switch ( type )
1153 {
1154 case LF_CHAR:
1155 length += 1;
1156 *value = *(char *)leaf;
1157 break;
1158
1159 case LF_SHORT:
1160 length += 2;
1161 *value = *(short *)leaf;
1162 break;
1163
1164 case LF_USHORT:
1165 length += 2;
1166 *value = *(unsigned short *)leaf;
1167 break;
1168
1169 case LF_LONG:
1170 length += 4;
1171 *value = *(int *)leaf;
1172 break;
1173
1174 case LF_ULONG:
1175 length += 4;
1176 *value = *(unsigned int *)leaf;
1177 break;
1178
1179 case LF_QUADWORD:
1180 case LF_UQUADWORD:
1181 length += 8;
1182 *value = 0; /* FIXME */
1183 break;
1184
1185 case LF_REAL32:
1186 length += 4;
1187 *value = 0; /* FIXME */
1188 break;
1189
1190 case LF_REAL48:
1191 length += 6;
1192 *value = 0; /* FIXME */
1193 break;
1194
1195 case LF_REAL64:
1196 length += 8;
1197 *value = 0; /* FIXME */
1198 break;
1199
1200 case LF_REAL80:
1201 length += 10;
1202 *value = 0; /* FIXME */
1203 break;
1204
1205 case LF_REAL128:
1206 length += 16;
1207 *value = 0; /* FIXME */
1208 break;
1209
1210 case LF_COMPLEX32:
1211 length += 4;
1212 *value = 0; /* FIXME */
1213 break;
1214
1215 case LF_COMPLEX64:
1216 length += 8;
1217 *value = 0; /* FIXME */
1218 break;
1219
1220 case LF_COMPLEX80:
1221 length += 10;
1222 *value = 0; /* FIXME */
1223 break;
1224
1225 case LF_COMPLEX128:
1226 length += 16;
1227 *value = 0; /* FIXME */
1228 break;
1229
1230 case LF_VARSTRING:
1231 length += 2 + *leaf;
1232 *value = 0; /* FIXME */
1233 break;
1234
1235 default:
1236 DEBUG_Printf( DBG_CHN_MESG, "Unknown numeric leaf type %04x\n", type );
1237 *value = 0;
1238 break;
1239 }
1240 }
1241
1242 return length;
1243}
1244
1245static char *
1246terminate_string( unsigned char *name )
1247{
1248 static char symname[256];
1249
1250 int namelen = name[0];
1251 assert( namelen >= 0 && namelen < 256 );
1252
1253 memcpy( symname, name+1, namelen );
1254 symname[namelen] = '\0';
1255
1256 if ( !*symname || strcmp( symname, "__unnamed" ) == 0 )
1257 return NULL;
1258 else
1259 return symname;
1260}
1261
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001262static
Ulrich Weigand8142a161999-12-10 03:43:53 +00001263struct datatype * DEBUG_GetCVType(unsigned int typeno)
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001264{
Ulrich Weigand164bac92000-04-25 19:53:49 +00001265 struct datatype * dt = NULL;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001266
Ulrich Weigand164bac92000-04-25 19:53:49 +00001267 /*
1268 * Convert Codeview type numbers into something we can grok internally.
1269 * Numbers < 0x1000 are all fixed builtin types. Numbers from 0x1000 and
1270 * up are all user defined (structs, etc).
1271 */
1272 if ( typeno < 0x1000 )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001273 {
Ulrich Weigand164bac92000-04-25 19:53:49 +00001274 if ( typeno < MAX_BUILTIN_TYPES )
1275 dt = cv_basic_types[typeno];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001276 }
Ulrich Weigand164bac92000-04-25 19:53:49 +00001277 else
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001278 {
Ulrich Weigand164bac92000-04-25 19:53:49 +00001279 if ( typeno - 0x1000 < num_cv_defined_types )
1280 dt = cv_defined_types[typeno - 0x1000];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001281 }
1282
Ulrich Weigand164bac92000-04-25 19:53:49 +00001283 return dt;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001284}
1285
1286static int
Ulrich Weigand164bac92000-04-25 19:53:49 +00001287DEBUG_AddCVType( unsigned int typeno, struct datatype *dt )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001288{
Ulrich Weigand164bac92000-04-25 19:53:49 +00001289 while ( typeno - 0x1000 >= num_cv_defined_types )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001290 {
Ulrich Weigand164bac92000-04-25 19:53:49 +00001291 num_cv_defined_types += 0x100;
1292 cv_defined_types = (struct datatype **)
1293 DBG_realloc( cv_defined_types,
1294 num_cv_defined_types * sizeof(struct datatype *) );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001295
Ulrich Weigand164bac92000-04-25 19:53:49 +00001296 memset( cv_defined_types + num_cv_defined_types - 0x100,
1297 0,
1298 0x100 * sizeof(struct datatype *) );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001299
Ulrich Weigand164bac92000-04-25 19:53:49 +00001300 if ( cv_defined_types == NULL )
1301 return FALSE;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001302 }
1303
Ulrich Weigand164bac92000-04-25 19:53:49 +00001304 cv_defined_types[ typeno - 0x1000 ] = dt;
1305 return TRUE;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001306}
1307
Ulrich Weigand164bac92000-04-25 19:53:49 +00001308static void
1309DEBUG_ClearTypeTable( void )
1310{
1311 if ( cv_defined_types )
1312 DBG_free( cv_defined_types );
1313
1314 cv_defined_types = NULL;
1315 num_cv_defined_types = 0;
1316}
1317
1318static int
1319DEBUG_AddCVType_Pointer( unsigned int typeno, unsigned int datatype )
1320{
1321 struct datatype *dt =
1322 DEBUG_FindOrMakePointerType( DEBUG_GetCVType( datatype ) );
1323
1324 return DEBUG_AddCVType( typeno, dt );
1325}
1326
1327static int
1328DEBUG_AddCVType_Array( unsigned int typeno, char *name,
1329 unsigned int elemtype, unsigned int arr_len )
1330{
1331 struct datatype *dt = DEBUG_NewDataType( DT_ARRAY, name );
1332 struct datatype *elem = DEBUG_GetCVType( elemtype );
1333 unsigned int elem_size = elem? DEBUG_GetObjectSize( elem ) : 0;
1334 unsigned int arr_max = elem_size? arr_len / elem_size : 0;
1335
1336 DEBUG_SetArrayParams( dt, 0, arr_max, elem );
1337 return DEBUG_AddCVType( typeno, dt );
1338}
1339
1340static int
1341DEBUG_AddCVType_Bitfield( unsigned int typeno,
1342 unsigned int bitoff, unsigned int nbits,
1343 unsigned int basetype )
1344{
1345 struct datatype *dt = DEBUG_NewDataType( DT_BITFIELD, NULL );
1346 struct datatype *base = DEBUG_GetCVType( basetype );
1347
1348 DEBUG_SetBitfieldParams( dt, bitoff, nbits, base );
1349 return DEBUG_AddCVType( typeno, dt );
1350}
1351
1352static int
1353DEBUG_AddCVType_EnumFieldList( unsigned int typeno, unsigned char *list, int len )
1354{
1355 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, NULL );
1356 unsigned char *ptr = list;
1357
1358 while ( ptr - list < len )
1359 {
1360 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1361
1362 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1363 {
1364 ptr += *ptr & 0x0f;
1365 continue;
1366 }
1367
1368 switch ( type->generic.id )
1369 {
1370 case LF_ENUMERATE:
1371 {
1372 int value, vlen = numeric_leaf( &value, &type->enumerate.value );
1373 unsigned char *name = (unsigned char *)&type->enumerate.value + vlen;
1374
1375 DEBUG_AddStructElement( dt, terminate_string( name ),
1376 NULL, value, 0 );
1377
1378 ptr += 2 + 2 + vlen + (1 + name[0]);
1379 break;
1380 }
1381
1382 default:
1383 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in ENUM field list\n",
1384 type->generic.id );
1385 return FALSE;
1386 }
1387 }
1388
1389 return DEBUG_AddCVType( typeno, dt );
1390}
1391
1392static int
1393DEBUG_AddCVType_StructFieldList( unsigned int typeno, unsigned char *list, int len )
1394{
1395 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, NULL );
1396 unsigned char *ptr = list;
1397
1398 while ( ptr - list < len )
1399 {
1400 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1401
1402 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1403 {
1404 ptr += *ptr & 0x0f;
1405 continue;
1406 }
1407
1408 switch ( type->generic.id )
1409 {
1410 case LF_BCLASS:
1411 {
1412 int offset, olen = numeric_leaf( &offset, &type->bclass.offset );
1413
1414 /* FIXME: ignored for now */
1415
1416 ptr += 2 + 2 + 2 + olen;
1417 break;
1418 }
1419
1420 case LF_BCLASS_32:
1421 {
1422 int offset, olen = numeric_leaf( &offset, &type->bclass32.offset );
1423
1424 /* FIXME: ignored for now */
1425
1426 ptr += 2 + 2 + 4 + olen;
1427 break;
1428 }
1429
1430 case LF_VBCLASS:
1431 case LF_IVBCLASS:
1432 {
1433 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass.vbpoff );
1434 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass.vbpoff + vbpoff);
1435 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1436
1437 /* FIXME: ignored for now */
1438
1439 ptr += 2 + 2 + 2 + 2 + vbplen + vplen;
1440 break;
1441 }
1442
1443 case LF_VBCLASS_32:
1444 case LF_IVBCLASS_32:
1445 {
1446 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass32.vbpoff );
1447 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass32.vbpoff + vbpoff);
1448 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1449
1450 /* FIXME: ignored for now */
1451
1452 ptr += 2 + 2 + 4 + 4 + vbplen + vplen;
1453 break;
1454 }
1455
1456 case LF_MEMBER:
1457 {
1458 int offset, olen = numeric_leaf( &offset, &type->member.offset );
1459 unsigned char *name = (unsigned char *)&type->member.offset + olen;
1460
1461 struct datatype *subtype = DEBUG_GetCVType( type->member.type );
1462 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1463
1464 DEBUG_AddStructElement( dt, terminate_string( name ),
1465 subtype, offset << 3, elem_size << 3 );
1466
1467 ptr += 2 + 2 + 2 + olen + (1 + name[0]);
1468 break;
1469 }
1470
1471 case LF_MEMBER_32:
1472 {
1473 int offset, olen = numeric_leaf( &offset, &type->member32.offset );
1474 unsigned char *name = (unsigned char *)&type->member32.offset + olen;
1475
1476 struct datatype *subtype = DEBUG_GetCVType( type->member32.type );
1477 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1478
1479 DEBUG_AddStructElement( dt, terminate_string( name ),
1480 subtype, offset << 3, elem_size << 3 );
1481
1482 ptr += 2 + 2 + 4 + olen + (1 + name[0]);
1483 break;
1484 }
1485
1486 case LF_STMEMBER:
1487 /* FIXME: ignored for now */
1488 ptr += 2 + 2 + 2 + (1 + type->stmember.name[0]);
1489 break;
1490
1491 case LF_STMEMBER_32:
1492 /* FIXME: ignored for now */
1493 ptr += 2 + 4 + 2 + (1 + type->stmember32.name[0]);
1494 break;
1495
1496 case LF_METHOD:
1497 /* FIXME: ignored for now */
1498 ptr += 2 + 2 + 2 + (1 + type->method.name[0]);
1499 break;
1500
1501 case LF_METHOD_32:
1502 /* FIXME: ignored for now */
1503 ptr += 2 + 2 + 4 + (1 + type->method32.name[0]);
1504 break;
1505
1506 case LF_NESTTYPE:
1507 /* FIXME: ignored for now */
1508 ptr += 2 + 2 + (1 + type->nesttype.name[0]);
1509 break;
1510
1511 case LF_NESTTYPE_32:
1512 /* FIXME: ignored for now */
1513 ptr += 2 + 2 + 4 + (1 + type->nesttype32.name[0]);
1514 break;
1515
1516 case LF_VFUNCTAB:
1517 /* FIXME: ignored for now */
1518 ptr += 2 + 2;
1519 break;
1520
1521 case LF_VFUNCTAB_32:
1522 /* FIXME: ignored for now */
1523 ptr += 2 + 2 + 4;
1524 break;
1525
1526 case LF_ONEMETHOD:
1527 /* FIXME: ignored for now */
1528 switch ( (type->onemethod.attribute >> 2) & 7 )
1529 {
1530 case 4: case 6: /* (pure) introducing virtual method */
1531 ptr += 2 + 2 + 2 + 4 + (1 + type->onemethod_virt.name[0]);
1532 break;
1533
1534 default:
1535 ptr += 2 + 2 + 2 + (1 + type->onemethod.name[0]);
1536 break;
1537 }
1538 break;
1539
1540 case LF_ONEMETHOD_32:
1541 /* FIXME: ignored for now */
1542 switch ( (type->onemethod32.attribute >> 2) & 7 )
1543 {
1544 case 4: case 6: /* (pure) introducing virtual method */
1545 ptr += 2 + 2 + 4 + 4 + (1 + type->onemethod32_virt.name[0]);
1546 break;
1547
1548 default:
1549 ptr += 2 + 2 + 4 + (1 + type->onemethod32.name[0]);
1550 break;
1551 }
1552 break;
1553
1554 default:
1555 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in STRUCT field list\n",
1556 type->generic.id );
1557 return FALSE;
1558 }
1559 }
1560
1561 return DEBUG_AddCVType( typeno, dt );
1562}
1563
1564static int
1565DEBUG_AddCVType_Enum( unsigned int typeno, char *name, unsigned int fieldlist )
1566{
1567 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, name );
1568 struct datatype *list = DEBUG_GetCVType( fieldlist );
1569
1570 if ( list )
1571 DEBUG_CopyFieldlist( dt, list );
1572
1573 return DEBUG_AddCVType( typeno, dt );
1574}
1575
1576static int
1577DEBUG_AddCVType_Struct( unsigned int typeno, char *name, int structlen, unsigned int fieldlist )
1578{
1579 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, name );
1580 struct datatype *list = DEBUG_GetCVType( fieldlist );
1581
1582 if ( list )
1583 {
1584 DEBUG_SetStructSize( dt, structlen );
1585 DEBUG_CopyFieldlist( dt, list );
1586 }
1587
1588 return DEBUG_AddCVType( typeno, dt );
1589}
1590
1591static int
1592DEBUG_ParseTypeTable( char *table, int len )
1593{
1594 unsigned int curr_type = 0x1000;
1595 char *ptr = table;
1596
1597 while ( ptr - table < len )
1598 {
1599 union codeview_type *type = (union codeview_type *) ptr;
1600 int retv = TRUE;
1601
1602 switch ( type->generic.id )
1603 {
1604 case LF_POINTER:
1605 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer.datatype );
1606 break;
1607 case LF_POINTER_32:
1608 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer32.datatype );
1609 break;
1610
1611 case LF_ARRAY:
1612 {
1613 int arrlen, alen = numeric_leaf( &arrlen, &type->array.arrlen );
1614 unsigned char *name = (unsigned char *)&type->array.arrlen + alen;
1615
1616 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1617 type->array.elemtype, arrlen );
1618 break;
1619 }
1620 case LF_ARRAY_32:
1621 {
1622 int arrlen, alen = numeric_leaf( &arrlen, &type->array32.arrlen );
1623 unsigned char *name = (unsigned char *)&type->array32.arrlen + alen;
1624
1625 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1626 type->array32.elemtype, type->array32.arrlen );
1627 break;
1628 }
1629
1630 case LF_BITFIELD:
1631 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield.bitoff,
1632 type->bitfield.nbits,
1633 type->bitfield.type );
1634 break;
1635 case LF_BITFIELD_32:
1636 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield32.bitoff,
1637 type->bitfield32.nbits,
1638 type->bitfield32.type );
1639 break;
1640
1641 case LF_FIELDLIST:
1642 case LF_FIELDLIST_32:
1643 {
1644 /*
1645 * A 'field list' is a CodeView-specific data type which doesn't
1646 * directly correspond to any high-level data type. It is used
1647 * to hold the collection of members of a struct, class, union
1648 * or enum type. The actual definition of that type will follow
1649 * later, and refer to the field list definition record.
1650 *
1651 * As we don't have a field list type ourselves, we look ahead
1652 * in the field list to try to find out whether this field list
1653 * will be used for an enum or struct type, and create a dummy
1654 * type of the corresponding sort. Later on, the definition of
1655 * the 'real' type will copy the member / enumeration data.
1656 */
1657
1658 char *list = type->fieldlist.list;
1659 int len = (ptr + type->generic.len + 2) - list;
1660
1661 if ( ((union codeview_fieldtype *)list)->generic.id == LF_ENUMERATE )
1662 retv = DEBUG_AddCVType_EnumFieldList( curr_type, list, len );
1663 else
1664 retv = DEBUG_AddCVType_StructFieldList( curr_type, list, len );
1665 break;
1666 }
1667
1668 case LF_STRUCTURE:
1669 case LF_CLASS:
1670 {
1671 int structlen, slen = numeric_leaf( &structlen, &type->structure.structlen );
1672 unsigned char *name = (unsigned char *)&type->structure.structlen + slen;
1673
1674 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1675 structlen, type->structure.fieldlist );
1676 break;
1677 }
1678 case LF_STRUCTURE_32:
1679 case LF_CLASS_32:
1680 {
1681 int structlen, slen = numeric_leaf( &structlen, &type->structure32.structlen );
1682 unsigned char *name = (unsigned char *)&type->structure32.structlen + slen;
1683
1684 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1685 structlen, type->structure32.fieldlist );
1686 break;
1687 }
1688
1689 case LF_UNION:
1690 {
1691 int un_len, ulen = numeric_leaf( &un_len, &type->t_union.un_len );
1692 unsigned char *name = (unsigned char *)&type->t_union.un_len + ulen;
1693
1694 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1695 un_len, type->t_union.fieldlist );
1696 break;
1697 }
1698 case LF_UNION_32:
1699 {
1700 int un_len, ulen = numeric_leaf( &un_len, &type->t_union32.un_len );
1701 unsigned char *name = (unsigned char *)&type->t_union32.un_len + ulen;
1702
1703 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1704 un_len, type->t_union32.fieldlist );
1705 break;
1706 }
1707
1708 case LF_ENUM:
1709 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration.name ),
1710 type->enumeration.field );
1711 break;
1712 case LF_ENUM_32:
1713 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration32.name ),
1714 type->enumeration32.field );
1715 break;
1716
1717 default:
1718 break;
1719 }
1720
1721 if ( !retv )
1722 return FALSE;
1723
1724 curr_type++;
1725 ptr += type->generic.len + 2;
1726 }
1727
1728 return TRUE;
1729}
1730
1731
Ulrich Weigand6011e982000-11-07 20:29:20 +00001732/*========================================================================
1733 * Process CodeView line number information.
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001734 */
Ulrich Weigand6011e982000-11-07 20:29:20 +00001735
1736union any_size
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001737{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001738 char * c;
1739 short * s;
1740 int * i;
1741 unsigned int * ui;
1742};
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001743
Ulrich Weigand6011e982000-11-07 20:29:20 +00001744struct startend
Eric Pouechac11a682000-03-26 13:37:39 +00001745{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001746 unsigned int start;
1747 unsigned int end;
1748};
Eric Pouechac11a682000-03-26 13:37:39 +00001749
Ulrich Weigand6011e982000-11-07 20:29:20 +00001750struct codeview_linetab_hdr
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001751{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001752 unsigned int nline;
1753 unsigned int segno;
1754 unsigned int start;
1755 unsigned int end;
1756 char * sourcefile;
1757 unsigned short * linetab;
1758 unsigned int * offtab;
1759};
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001760
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001761static struct codeview_linetab_hdr *
Ulrich Weigand6011e982000-11-07 20:29:20 +00001762DEBUG_SnarfLinetab(char * linetab,
1763 int size)
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001764{
1765 int file_segcount;
1766 char filename[PATH_MAX];
1767 unsigned int * filetab;
1768 char * fn;
1769 int i;
1770 int k;
1771 struct codeview_linetab_hdr * lt_hdr;
1772 unsigned int * lt_ptr;
1773 int nfile;
1774 int nseg;
1775 union any_size pnt;
1776 union any_size pnt2;
1777 struct startend * start;
1778 int this_seg;
1779
1780 /*
1781 * Now get the important bits.
1782 */
Patrik Stridvall896889f1999-05-08 12:50:36 +00001783 pnt.c = linetab;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001784 nfile = *pnt.s++;
1785 nseg = *pnt.s++;
1786
1787 filetab = (unsigned int *) pnt.c;
1788
1789 /*
1790 * Now count up the number of segments in the file.
1791 */
1792 nseg = 0;
1793 for(i=0; i<nfile; i++)
1794 {
Patrik Stridvall896889f1999-05-08 12:50:36 +00001795 pnt2.c = linetab + filetab[i];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001796 nseg += *pnt2.s;
1797 }
1798
1799 /*
1800 * Next allocate the header we will be returning.
1801 * There is one header for each segment, so that we can reach in
1802 * and pull bits as required.
1803 */
1804 lt_hdr = (struct codeview_linetab_hdr *)
Ove Kaavendda17c61999-04-25 12:24:42 +00001805 DBG_alloc((nseg + 1) * sizeof(*lt_hdr));
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001806 if( lt_hdr == NULL )
1807 {
1808 goto leave;
1809 }
1810
1811 memset(lt_hdr, 0, sizeof(*lt_hdr) * (nseg+1));
1812
1813 /*
1814 * Now fill the header we will be returning, one for each segment.
1815 * Note that this will basically just contain pointers into the existing
1816 * line table, and we do not actually copy any additional information
1817 * or allocate any additional memory.
1818 */
1819
1820 this_seg = 0;
1821 for(i=0; i<nfile; i++)
1822 {
1823 /*
1824 * Get the pointer into the segment information.
1825 */
Patrik Stridvall896889f1999-05-08 12:50:36 +00001826 pnt2.c = linetab + filetab[i];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001827 file_segcount = *pnt2.s;
1828
1829 pnt2.ui++;
1830 lt_ptr = (unsigned int *) pnt2.c;
1831 start = (struct startend *) (lt_ptr + file_segcount);
1832
1833 /*
1834 * Now snarf the filename for all of the segments for this file.
1835 */
1836 fn = (unsigned char *) (start + file_segcount);
1837 memset(filename, 0, sizeof(filename));
1838 memcpy(filename, fn + 1, *fn);
Ove Kaavendda17c61999-04-25 12:24:42 +00001839 fn = DBG_strdup(filename);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001840
1841 for(k = 0; k < file_segcount; k++, this_seg++)
1842 {
Patrik Stridvall896889f1999-05-08 12:50:36 +00001843 pnt2.c = linetab + lt_ptr[k];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001844 lt_hdr[this_seg].start = start[k].start;
1845 lt_hdr[this_seg].end = start[k].end;
1846 lt_hdr[this_seg].sourcefile = fn;
1847 lt_hdr[this_seg].segno = *pnt2.s++;
1848 lt_hdr[this_seg].nline = *pnt2.s++;
1849 lt_hdr[this_seg].offtab = pnt2.ui;
1850 lt_hdr[this_seg].linetab = (unsigned short *)
1851 (pnt2.ui + lt_hdr[this_seg].nline);
1852 }
1853 }
1854
1855leave:
1856
1857 return lt_hdr;
1858
1859}
1860
Ulrich Weigand6011e982000-11-07 20:29:20 +00001861
1862/*========================================================================
1863 * Process CodeView symbol information.
1864 */
1865
1866union codeview_symbol
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001867{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001868 struct
1869 {
1870 short int len;
1871 short int id;
1872 } generic;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001873
Ulrich Weigand6011e982000-11-07 20:29:20 +00001874 struct
1875 {
1876 short int len;
1877 short int id;
1878 unsigned int offset;
1879 unsigned short seg;
1880 unsigned short symtype;
1881 unsigned char namelen;
1882 unsigned char name[1];
1883 } data;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001884
Ulrich Weigand6011e982000-11-07 20:29:20 +00001885 struct
1886 {
1887 short int len;
1888 short int id;
1889 unsigned int symtype;
1890 unsigned int offset;
1891 unsigned short seg;
1892 unsigned char namelen;
1893 unsigned char name[1];
1894 } data32;
1895
1896 struct
1897 {
1898 short int len;
1899 short int id;
1900 unsigned int pparent;
1901 unsigned int pend;
1902 unsigned int next;
1903 unsigned int offset;
1904 unsigned short segment;
1905 unsigned short thunk_len;
1906 unsigned char thtype;
1907 unsigned char namelen;
1908 unsigned char name[1];
1909 } thunk;
1910
1911 struct
1912 {
1913 short int len;
1914 short int id;
1915 unsigned int pparent;
1916 unsigned int pend;
1917 unsigned int next;
1918 unsigned int proc_len;
1919 unsigned int debug_start;
1920 unsigned int debug_end;
1921 unsigned int offset;
1922 unsigned short segment;
1923 unsigned short proctype;
1924 unsigned char flags;
1925 unsigned char namelen;
1926 unsigned char name[1];
1927 } proc;
1928
1929 struct
1930 {
1931 short int len;
1932 short int id;
1933 unsigned int pparent;
1934 unsigned int pend;
1935 unsigned int next;
1936 unsigned int proc_len;
1937 unsigned int debug_start;
1938 unsigned int debug_end;
1939 unsigned int proctype;
1940 unsigned int offset;
1941 unsigned short segment;
1942 unsigned char flags;
1943 unsigned char namelen;
1944 unsigned char name[1];
1945 } proc32;
1946
1947 struct
1948 {
1949 short int len; /* Total length of this entry */
1950 short int id; /* Always S_BPREL32 */
1951 unsigned int offset; /* Stack offset relative to BP */
1952 unsigned short symtype;
1953 unsigned char namelen;
1954 unsigned char name[1];
1955 } stack;
1956
1957 struct
1958 {
1959 short int len; /* Total length of this entry */
1960 short int id; /* Always S_BPREL32 */
1961 unsigned int offset; /* Stack offset relative to BP */
1962 unsigned int symtype;
1963 unsigned char namelen;
1964 unsigned char name[1];
1965 } stack32;
1966
1967};
1968
1969#define S_COMPILE 0x0001
1970#define S_REGISTER 0x0002
1971#define S_CONSTANT 0x0003
1972#define S_UDT 0x0004
1973#define S_SSEARCH 0x0005
1974#define S_END 0x0006
1975#define S_SKIP 0x0007
1976#define S_CVRESERVE 0x0008
1977#define S_OBJNAME 0x0009
1978#define S_ENDARG 0x000a
1979#define S_COBOLUDT 0x000b
1980#define S_MANYREG 0x000c
1981#define S_RETURN 0x000d
1982#define S_ENTRYTHIS 0x000e
1983
1984#define S_BPREL 0x0200
1985#define S_LDATA 0x0201
1986#define S_GDATA 0x0202
1987#define S_PUB 0x0203
1988#define S_LPROC 0x0204
1989#define S_GPROC 0x0205
1990#define S_THUNK 0x0206
1991#define S_BLOCK 0x0207
1992#define S_WITH 0x0208
1993#define S_LABEL 0x0209
1994#define S_CEXMODEL 0x020a
1995#define S_VFTPATH 0x020b
1996#define S_REGREL 0x020c
1997#define S_LTHREAD 0x020d
1998#define S_GTHREAD 0x020e
1999
2000#define S_PROCREF 0x0400
2001#define S_DATAREF 0x0401
2002#define S_ALIGN 0x0402
2003#define S_LPROCREF 0x0403
2004
2005#define S_REGISTER_32 0x1001 /* Variants with new 32-bit type indices */
2006#define S_CONSTANT_32 0x1002
2007#define S_UDT_32 0x1003
2008#define S_COBOLUDT_32 0x1004
2009#define S_MANYREG_32 0x1005
2010
2011#define S_BPREL_32 0x1006
2012#define S_LDATA_32 0x1007
2013#define S_GDATA_32 0x1008
2014#define S_PUB_32 0x1009
2015#define S_LPROC_32 0x100a
2016#define S_GPROC_32 0x100b
2017#define S_VFTTABLE_32 0x100c
2018#define S_REGREL_32 0x100d
2019#define S_LTHREAD_32 0x100e
2020#define S_GTHREAD_32 0x100f
2021
2022
2023
2024static unsigned int
2025DEBUG_MapCVOffset( DBG_MODULE *module, unsigned int offset )
2026{
Eric Poueche9392062000-11-15 22:16:26 +00002027 int nomap = module->msc_info->nomap;
2028 OMAP_DATA *omapp = module->msc_info->omapp;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002029 int i;
2030
2031 if ( !nomap || !omapp )
2032 return offset;
2033
2034 /* FIXME: use binary search */
2035 for ( i = 0; i < nomap-1; i++ )
2036 if ( omapp[i].from <= offset && omapp[i+1].from > offset )
2037 return !omapp[i].to? 0 : omapp[i].to + (offset - omapp[i].from);
2038
2039 return 0;
2040}
2041
2042static struct name_hash *
2043DEBUG_AddCVSymbol( DBG_MODULE *module, char *name, int namelen,
Joerg Mayerd18140c2000-12-26 01:28:51 +00002044 int type, unsigned int seg, unsigned int offset,
2045 int size, int cookie, int flags,
Ulrich Weigand6011e982000-11-07 20:29:20 +00002046 struct codeview_linetab_hdr *linetab )
2047{
Eric Poueche9392062000-11-15 22:16:26 +00002048 int nsect = module->msc_info->nsect;
2049 PIMAGE_SECTION_HEADER sectp = module->msc_info->sectp;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002050
2051 struct name_hash *symbol;
2052 char symname[PATH_MAX];
2053 DBG_VALUE value;
2054
2055 /*
2056 * Some sanity checks
2057 */
2058
2059 if ( !name || !namelen )
2060 return NULL;
2061
2062 if ( !seg || seg > nsect )
2063 return NULL;
2064
2065 /*
2066 * Convert type, address, and symbol name
2067 */
2068 value.type = type? DEBUG_GetCVType( type ) : NULL;
2069 value.cookie = cookie;
2070
2071 value.addr.seg = 0;
2072 value.addr.off = (unsigned int) module->load_addr +
2073 DEBUG_MapCVOffset( module, sectp[seg-1].VirtualAddress + offset );
2074
2075 memcpy( symname, name, namelen );
2076 symname[namelen] = '\0';
2077
2078
2079 /*
2080 * Check whether we have line number information
2081 */
2082 if ( linetab )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002083 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002084 for ( ; linetab->linetab; linetab++ )
2085 if ( linetab->segno == seg
2086 && linetab->start <= offset
2087 && linetab->end > offset )
2088 break;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002089
Ulrich Weigand6011e982000-11-07 20:29:20 +00002090 if ( !linetab->linetab )
2091 linetab = NULL;
2092 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002093
Ulrich Weigand6011e982000-11-07 20:29:20 +00002094
2095 /*
2096 * Create Wine symbol record
2097 */
2098 symbol = DEBUG_AddSymbol( symname, &value,
2099 linetab? linetab->sourcefile : NULL, flags );
2100
2101 if ( size )
2102 DEBUG_SetSymbolSize( symbol, size );
2103
2104
2105 /*
2106 * Add line numbers if found
2107 */
2108 if ( linetab )
2109 {
Joerg Mayerd18140c2000-12-26 01:28:51 +00002110 unsigned int i;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002111 for ( i = 0; i < linetab->nline; i++ )
2112 if ( linetab->offtab[i] >= offset
2113 && linetab->offtab[i] < offset + size )
2114 {
2115 DEBUG_AddLineNumber( symbol, linetab->linetab[i],
2116 linetab->offtab[i] - offset );
2117 }
2118 }
2119
2120 return symbol;
2121}
2122
2123static struct wine_locals *
2124DEBUG_AddCVLocal( struct name_hash *func, char *name, int namelen,
2125 int type, int offset )
2126{
2127 struct wine_locals *local;
2128 char symname[PATH_MAX];
2129
2130 memcpy( symname, name, namelen );
2131 symname[namelen] = '\0';
2132
2133 local = DEBUG_AddLocal( func, 0, offset, 0, 0, symname );
2134 DEBUG_SetLocalSymbolType( local, DEBUG_GetCVType( type ) );
2135
2136 return local;
2137}
2138
2139static int
2140DEBUG_SnarfCodeView( DBG_MODULE *module, LPBYTE root, int offset, int size,
2141 struct codeview_linetab_hdr *linetab )
2142{
2143 struct name_hash *curr_func = NULL;
2144 int i, length;
2145
2146
2147 /*
2148 * Loop over the different types of records and whenever we
2149 * find something we are interested in, record it and move on.
2150 */
2151 for ( i = offset; i < size; i += length )
2152 {
2153 union codeview_symbol *sym = (union codeview_symbol *)(root + i);
2154 length = sym->generic.len + 2;
2155
2156 switch ( sym->generic.id )
2157 {
2158 /*
2159 * Global and local data symbols. We don't associate these
2160 * with any given source file.
2161 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002162 case S_GDATA:
2163 case S_LDATA:
2164 case S_PUB:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002165 DEBUG_AddCVSymbol( module, sym->data.name, sym->data.namelen,
2166 sym->data.symtype, sym->data.seg,
2167 sym->data.offset, 0,
2168 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2169 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002170 case S_GDATA_32:
2171 case S_LDATA_32:
2172 case S_PUB_32:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002173 DEBUG_AddCVSymbol( module, sym->data32.name, sym->data32.namelen,
2174 sym->data32.symtype, sym->data32.seg,
2175 sym->data32.offset, 0,
2176 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2177 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002178
Ulrich Weigand6011e982000-11-07 20:29:20 +00002179 /*
2180 * Sort of like a global function, but it just points
2181 * to a thunk, which is a stupid name for what amounts to
2182 * a PLT slot in the normal jargon that everyone else uses.
2183 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002184 case S_THUNK:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002185 DEBUG_AddCVSymbol( module, sym->thunk.name, sym->thunk.namelen,
2186 0, sym->thunk.segment,
2187 sym->thunk.offset, sym->thunk.thunk_len,
2188 DV_TARGET, SYM_WIN32 | SYM_FUNC, NULL );
2189 break;
2190
2191 /*
2192 * Global and static functions.
2193 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002194 case S_GPROC:
2195 case S_LPROC:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002196 DEBUG_Normalize( curr_func );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002197
Ulrich Weigand6011e982000-11-07 20:29:20 +00002198 curr_func = DEBUG_AddCVSymbol( module, sym->proc.name, sym->proc.namelen,
2199 sym->proc.proctype, sym->proc.segment,
2200 sym->proc.offset, sym->proc.proc_len,
2201 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002202
Ulrich Weigand6011e982000-11-07 20:29:20 +00002203 DEBUG_SetSymbolBPOff( curr_func, sym->proc.debug_start );
2204 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002205 case S_GPROC_32:
2206 case S_LPROC_32:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002207 DEBUG_Normalize( curr_func );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002208
Ulrich Weigand6011e982000-11-07 20:29:20 +00002209 curr_func = DEBUG_AddCVSymbol( module, sym->proc32.name, sym->proc32.namelen,
2210 sym->proc32.proctype, sym->proc32.segment,
2211 sym->proc32.offset, sym->proc32.proc_len,
2212 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002213
Ulrich Weigand6011e982000-11-07 20:29:20 +00002214 DEBUG_SetSymbolBPOff( curr_func, sym->proc32.debug_start );
2215 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002216
Ulrich Weigand6011e982000-11-07 20:29:20 +00002217
2218 /*
2219 * Function parameters and stack variables.
2220 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002221 case S_BPREL:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002222 DEBUG_AddCVLocal( curr_func, sym->stack.name, sym->stack.namelen,
2223 sym->stack.symtype, sym->stack.offset );
2224 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002225 case S_BPREL_32:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002226 DEBUG_AddCVLocal( curr_func, sym->stack32.name, sym->stack32.namelen,
2227 sym->stack32.symtype, sym->stack32.offset );
2228 break;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002229
Ulrich Weigand6011e982000-11-07 20:29:20 +00002230
2231 /*
2232 * These are special, in that they are always followed by an
2233 * additional length-prefixed string which is *not* included
2234 * into the symbol length count. We need to skip it.
2235 */
2236 case S_PROCREF:
2237 case S_DATAREF:
2238 case S_LPROCREF:
2239 {
2240 LPBYTE name = (LPBYTE)sym + length;
2241 length += (*name + 1 + 3) & ~3;
2242 break;
2243 }
2244 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002245 }
2246
Ulrich Weigand6011e982000-11-07 20:29:20 +00002247 DEBUG_Normalize( curr_func );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002248
Ulrich Weigand6011e982000-11-07 20:29:20 +00002249 if ( linetab ) DBG_free(linetab);
2250 return TRUE;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002251}
2252
2253
Ulrich Weigand6011e982000-11-07 20:29:20 +00002254
2255/*========================================================================
2256 * Process PDB file.
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002257 */
Ulrich Weigand8142a161999-12-10 03:43:53 +00002258
2259#pragma pack(1)
2260typedef struct _PDB_FILE
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002261{
Ulrich Weigand8142a161999-12-10 03:43:53 +00002262 DWORD size;
2263 DWORD unknown;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002264
Ulrich Weigand8142a161999-12-10 03:43:53 +00002265} PDB_FILE, *PPDB_FILE;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002266
Ulrich Weigand8142a161999-12-10 03:43:53 +00002267typedef struct _PDB_HEADER
2268{
2269 CHAR ident[40];
2270 DWORD signature;
2271 DWORD blocksize;
2272 WORD freelist;
2273 WORD total_alloc;
2274 PDB_FILE toc;
2275 WORD toc_block[ 1 ];
2276
2277} PDB_HEADER, *PPDB_HEADER;
2278
2279typedef struct _PDB_TOC
2280{
2281 DWORD nFiles;
2282 PDB_FILE file[ 1 ];
2283
2284} PDB_TOC, *PPDB_TOC;
2285
2286typedef struct _PDB_ROOT
2287{
2288 DWORD version;
2289 DWORD TimeDateStamp;
2290 DWORD unknown;
2291 DWORD cbNames;
2292 CHAR names[ 1 ];
2293
2294} PDB_ROOT, *PPDB_ROOT;
2295
2296typedef struct _PDB_TYPES_OLD
2297{
2298 DWORD version;
2299 WORD first_index;
2300 WORD last_index;
2301 DWORD type_size;
2302 WORD file;
2303 WORD pad;
2304
2305} PDB_TYPES_OLD, *PPDB_TYPES_OLD;
2306
2307typedef struct _PDB_TYPES
2308{
2309 DWORD version;
2310 DWORD type_offset;
2311 DWORD first_index;
2312 DWORD last_index;
2313 DWORD type_size;
2314 WORD file;
2315 WORD pad;
2316 DWORD hash_size;
2317 DWORD hash_base;
2318 DWORD hash_offset;
2319 DWORD hash_len;
2320 DWORD search_offset;
2321 DWORD search_len;
2322 DWORD unknown_offset;
2323 DWORD unknown_len;
2324
2325} PDB_TYPES, *PPDB_TYPES;
2326
2327typedef struct _PDB_SYMBOL_RANGE
2328{
2329 WORD segment;
2330 WORD pad1;
2331 DWORD offset;
2332 DWORD size;
2333 DWORD characteristics;
2334 WORD index;
2335 WORD pad2;
2336
2337} PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
2338
2339typedef struct _PDB_SYMBOL_RANGE_EX
2340{
2341 WORD segment;
2342 WORD pad1;
2343 DWORD offset;
2344 DWORD size;
2345 DWORD characteristics;
2346 WORD index;
2347 WORD pad2;
2348 DWORD timestamp;
2349 DWORD unknown;
2350
2351} PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
2352
2353typedef struct _PDB_SYMBOL_FILE
2354{
2355 DWORD unknown1;
2356 PDB_SYMBOL_RANGE range;
2357 WORD flag;
2358 WORD file;
2359 DWORD symbol_size;
2360 DWORD lineno_size;
2361 DWORD unknown2;
2362 DWORD nSrcFiles;
2363 DWORD attribute;
2364 CHAR filename[ 1 ];
2365
2366} PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
2367
2368typedef struct _PDB_SYMBOL_FILE_EX
2369{
2370 DWORD unknown1;
2371 PDB_SYMBOL_RANGE_EX range;
2372 WORD flag;
2373 WORD file;
2374 DWORD symbol_size;
2375 DWORD lineno_size;
2376 DWORD unknown2;
2377 DWORD nSrcFiles;
2378 DWORD attribute;
2379 DWORD reserved[ 2 ];
2380 CHAR filename[ 1 ];
2381
2382} PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
2383
2384typedef struct _PDB_SYMBOL_SOURCE
2385{
2386 WORD nModules;
2387 WORD nSrcFiles;
2388 WORD table[ 1 ];
2389
2390} PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
2391
2392typedef struct _PDB_SYMBOL_IMPORT
2393{
2394 DWORD unknown1;
2395 DWORD unknown2;
2396 DWORD TimeDateStamp;
2397 DWORD nRequests;
2398 CHAR filename[ 1 ];
2399
2400} PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
2401
2402typedef struct _PDB_SYMBOLS_OLD
2403{
2404 WORD hash1_file;
2405 WORD hash2_file;
2406 WORD gsym_file;
2407 WORD pad;
2408 DWORD module_size;
2409 DWORD offset_size;
2410 DWORD hash_size;
2411 DWORD srcmodule_size;
2412
2413} PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
2414
2415typedef struct _PDB_SYMBOLS
2416{
2417 DWORD signature;
2418 DWORD version;
Ulrich Weigand90394212000-10-22 23:48:06 +00002419 DWORD unknown;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002420 DWORD hash1_file;
2421 DWORD hash2_file;
2422 DWORD gsym_file;
2423 DWORD module_size;
2424 DWORD offset_size;
2425 DWORD hash_size;
2426 DWORD srcmodule_size;
2427 DWORD pdbimport_size;
2428 DWORD resvd[ 5 ];
2429
2430} PDB_SYMBOLS, *PPDB_SYMBOLS;
2431#pragma pack()
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002432
2433
Ulrich Weigand8142a161999-12-10 03:43:53 +00002434static void *pdb_read( LPBYTE image, WORD *block_list, int size )
2435{
2436 PPDB_HEADER pdb = (PPDB_HEADER)image;
2437 int i, nBlocks;
2438 LPBYTE buffer;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002439
Ulrich Weigand8142a161999-12-10 03:43:53 +00002440 if ( !size ) return NULL;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002441
Ulrich Weigand8142a161999-12-10 03:43:53 +00002442 nBlocks = (size + pdb->blocksize-1) / pdb->blocksize;
2443 buffer = DBG_alloc( nBlocks * pdb->blocksize );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002444
Ulrich Weigand8142a161999-12-10 03:43:53 +00002445 for ( i = 0; i < nBlocks; i++ )
2446 memcpy( buffer + i*pdb->blocksize,
2447 image + block_list[i]*pdb->blocksize, pdb->blocksize );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002448
Ulrich Weigand8142a161999-12-10 03:43:53 +00002449 return buffer;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002450}
2451
Joerg Mayerd18140c2000-12-26 01:28:51 +00002452static void *pdb_read_file( LPBYTE image, PPDB_TOC toc, DWORD fileNr )
Ulrich Weigand8142a161999-12-10 03:43:53 +00002453{
2454 PPDB_HEADER pdb = (PPDB_HEADER)image;
2455 WORD *block_list;
Joerg Mayerd18140c2000-12-26 01:28:51 +00002456 DWORD i;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002457
2458 if ( !toc || fileNr >= toc->nFiles )
2459 return NULL;
2460
2461 block_list = (WORD *) &toc->file[ toc->nFiles ];
2462 for ( i = 0; i < fileNr; i++ )
2463 block_list += (toc->file[i].size + pdb->blocksize-1) / pdb->blocksize;
2464
2465 return pdb_read( image, block_list, toc->file[fileNr].size );
2466}
2467
2468static void pdb_free( void *buffer )
2469{
2470 DBG_free( buffer );
2471}
2472
2473static void pdb_convert_types_header( PDB_TYPES *types, char *image )
2474{
2475 memset( types, 0, sizeof(PDB_TYPES) );
2476 if ( !image ) return;
2477
2478 if ( *(DWORD *)image < 19960000 ) /* FIXME: correct version? */
2479 {
2480 /* Old version of the types record header */
2481 PDB_TYPES_OLD *old = (PDB_TYPES_OLD *)image;
2482 types->version = old->version;
2483 types->type_offset = sizeof(PDB_TYPES_OLD);
2484 types->type_size = old->type_size;
2485 types->first_index = old->first_index;
2486 types->last_index = old->last_index;
2487 types->file = old->file;
2488 }
2489 else
2490 {
2491 /* New version of the types record header */
2492 *types = *(PDB_TYPES *)image;
2493 }
2494}
2495
2496static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols,
2497 int *header_size, char *image )
2498{
2499 memset( symbols, 0, sizeof(PDB_SYMBOLS) );
2500 if ( !image ) return;
2501
2502 if ( *(DWORD *)image != 0xffffffff )
2503 {
2504 /* Old version of the symbols record header */
2505 PDB_SYMBOLS_OLD *old = (PDB_SYMBOLS_OLD *)image;
2506 symbols->version = 0;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002507 symbols->module_size = old->module_size;
2508 symbols->offset_size = old->offset_size;
2509 symbols->hash_size = old->hash_size;
2510 symbols->srcmodule_size = old->srcmodule_size;
2511 symbols->pdbimport_size = 0;
2512 symbols->hash1_file = old->hash1_file;
2513 symbols->hash2_file = old->hash2_file;
2514 symbols->gsym_file = old->gsym_file;
2515
2516 *header_size = sizeof(PDB_SYMBOLS_OLD);
2517 }
2518 else
2519 {
2520 /* New version of the symbols record header */
2521 *symbols = *(PDB_SYMBOLS *)image;
2522
2523 *header_size = sizeof(PDB_SYMBOLS);
2524 }
2525}
2526
Eric Poueche9392062000-11-15 22:16:26 +00002527static enum DbgInfoLoad DEBUG_ProcessPDBFile( DBG_MODULE *module,
2528 const char *filename, DWORD timestamp )
Ulrich Weigand8142a161999-12-10 03:43:53 +00002529{
Eric Poueche9392062000-11-15 22:16:26 +00002530 enum DbgInfoLoad dil = DIL_ERROR;
Eric Poueche5efa0c2000-04-13 19:31:58 +00002531 HANDLE hFile, hMap;
2532 char *image = NULL;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002533 PDB_HEADER *pdb = NULL;
2534 PDB_TOC *toc = NULL;
2535 PDB_ROOT *root = NULL;
2536 char *types_image = NULL;
2537 char *symbols_image = NULL;
2538 PDB_TYPES types;
2539 PDB_SYMBOLS symbols;
2540 int header_size = 0;
2541 char *modimage, *file;
2542
Ulrich Weigand6011e982000-11-07 20:29:20 +00002543 DEBUG_Printf( DBG_CHN_TRACE, "Processing PDB file %s\n", filename );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002544
2545 /*
Eric Poueche5efa0c2000-04-13 19:31:58 +00002546 * Open and map() .PDB file
Ulrich Weigand8142a161999-12-10 03:43:53 +00002547 */
Ulrich Weigand6011e982000-11-07 20:29:20 +00002548 image = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2549 if ( !image )
2550 {
2551 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .PDB file %s\n", filename );
2552 goto leave;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002553 }
2554
2555 /*
2556 * Read in TOC and well-known files
2557 */
2558
2559 pdb = (PPDB_HEADER)image;
2560 toc = pdb_read( image, pdb->toc_block, pdb->toc.size );
2561 root = pdb_read_file( image, toc, 1 );
2562 types_image = pdb_read_file( image, toc, 2 );
2563 symbols_image = pdb_read_file( image, toc, 3 );
2564
2565 pdb_convert_types_header( &types, types_image );
2566 pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
2567
2568 /*
2569 * Check for unknown versions
2570 */
2571
2572 switch ( root->version )
2573 {
2574 case 19950623: /* VC 4.0 */
2575 case 19950814:
2576 case 19960307: /* VC 5.0 */
2577 case 19970604: /* VC 6.0 */
2578 break;
2579 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +00002580 DEBUG_Printf( DBG_CHN_ERR, "-Unknown root block version %ld\n", root->version );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002581 }
2582
2583 switch ( types.version )
2584 {
2585 case 19950410: /* VC 4.0 */
2586 case 19951122:
2587 case 19961031: /* VC 5.0 / 6.0 */
2588 break;
2589 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +00002590 DEBUG_Printf( DBG_CHN_ERR, "-Unknown type info version %ld\n", types.version );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002591 }
2592
2593 switch ( symbols.version )
2594 {
2595 case 0: /* VC 4.0 */
2596 case 19960307: /* VC 5.0 */
2597 case 19970606: /* VC 6.0 */
2598 break;
2599 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +00002600 DEBUG_Printf( DBG_CHN_ERR, "-Unknown symbol info version %ld\n", symbols.version );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002601 }
2602
2603
2604 /*
2605 * Check .PDB time stamp
2606 */
2607
Ulrich Weigand6011e982000-11-07 20:29:20 +00002608 if ( root->TimeDateStamp != timestamp )
Ulrich Weigand8142a161999-12-10 03:43:53 +00002609 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002610 DEBUG_Printf( DBG_CHN_ERR, "-Wrong time stamp of .PDB file %s (0x%08lx, 0x%08lx)\n",
2611 filename, root->TimeDateStamp, timestamp );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002612 }
2613
2614 /*
2615 * Read type table
2616 */
2617
2618 DEBUG_ParseTypeTable( types_image + types.type_offset, types.type_size );
2619
2620 /*
2621 * Read type-server .PDB imports
2622 */
2623
2624 if ( symbols.pdbimport_size )
2625 {
2626 /* FIXME */
Eric Poueche5efa0c2000-04-13 19:31:58 +00002627 DEBUG_Printf(DBG_CHN_ERR, "-Type server .PDB imports ignored!\n" );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002628 }
2629
2630 /*
2631 * Read global symbol table
2632 */
2633
2634 modimage = pdb_read_file( image, toc, symbols.gsym_file );
2635 if ( modimage )
2636 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002637 DEBUG_SnarfCodeView( module, modimage, 0,
Ulrich Weigand8142a161999-12-10 03:43:53 +00002638 toc->file[symbols.gsym_file].size, NULL );
2639 pdb_free( modimage );
2640 }
2641
2642 /*
2643 * Read per-module symbol / linenumber tables
2644 */
2645
2646 file = symbols_image + header_size;
2647 while ( file - symbols_image < header_size + symbols.module_size )
2648 {
2649 int file_nr, file_index, symbol_size, lineno_size;
2650 char *file_name;
2651
Ulrich Weigand90394212000-10-22 23:48:06 +00002652 if ( symbols.version < 19970000 )
Ulrich Weigand8142a161999-12-10 03:43:53 +00002653 {
2654 PDB_SYMBOL_FILE *sym_file = (PDB_SYMBOL_FILE *) file;
2655 file_nr = sym_file->file;
2656 file_name = sym_file->filename;
2657 file_index = sym_file->range.index;
2658 symbol_size = sym_file->symbol_size;
2659 lineno_size = sym_file->lineno_size;
2660 }
2661 else
2662 {
2663 PDB_SYMBOL_FILE_EX *sym_file = (PDB_SYMBOL_FILE_EX *) file;
2664 file_nr = sym_file->file;
2665 file_name = sym_file->filename;
2666 file_index = sym_file->range.index;
2667 symbol_size = sym_file->symbol_size;
2668 lineno_size = sym_file->lineno_size;
2669 }
2670
2671 modimage = pdb_read_file( image, toc, file_nr );
2672 if ( modimage )
2673 {
2674 struct codeview_linetab_hdr *linetab = NULL;
2675
2676 if ( lineno_size )
2677 linetab = DEBUG_SnarfLinetab( modimage + symbol_size, lineno_size );
2678
2679 if ( symbol_size )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002680 DEBUG_SnarfCodeView( module, modimage, sizeof(DWORD),
2681 symbol_size, linetab );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002682
2683 pdb_free( modimage );
2684 }
2685
2686 file_name += strlen(file_name) + 1;
2687 file = (char *)( (DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3 );
2688 }
2689
Eric Poueche9392062000-11-15 22:16:26 +00002690 dil = DIL_LOADED;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002691
2692 leave:
2693
2694 /*
2695 * Cleanup
2696 */
2697
Ulrich Weigand164bac92000-04-25 19:53:49 +00002698 DEBUG_ClearTypeTable();
2699
Ulrich Weigand8142a161999-12-10 03:43:53 +00002700 if ( symbols_image ) pdb_free( symbols_image );
2701 if ( types_image ) pdb_free( types_image );
2702 if ( root ) pdb_free( root );
2703 if ( toc ) pdb_free( toc );
2704
Eric Poueche5efa0c2000-04-13 19:31:58 +00002705 DEBUG_UnmapDebugInfoFile(hFile, hMap, image);
Ulrich Weigand8142a161999-12-10 03:43:53 +00002706
Eric Poueche9392062000-11-15 22:16:26 +00002707 return dil;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002708}
2709
2710
Ulrich Weigand6011e982000-11-07 20:29:20 +00002711
2712
2713/*========================================================================
2714 * Process CodeView debug information.
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002715 */
Ulrich Weigand6011e982000-11-07 20:29:20 +00002716
2717#define CODEVIEW_NB09_SIG ( 'N' | ('B' << 8) | ('0' << 16) | ('9' << 24) )
2718#define CODEVIEW_NB10_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('0' << 24) )
2719#define CODEVIEW_NB11_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('1' << 24) )
2720
2721typedef struct _CODEVIEW_HEADER
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002722{
Ulrich Weigand6011e982000-11-07 20:29:20 +00002723 DWORD dwSignature;
2724 DWORD lfoDirectory;
2725
2726} CODEVIEW_HEADER, *PCODEVIEW_HEADER;
2727
2728typedef struct _CODEVIEW_PDB_DATA
2729{
2730 DWORD timestamp;
2731 DWORD unknown;
2732 CHAR name[ 1 ];
2733
2734} CODEVIEW_PDB_DATA, *PCODEVIEW_PDB_DATA;
2735
2736typedef struct _CV_DIRECTORY_HEADER
2737{
2738 WORD cbDirHeader;
2739 WORD cbDirEntry;
2740 DWORD cDir;
2741 DWORD lfoNextDir;
2742 DWORD flags;
2743
2744} CV_DIRECTORY_HEADER, *PCV_DIRECTORY_HEADER;
2745
2746typedef struct _CV_DIRECTORY_ENTRY
2747{
2748 WORD subsection;
2749 WORD iMod;
2750 DWORD lfo;
2751 DWORD cb;
2752
2753} CV_DIRECTORY_ENTRY, *PCV_DIRECTORY_ENTRY;
Sergey Turchanovd72e2de1999-01-24 09:46:21 +00002754
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002755
Ulrich Weigand6011e982000-11-07 20:29:20 +00002756#define sstAlignSym 0x125
2757#define sstSrcModule 0x127
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002758
Ulrich Weigand6011e982000-11-07 20:29:20 +00002759
Eric Poueche9392062000-11-15 22:16:26 +00002760static enum DbgInfoLoad DEBUG_ProcessCodeView( DBG_MODULE *module, LPBYTE root )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002761{
2762 PCODEVIEW_HEADER cv = (PCODEVIEW_HEADER)root;
Eric Poueche9392062000-11-15 22:16:26 +00002763 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002764
2765 switch ( cv->dwSignature )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002766 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002767 case CODEVIEW_NB09_SIG:
2768 case CODEVIEW_NB11_SIG:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002769 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002770 PCV_DIRECTORY_HEADER hdr = (PCV_DIRECTORY_HEADER)(root + cv->lfoDirectory);
2771 PCV_DIRECTORY_ENTRY ent, prev, next;
Joerg Mayerd18140c2000-12-26 01:28:51 +00002772 unsigned int i;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002773
Ulrich Weigand6011e982000-11-07 20:29:20 +00002774 ent = (PCV_DIRECTORY_ENTRY)((LPBYTE)hdr + hdr->cbDirHeader);
2775 for ( i = 0; i < hdr->cDir; i++, ent = next )
2776 {
2777 next = (i == hdr->cDir-1)? NULL :
2778 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent + hdr->cbDirEntry);
2779 prev = (i == 0)? NULL :
2780 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent - hdr->cbDirEntry);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002781
Ulrich Weigand6011e982000-11-07 20:29:20 +00002782 if ( ent->subsection == sstAlignSym )
2783 {
2784 /*
2785 * Check the next and previous entry. If either is a
2786 * sstSrcModule, it contains the line number info for
2787 * this file.
2788 *
2789 * FIXME: This is not a general solution!
2790 */
2791 struct codeview_linetab_hdr *linetab = NULL;
Juergen Schmied7493ead2000-10-29 18:03:41 +00002792
Ulrich Weigand6011e982000-11-07 20:29:20 +00002793 if ( next && next->iMod == ent->iMod
2794 && next->subsection == sstSrcModule )
2795 linetab = DEBUG_SnarfLinetab( root + next->lfo, next->cb );
Juergen Schmied7493ead2000-10-29 18:03:41 +00002796
Ulrich Weigand6011e982000-11-07 20:29:20 +00002797 if ( prev && prev->iMod == ent->iMod
2798 && prev->subsection == sstSrcModule )
2799 linetab = DEBUG_SnarfLinetab( root + prev->lfo, prev->cb );
2800
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002801
Ulrich Weigand6011e982000-11-07 20:29:20 +00002802 DEBUG_SnarfCodeView( module, root + ent->lfo, sizeof(DWORD),
2803 ent->cb, linetab );
2804 }
2805 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002806
Eric Poueche9392062000-11-15 22:16:26 +00002807 dil = DIL_LOADED;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002808 break;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002809 }
Ulrich Weigand6011e982000-11-07 20:29:20 +00002810
2811 case CODEVIEW_NB10_SIG:
2812 {
2813 PCODEVIEW_PDB_DATA pdb = (PCODEVIEW_PDB_DATA)(cv + 1);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002814
Eric Poueche9392062000-11-15 22:16:26 +00002815 dil = DEBUG_ProcessPDBFile( module, pdb->name, pdb->timestamp );
Ulrich Weigand6011e982000-11-07 20:29:20 +00002816 break;
2817 }
2818
2819 default:
2820 DEBUG_Printf( DBG_CHN_ERR, "Unknown CODEVIEW signature %08lX in module %s\n",
2821 cv->dwSignature, module->module_name );
2822 break;
2823 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002824
Eric Poueche9392062000-11-15 22:16:26 +00002825 return dil;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002826}
2827
Ulrich Weigand6011e982000-11-07 20:29:20 +00002828
2829/*========================================================================
2830 * Process debug directory.
2831 */
Eric Poueche9392062000-11-15 22:16:26 +00002832static enum DbgInfoLoad DEBUG_ProcessDebugDirectory( DBG_MODULE *module,
2833 LPBYTE file_map,
2834 PIMAGE_DEBUG_DIRECTORY dbg,
2835 int nDbg )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00002836{
Eric Poueche9392062000-11-15 22:16:26 +00002837 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002838 int i;
2839
Ulrich Weigand6011e982000-11-07 20:29:20 +00002840 /* First, watch out for OMAP data */
2841 for ( i = 0; i < nDbg; i++ )
2842 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC )
2843 {
Eric Poueche9392062000-11-15 22:16:26 +00002844 module->msc_info->nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
2845 module->msc_info->omapp = (OMAP_DATA *)(file_map + dbg[i].PointerToRawData);
Ulrich Weigand6011e982000-11-07 20:29:20 +00002846 break;
2847 }
2848
2849
2850 /* Now, try to parse CodeView debug info */
Eric Poueche9392062000-11-15 22:16:26 +00002851 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002852 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW )
Eric Poueche9392062000-11-15 22:16:26 +00002853 dil = DEBUG_ProcessCodeView( module, file_map + dbg[i].PointerToRawData );
Ulrich Weigand6011e982000-11-07 20:29:20 +00002854
2855
2856 /* If not found, try to parse COFF debug info */
Eric Poueche9392062000-11-15 22:16:26 +00002857 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002858 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_COFF )
Eric Poueche9392062000-11-15 22:16:26 +00002859 dil = DEBUG_ProcessCoff( module, file_map + dbg[i].PointerToRawData );
Ulrich Weigand6011e982000-11-07 20:29:20 +00002860
Eric Poueche9392062000-11-15 22:16:26 +00002861#if 0
2862 /* FIXME: this should be supported... this is the debug information for
2863 * functions compiled without a frame pointer (FPO = frame pointer omission)
2864 * the associated data helps finding out the relevant information
2865 */
2866 for ( i = 0; i < nDbg; i++ )
2867 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_FPO )
2868 DEBUG_Printf(DBG_CHN_MESG, "This guy has FPO information\n");
Ulrich Weigand6011e982000-11-07 20:29:20 +00002869
Eric Poueche9392062000-11-15 22:16:26 +00002870#define FRAME_FPO 0
2871#define FRAME_TRAP 1
2872#define FRAME_TSS 2
2873
2874typedef struct _FPO_DATA {
2875 DWORD ulOffStart; /* offset 1st byte of function code */
2876 DWORD cbProcSize; /* # bytes in function */
2877 DWORD cdwLocals; /* # bytes in locals/4 */
2878 WORD cdwParams; /* # bytes in params/4 */
2879
2880 WORD cbProlog : 8; /* # bytes in prolog */
2881 WORD cbRegs : 3; /* # regs saved */
2882 WORD fHasSEH : 1; /* TRUE if SEH in func */
2883 WORD fUseBP : 1; /* TRUE if EBP has been allocated */
2884 WORD reserved : 1; /* reserved for future use */
2885 WORD cbFrame : 2; /* frame type */
2886} FPO_DATA;
2887#endif
2888
2889 return dil;
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00002890}
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002891
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002892
Ulrich Weigand6011e982000-11-07 20:29:20 +00002893/*========================================================================
2894 * Process DBG file.
2895 */
Eric Poueche9392062000-11-15 22:16:26 +00002896static enum DbgInfoLoad DEBUG_ProcessDBGFile( DBG_MODULE *module,
2897 const char *filename, DWORD timestamp )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002898{
Eric Poueche9392062000-11-15 22:16:26 +00002899 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002900 HANDLE hFile = 0, hMap = 0;
2901 LPBYTE file_map = NULL;
2902 PIMAGE_SEPARATE_DEBUG_HEADER hdr;
2903 PIMAGE_DEBUG_DIRECTORY dbg;
2904 int nDbg;
2905
2906
2907 DEBUG_Printf( DBG_CHN_TRACE, "Processing DBG file %s\n", filename );
2908
2909 file_map = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2910 if ( !file_map )
2911 {
2912 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .DBG file %s\n", filename );
2913 goto leave;
2914 }
2915
2916 hdr = (PIMAGE_SEPARATE_DEBUG_HEADER) file_map;
2917
2918 if ( hdr->TimeDateStamp != timestamp )
2919 {
2920 DEBUG_Printf( DBG_CHN_ERR, "Warning - %s has incorrect internal timestamp\n",
2921 filename );
2922 /*
2923 * Well, sometimes this happens to DBG files which ARE REALLY the right .DBG
2924 * files but nonetheless this check fails. Anyway, WINDBG (debugger for
2925 * Windows by Microsoft) loads debug symbols which have incorrect timestamps.
2926 */
2927 }
2928
2929
2930 dbg = (PIMAGE_DEBUG_DIRECTORY) ( file_map + sizeof(*hdr)
2931 + hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)
2932 + hdr->ExportedNamesSize );
2933
2934 nDbg = hdr->DebugDirectorySize / sizeof(*dbg);
2935
Eric Poueche9392062000-11-15 22:16:26 +00002936 dil = DEBUG_ProcessDebugDirectory( module, file_map, dbg, nDbg );
Ulrich Weigand6011e982000-11-07 20:29:20 +00002937
2938
2939 leave:
2940 DEBUG_UnmapDebugInfoFile( hFile, hMap, file_map );
Eric Poueche9392062000-11-15 22:16:26 +00002941 return dil;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002942}
2943
2944
2945/*========================================================================
2946 * Process MSC debug information in PE file.
2947 */
Eric Poueche9392062000-11-15 22:16:26 +00002948enum DbgInfoLoad DEBUG_RegisterMSCDebugInfo( DBG_MODULE *module, HANDLE hFile,
2949 void *_nth, unsigned long nth_ofs )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002950{
Eric Poueche9392062000-11-15 22:16:26 +00002951 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002952 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
2953 PIMAGE_DATA_DIRECTORY dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
2954 PIMAGE_DEBUG_DIRECTORY dbg = NULL;
2955 int nDbg;
2956 MSC_DBG_INFO extra_info = { 0, NULL, 0, NULL };
2957 HANDLE hMap = 0;
2958 LPBYTE file_map = NULL;
2959
2960
2961 /* Read in section data */
2962
Eric Poueche9392062000-11-15 22:16:26 +00002963 module->msc_info = &extra_info;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002964 extra_info.nsect = nth->FileHeader.NumberOfSections;
2965 extra_info.sectp = DBG_alloc( extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) );
2966 if ( !extra_info.sectp )
2967 goto leave;
2968
2969 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr +
2970 nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
2971 nth->FileHeader.SizeOfOptionalHeader,
2972 extra_info.sectp,
2973 extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) ) )
2974 goto leave;
2975
Ulrich Weigand6011e982000-11-07 20:29:20 +00002976 /* Read in debug directory */
2977
2978 nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
2979 if ( !nDbg )
2980 goto leave;
2981
2982 dbg = (PIMAGE_DEBUG_DIRECTORY) DBG_alloc( nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) );
2983 if ( !dbg )
2984 goto leave;
2985
2986 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr + dir->VirtualAddress,
2987 dbg, nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) ) )
2988 goto leave;
2989
2990
2991 /* Map in PE file */
2992 file_map = DEBUG_MapDebugInfoFile( NULL, 0, 0, &hFile, &hMap );
2993 if ( !file_map )
2994 goto leave;
2995
2996
2997 /* Parse debug directory */
2998
2999 if ( nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED )
3000 {
3001 /* Debug info is stripped to .DBG file */
3002
3003 PIMAGE_DEBUG_MISC misc = (PIMAGE_DEBUG_MISC)(file_map + dbg->PointerToRawData);
3004
3005 if ( nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC
3006 || misc->DataType != IMAGE_DEBUG_MISC_EXENAME )
3007 {
3008 DEBUG_Printf( DBG_CHN_ERR, "-Debug info stripped, but no .DBG file in module %s\n",
3009 module->module_name );
3010 goto leave;
3011 }
3012
Eric Poueche9392062000-11-15 22:16:26 +00003013 dil = DEBUG_ProcessDBGFile( module, misc->Data, nth->FileHeader.TimeDateStamp );
Ulrich Weigand6011e982000-11-07 20:29:20 +00003014 }
3015 else
3016 {
3017 /* Debug info is embedded into PE module */
3018
Eric Poueche9392062000-11-15 22:16:26 +00003019 dil = DEBUG_ProcessDebugDirectory( module, file_map, dbg, nDbg );
Ulrich Weigand6011e982000-11-07 20:29:20 +00003020 }
3021
3022
3023 leave:
Eric Poueche9392062000-11-15 22:16:26 +00003024 module->msc_info = NULL;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003025
3026 DEBUG_UnmapDebugInfoFile( 0, hMap, file_map );
3027 if ( extra_info.sectp ) DBG_free( extra_info.sectp );
3028 if ( dbg ) DBG_free( dbg );
Eric Poueche9392062000-11-15 22:16:26 +00003029 return dil;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003030}
3031
3032
3033/*========================================================================
3034 * look for stabs information in PE header (it's how mingw compiler provides its
3035 * debugging information), and also wine PE <-> ELF linking thru .wsolnk sections
3036 */
Eric Poueche9392062000-11-15 22:16:26 +00003037enum DbgInfoLoad DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile,
3038 void* _nth, unsigned long nth_ofs)
Ulrich Weigand6011e982000-11-07 20:29:20 +00003039{
3040 IMAGE_SECTION_HEADER pe_seg;
3041 unsigned long pe_seg_ofs;
3042 int i, stabsize = 0, stabstrsize = 0;
3043 unsigned int stabs = 0, stabstr = 0;
3044 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
Eric Poueche9392062000-11-15 22:16:26 +00003045 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003046
3047 pe_seg_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
3048 nth->FileHeader.SizeOfOptionalHeader;
3049
3050 for (i = 0; i < nth->FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg)) {
3051 if (!DEBUG_READ_MEM_VERBOSE((void*)((char *)module->load_addr + pe_seg_ofs),
3052 &pe_seg, sizeof(pe_seg)))
3053 continue;
3054
3055 if (!strcasecmp(pe_seg.Name, ".stab")) {
3056 stabs = pe_seg.VirtualAddress;
3057 stabsize = pe_seg.SizeOfRawData;
3058 } else if (!strncasecmp(pe_seg.Name, ".stabstr", 8)) {
3059 stabstr = pe_seg.VirtualAddress;
3060 stabstrsize = pe_seg.SizeOfRawData;
3061 }
3062 }
3063
3064 if (stabstrsize && stabsize) {
3065 char* s1 = DBG_alloc(stabsize+stabstrsize);
3066
3067 if (s1) {
3068 if (DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabs, s1, stabsize) &&
3069 DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabstr,
3070 s1 + stabsize, stabstrsize)) {
Eric Poueche9392062000-11-15 22:16:26 +00003071 dil = DEBUG_ParseStabs(s1, 0, 0, stabsize, stabsize, stabstrsize);
Ulrich Weigand6011e982000-11-07 20:29:20 +00003072 } else {
3073 DEBUG_Printf(DBG_CHN_MESG, "couldn't read data block\n");
3074 }
3075 DBG_free(s1);
3076 } else {
3077 DEBUG_Printf(DBG_CHN_MESG, "couldn't alloc %d bytes\n",
3078 stabsize + stabstrsize);
3079 }
Eric Poueche9392062000-11-15 22:16:26 +00003080 } else {
3081 dil = DIL_NOINFO;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003082 }
Eric Poueche9392062000-11-15 22:16:26 +00003083 return dil;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003084}
Alexandre Julliardc6c09441997-01-12 18:32:19 +00003085