blob: a45949246a26b97be3ec2c59f0290ed031bedc1d [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 Julliardf899ef02001-07-23 00:04:00 +000027
28#define MAX_PATHNAME_LEN 1024
Alexandre Julliardc6c09441997-01-12 18:32:19 +000029
Ulrich Weigand6011e982000-11-07 20:29:20 +000030typedef struct
31{
32 DWORD from;
33 DWORD to;
34
35} OMAP_DATA;
36
Eric Poueche9392062000-11-15 22:16:26 +000037typedef struct tagMSC_DBG_INFO
Ulrich Weigand6011e982000-11-07 20:29:20 +000038{
39 int nsect;
40 PIMAGE_SECTION_HEADER sectp;
41
42 int nomap;
43 OMAP_DATA * omapp;
44
Eric Pouechac11a682000-03-26 13:37:39 +000045} MSC_DBG_INFO;
46
Ulrich Weigand6011e982000-11-07 20:29:20 +000047/*========================================================================
48 * Debug file access helper routines
49 */
50
51
52/***********************************************************************
53 * DEBUG_LocateDebugInfoFile
54 *
55 * NOTE: dbg_filename must be at least MAX_PATHNAME_LEN bytes in size
Eric Pouechac11a682000-03-26 13:37:39 +000056 */
Eric Poueche5efa0c2000-04-13 19:31:58 +000057static void DEBUG_LocateDebugInfoFile(const char *filename, char *dbg_filename)
Sergey Turchanovd72e2de1999-01-24 09:46:21 +000058{
Eric Poueche5efa0c2000-04-13 19:31:58 +000059 char *str1 = DBG_alloc(MAX_PATHNAME_LEN);
60 char *str2 = DBG_alloc(MAX_PATHNAME_LEN*10);
61 const char *file;
Sergey Turchanovd72e2de1999-01-24 09:46:21 +000062 char *name_part;
Sergey Turchanovd72e2de1999-01-24 09:46:21 +000063
64 file = strrchr(filename, '\\');
65 if( file == NULL ) file = filename; else file++;
66
Eric Poueche5efa0c2000-04-13 19:31:58 +000067 if ((GetEnvironmentVariable("_NT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
68 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
69 (GetEnvironmentVariable("_NT_ALT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
70 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
71 (SearchPath(NULL, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part)))
72 lstrcpyn(dbg_filename, str2, MAX_PATHNAME_LEN);
Sergey Turchanovd72e2de1999-01-24 09:46:21 +000073 else
Eric Poueche5efa0c2000-04-13 19:31:58 +000074 lstrcpyn(dbg_filename, filename, MAX_PATHNAME_LEN);
Ove Kaavendda17c61999-04-25 12:24:42 +000075 DBG_free(str1);
76 DBG_free(str2);
Eric Poueche5efa0c2000-04-13 19:31:58 +000077}
78
79/***********************************************************************
80 * DEBUG_MapDebugInfoFile
81 */
82static void* DEBUG_MapDebugInfoFile(const char* name, DWORD offset, DWORD size,
83 HANDLE* hFile, HANDLE* hMap)
84{
Eric Poueche5efa0c2000-04-13 19:31:58 +000085 DWORD g_offset; /* offset aligned on map granuality */
86 DWORD g_size; /* size to map, with offset aligned */
87 char* ret;
88
89 *hMap = 0;
90
91 if (name != NULL) {
92 char filename[MAX_PATHNAME_LEN];
93
94 DEBUG_LocateDebugInfoFile(name, filename);
François Gougetd5042c42000-12-29 05:38:00 +000095 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 +000096 return NULL;
97 }
98
99 if (!size) {
100 DWORD file_size = GetFileSize(*hFile, NULL);
101 if (file_size == (DWORD)-1) return NULL;
102 size = file_size - offset;
103 }
104
105 g_offset = offset & ~0xFFFF; /* FIXME: is granularity portable ? */
106 g_size = offset + size - g_offset;
107
108 if ((*hMap = CreateFileMapping(*hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == 0)
109 return NULL;
110
111 if ((ret = MapViewOfFile(*hMap, FILE_MAP_READ, 0, g_offset, g_size)) != NULL)
112 ret += offset - g_offset;
113 return ret;
114}
115
116/***********************************************************************
117 * DEBUG_UnmapDebugInfoFile
118 */
119static void DEBUG_UnmapDebugInfoFile(HANDLE hFile, HANDLE hMap, void* addr)
120{
121 if (addr) UnmapViewOfFile(addr);
122 if (hMap) CloseHandle(hMap);
Marcus Meissnerbb72c3d2001-08-03 18:11:00 +0000123 if (hFile!=INVALID_HANDLE_VALUE) CloseHandle(hFile);
Sergey Turchanovd72e2de1999-01-24 09:46:21 +0000124}
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000125
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000126
Ulrich Weigand6011e982000-11-07 20:29:20 +0000127
128/*========================================================================
129 * Process COFF debug information.
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000130 */
Ulrich Weigand6011e982000-11-07 20:29:20 +0000131
Eric Pouech5394ab82000-11-12 03:40:55 +0000132struct CoffFile
Ulrich Weigand6011e982000-11-07 20:29:20 +0000133{
134 unsigned int startaddr;
135 unsigned int endaddr;
Eric Pouech5394ab82000-11-12 03:40:55 +0000136 const char *filename;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000137 int linetab_offset;
138 int linecnt;
139 struct name_hash **entries;
140 int neps;
141 int neps_alloc;
142};
143
Eric Pouech5394ab82000-11-12 03:40:55 +0000144struct CoffFileSet
Ulrich Weigand6011e982000-11-07 20:29:20 +0000145{
Eric Pouech5394ab82000-11-12 03:40:55 +0000146 struct CoffFile *files;
147 int nfiles;
148 int nfiles_alloc;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000149};
150
Eric Pouech5394ab82000-11-12 03:40:55 +0000151static const char* DEBUG_GetCoffName( PIMAGE_SYMBOL coff_sym, const char* coff_strtab )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000152{
Eric Pouech5394ab82000-11-12 03:40:55 +0000153 static char namebuff[9];
154 const char* nampnt;
155
156 if( coff_sym->N.Name.Short )
157 {
158 memcpy(namebuff, coff_sym->N.ShortName, 8);
159 namebuff[8] = '\0';
160 nampnt = &namebuff[0];
161 }
162 else
163 {
164 nampnt = coff_strtab + coff_sym->N.Name.Long;
165 }
166
167 if( nampnt[0] == '_' )
168 nampnt++;
169 return nampnt;
170}
171
172static int DEBUG_AddCoffFile( struct CoffFileSet* coff_files, const char* filename )
173{
174 struct CoffFile* file;
175
176 if( coff_files->nfiles + 1 >= coff_files->nfiles_alloc )
177 {
178 coff_files->nfiles_alloc += 10;
179 coff_files->files = (struct CoffFile *) DBG_realloc(coff_files->files,
180 coff_files->nfiles_alloc * sizeof(struct CoffFile));
181 }
182 file = coff_files->files + coff_files->nfiles;
183 file->startaddr = 0xffffffff;
184 file->endaddr = 0;
185 file->filename = filename;
186 file->linetab_offset = -1;
187 file->linecnt = 0;
188 file->entries = NULL;
189 file->neps = file->neps_alloc = 0;
190
191 return coff_files->nfiles++;
192}
193
194static void DEBUG_AddCoffSymbol( struct CoffFile* coff_file, struct name_hash* sym )
195{
196 if( coff_file->neps + 1 >= coff_file->neps_alloc )
197 {
198 coff_file->neps_alloc += 10;
199 coff_file->entries = (struct name_hash **)
200 DBG_realloc(coff_file->entries,
201 coff_file->neps_alloc * sizeof(struct name_hash *));
202 }
203 coff_file->entries[coff_file->neps++] = sym;
204}
Ulrich Weigand6011e982000-11-07 20:29:20 +0000205
Eric Poueche9392062000-11-15 22:16:26 +0000206static enum DbgInfoLoad DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000207{
Eric Pouech5394ab82000-11-12 03:40:55 +0000208 PIMAGE_AUX_SYMBOL aux;
209 PIMAGE_COFF_SYMBOLS_HEADER coff;
210 PIMAGE_LINENUMBER coff_linetab;
211 PIMAGE_LINENUMBER linepnt;
212 char * coff_strtab;
213 PIMAGE_SYMBOL coff_sym;
214 PIMAGE_SYMBOL coff_symbols;
215 struct CoffFileSet coff_files;
216 int curr_file_idx = -1;
Joerg Mayerd18140c2000-12-26 01:28:51 +0000217 unsigned int i;
218 int j;
219 int k;
220 int l;
Eric Pouech5394ab82000-11-12 03:40:55 +0000221 int linetab_indx;
222 const char * nampnt;
223 int naux;
224 DBG_VALUE new_value;
Eric Poueche9392062000-11-15 22:16:26 +0000225 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000226
227 DEBUG_Printf(DBG_CHN_TRACE, "Processing COFF symbols...\n");
228
Eric Pouech5394ab82000-11-12 03:40:55 +0000229 assert(sizeof(IMAGE_SYMBOL) == IMAGE_SIZEOF_SYMBOL);
230 assert(sizeof(IMAGE_LINENUMBER) == IMAGE_SIZEOF_LINENUMBER);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000231
Eric Pouech5394ab82000-11-12 03:40:55 +0000232 coff_files.files = NULL;
233 coff_files.nfiles = coff_files.nfiles_alloc = 0;
234
235 coff = (PIMAGE_COFF_SYMBOLS_HEADER) root;
236
237 coff_symbols = (PIMAGE_SYMBOL) ((unsigned int) coff + coff->LvaToFirstSymbol);
238 coff_linetab = (PIMAGE_LINENUMBER) ((unsigned int) coff + coff->LvaToFirstLinenumber);
239 coff_strtab = (char *) (coff_symbols + coff->NumberOfSymbols);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000240
241 linetab_indx = 0;
242
243 new_value.cookie = DV_TARGET;
244 new_value.type = NULL;
245
Eric Pouech5394ab82000-11-12 03:40:55 +0000246 for(i=0; i < coff->NumberOfSymbols; i++ )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000247 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000248 coff_sym = coff_symbols + i;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000249 naux = coff_sym->NumberOfAuxSymbols;
250
251 if( coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE )
252 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000253 curr_file_idx = DEBUG_AddCoffFile( &coff_files, (char *) (coff_sym + 1) );
254 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000255 i += naux;
256 continue;
257 }
258
Eric Pouech5394ab82000-11-12 03:40:55 +0000259 if (curr_file_idx < 0) {
260 assert(coff_files.nfiles == 0 && coff_files.nfiles_alloc == 0);
261 curr_file_idx = DEBUG_AddCoffFile( &coff_files, "<none>" );
262 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
263 }
264
Ulrich Weigand6011e982000-11-07 20:29:20 +0000265 /*
266 * This guy marks the size and location of the text section
267 * for the current file. We need to keep track of this so
268 * we can figure out what file the different global functions
269 * go with.
270 */
271 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
272 && (naux != 0)
273 && (coff_sym->Type == 0)
274 && (coff_sym->SectionNumber == 1) )
275 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000276 aux = (PIMAGE_AUX_SYMBOL) (coff_sym + 1);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000277
Eric Pouech5394ab82000-11-12 03:40:55 +0000278 if( coff_files.files[curr_file_idx].linetab_offset != -1 )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000279 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000280 /*
281 * Save this so we can still get the old name.
282 */
283 const char* fn = coff_files.files[curr_file_idx].filename;
284
285#ifdef MORE_DBG
286 DEBUG_Printf(DBG_CHN_TRACE, "Duplicating sect from %s: %lx %x %x %d %d\n",
287 coff_files.files[curr_file_idx].filename,
288 aux->Section.Length,
289 aux->Section.NumberOfRelocations,
290 aux->Section.NumberOfLinenumbers,
291 aux->Section.Number,
292 aux->Section.Selection);
293 DEBUG_Printf(DBG_CHN_TRACE, "More sect %d %s %08lx %d %d %d\n",
Ulrich Weigand6011e982000-11-07 20:29:20 +0000294 coff_sym->SectionNumber,
Eric Pouech5394ab82000-11-12 03:40:55 +0000295 DEBUG_GetCoffName( coff_sym, coff_strtab ),
Ulrich Weigand6011e982000-11-07 20:29:20 +0000296 coff_sym->Value,
297 coff_sym->Type,
298 coff_sym->StorageClass,
299 coff_sym->NumberOfAuxSymbols);
300#endif
301
302 /*
Ulrich Weigand6011e982000-11-07 20:29:20 +0000303 * Duplicate the file entry. We have no way to describe
304 * multiple text sections in our current way of handling things.
305 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000306 DEBUG_AddCoffFile( &coff_files, fn );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000307 }
Eric Pouech5394ab82000-11-12 03:40:55 +0000308#ifdef MORE_DBG
Ulrich Weigand6011e982000-11-07 20:29:20 +0000309 else
310 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000311 DEBUG_Printf(DBG_CHN_TRACE, "New text sect from %s: %lx %x %x %d %d\n",
312 coff_files.files[curr_file_idx].filename,
313 aux->Section.Length,
314 aux->Section.NumberOfRelocations,
315 aux->Section.NumberOfLinenumbers,
316 aux->Section.Number,
317 aux->Section.Selection);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000318 }
319#endif
320
Eric Pouech5394ab82000-11-12 03:40:55 +0000321 if( coff_files.files[curr_file_idx].startaddr > coff_sym->Value )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000322 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000323 coff_files.files[curr_file_idx].startaddr = coff_sym->Value;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000324 }
325
Eric Pouech5394ab82000-11-12 03:40:55 +0000326 if( coff_files.files[curr_file_idx].endaddr < coff_sym->Value + aux->Section.Length )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000327 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000328 coff_files.files[curr_file_idx].endaddr = coff_sym->Value + aux->Section.Length;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000329 }
330
Eric Pouech5394ab82000-11-12 03:40:55 +0000331 coff_files.files[curr_file_idx].linetab_offset = linetab_indx;
332 coff_files.files[curr_file_idx].linecnt = aux->Section.NumberOfLinenumbers;
333 linetab_indx += aux->Section.NumberOfLinenumbers;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000334 i += naux;
335 continue;
336 }
337
338 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
339 && (naux == 0)
340 && (coff_sym->SectionNumber == 1) )
341 {
Eric Poueche9392062000-11-15 22:16:26 +0000342 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000343 /*
344 * This is a normal static function when naux == 0.
345 * Just register it. The current file is the correct
346 * one in this instance.
347 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000348 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000349
350 new_value.addr.seg = 0;
Eric Pouech5394ab82000-11-12 03:40:55 +0000351 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000352
Eric Pouech5394ab82000-11-12 03:40:55 +0000353#ifdef MORE_DBG
Ulrich Weigand6011e982000-11-07 20:29:20 +0000354 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding static symbol %s\n", nampnt);
355#endif
Eric Pouech5394ab82000-11-12 03:40:55 +0000356
357 /* FIXME: was adding symbol to this_file ??? */
358 DEBUG_AddCoffSymbol( &coff_files.files[curr_file_idx],
359 DEBUG_AddSymbol( nampnt, &new_value,
360 coff_files.files[curr_file_idx].filename,
361 SYM_WIN32 | SYM_FUNC ) );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000362 i += naux;
363 continue;
364 }
365
366 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
367 && ISFCN(coff_sym->Type)
368 && (coff_sym->SectionNumber > 0) )
369 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000370 const char* this_file = NULL;
Eric Poueche9392062000-11-15 22:16:26 +0000371 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
Eric Pouech5394ab82000-11-12 03:40:55 +0000372 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000373
374 new_value.addr.seg = 0;
Eric Pouech5394ab82000-11-12 03:40:55 +0000375 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000376
Eric Pouech5394ab82000-11-12 03:40:55 +0000377#ifdef MORE_DBG
378 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000379
Eric Pouech5394ab82000-11-12 03:40:55 +0000380 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global symbol %s (sect=%s)\n",
381 nampnt, MSC_INFO(module)->sectp[coff_sym->SectionNumber - 1].Name);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000382#endif
383
384 /*
385 * Now we need to figure out which file this guy belongs to.
386 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000387 for(j=0; j < coff_files.nfiles; j++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000388 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000389 if( coff_files.files[j].startaddr <= base + coff_sym->Value
390 && coff_files.files[j].endaddr > base + coff_sym->Value )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000391 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000392 this_file = coff_files.files[j].filename;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000393 break;
394 }
395 }
Eric Pouech5394ab82000-11-12 03:40:55 +0000396 if (j < coff_files.nfiles) {
397 DEBUG_AddCoffSymbol( &coff_files.files[j],
398 DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 | SYM_FUNC ) );
399 } else {
400 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_FUNC );
401 }
Ulrich Weigand6011e982000-11-07 20:29:20 +0000402 i += naux;
403 continue;
404 }
405
406 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
407 && (coff_sym->SectionNumber > 0) )
408 {
Eric Poueche9392062000-11-15 22:16:26 +0000409 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000410 /*
411 * Similar to above, but for the case of data symbols.
412 * These aren't treated as entrypoints.
413 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000414 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000415
416 new_value.addr.seg = 0;
Eric Pouech5394ab82000-11-12 03:40:55 +0000417 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000418
Eric Pouech5394ab82000-11-12 03:40:55 +0000419#ifdef MORE_DBG
420 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000421
422 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global data symbol %s\n", nampnt);
423#endif
424
425 /*
426 * Now we need to figure out which file this guy belongs to.
427 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000428 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_DATA );
Ulrich Weigand6011e982000-11-07 20:29:20 +0000429 i += naux;
430 continue;
431 }
432
433 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
434 && (naux == 0) )
435 {
436 /*
437 * Ignore these. They don't have anything to do with
438 * reality.
439 */
440 i += naux;
441 continue;
442 }
443
Eric Pouech5394ab82000-11-12 03:40:55 +0000444#ifdef MORE_DBG
445 DEBUG_Printf(DBG_CHN_TRACE,"Skipping unknown entry '%s' %d %d %d\n",
446 DEBUG_GetCoffName( coff_sym, coff_strtab ),
447 coff_sym->StorageClass, coff_sym->SectionNumber, naux);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000448#endif
449
450 /*
451 * For now, skip past the aux entries.
452 */
453 i += naux;
454
455 }
456
457 /*
458 * OK, we now should have a list of files, and we should have a list
459 * of entrypoints. We need to sort the entrypoints so that we are
460 * able to tie the line numbers with the given functions within the
461 * file.
462 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000463 if( coff_files.files != NULL )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000464 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000465 for(j=0; j < coff_files.nfiles; j++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000466 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000467 if( coff_files.files[j].entries != NULL )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000468 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000469 qsort(coff_files.files[j].entries, coff_files.files[j].neps,
Ulrich Weigand6011e982000-11-07 20:29:20 +0000470 sizeof(struct name_hash *), DEBUG_cmp_sym);
471 }
472 }
473
474 /*
475 * Now pick apart the line number tables, and attach the entries
476 * to the given functions.
477 */
Eric Pouech5394ab82000-11-12 03:40:55 +0000478 for(j=0; j < coff_files.nfiles; j++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000479 {
Joerg Mayerd18140c2000-12-26 01:28:51 +0000480 l = 0;
Eric Pouech5394ab82000-11-12 03:40:55 +0000481 if( coff_files.files[j].neps != 0 )
482 for(k=0; k < coff_files.files[j].linecnt; k++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000483 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000484 linepnt = coff_linetab + coff_files.files[j].linetab_offset + k;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000485 /*
486 * If we have spilled onto the next entrypoint, then
487 * bump the counter..
488 */
489 while(TRUE)
490 {
Joerg Mayerd18140c2000-12-26 01:28:51 +0000491 if (l+1 >= coff_files.files[j].neps) break;
492 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l+1], &new_value.addr);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000493 if( (((unsigned int)module->load_addr +
Eric Pouech5394ab82000-11-12 03:40:55 +0000494 linepnt->Type.VirtualAddress) >= new_value.addr.off) )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000495 {
Joerg Mayerd18140c2000-12-26 01:28:51 +0000496 l++;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000497 } else break;
498 }
499
500 /*
501 * Add the line number. This is always relative to the
502 * start of the function, so we need to subtract that offset
503 * first.
504 */
Joerg Mayerd18140c2000-12-26 01:28:51 +0000505 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l], &new_value.addr);
506 DEBUG_AddLineNumber(coff_files.files[j].entries[l],
Eric Pouech5394ab82000-11-12 03:40:55 +0000507 linepnt->Linenumber,
Ulrich Weigand6011e982000-11-07 20:29:20 +0000508 (unsigned int) module->load_addr
Eric Pouech5394ab82000-11-12 03:40:55 +0000509 + linepnt->Type.VirtualAddress
Ulrich Weigand6011e982000-11-07 20:29:20 +0000510 - new_value.addr.off);
511 }
512 }
513 }
514
Eric Poueche9392062000-11-15 22:16:26 +0000515 dil = DIL_LOADED;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000516
Eric Pouech5394ab82000-11-12 03:40:55 +0000517 if( coff_files.files != NULL )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000518 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000519 for(j=0; j < coff_files.nfiles; j++)
Ulrich Weigand6011e982000-11-07 20:29:20 +0000520 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000521 if( coff_files.files[j].entries != NULL )
Ulrich Weigand6011e982000-11-07 20:29:20 +0000522 {
Eric Pouech5394ab82000-11-12 03:40:55 +0000523 DBG_free(coff_files.files[j].entries);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000524 }
525 }
Eric Pouech5394ab82000-11-12 03:40:55 +0000526 DBG_free(coff_files.files);
Ulrich Weigand6011e982000-11-07 20:29:20 +0000527 }
528
Eric Poueche9392062000-11-15 22:16:26 +0000529 return dil;
Ulrich Weigand6011e982000-11-07 20:29:20 +0000530
531}
532
533
534
535/*========================================================================
536 * Process CodeView type information.
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000537 */
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000538
539union codeview_type
540{
541 struct
542 {
543 short int len;
544 short int id;
545 } generic;
546
547 struct
548 {
549 short int len;
550 short int id;
551 short int attribute;
552 short int datatype;
553 unsigned char variant[1];
554 } pointer;
555
556 struct
557 {
558 short int len;
559 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000560 unsigned int datatype;
561 unsigned int attribute;
562 unsigned char variant[1];
563 } pointer32;
564
565 struct
566 {
567 short int len;
568 short int id;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000569 unsigned char nbits;
570 unsigned char bitoff;
571 unsigned short type;
572 } bitfield;
573
574 struct
575 {
576 short int len;
577 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000578 unsigned int type;
579 unsigned char nbits;
580 unsigned char bitoff;
581 } bitfield32;
582
583 struct
584 {
585 short int len;
586 short int id;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000587 short int elemtype;
588 short int idxtype;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000589 unsigned short int arrlen; /* numeric leaf */
590#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000591 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000592#endif
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000593 } array;
594
595 struct
596 {
597 short int len;
598 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000599 unsigned int elemtype;
600 unsigned int idxtype;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000601 unsigned short int arrlen; /* numeric leaf */
602#if 0
Ulrich Weigand8142a161999-12-10 03:43:53 +0000603 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000604#endif
Ulrich Weigand8142a161999-12-10 03:43:53 +0000605 } array32;
606
607 struct
608 {
609 short int len;
610 short int id;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000611 short int n_element;
612 short int fieldlist;
613 short int property;
614 short int derived;
615 short int vshape;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000616 unsigned short int structlen; /* numeric leaf */
617#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000618 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000619#endif
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000620 } structure;
621
622 struct
623 {
624 short int len;
625 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000626 short int n_element;
627 short int property;
628 unsigned int fieldlist;
629 unsigned int derived;
630 unsigned int vshape;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000631 unsigned short int structlen; /* numeric leaf */
632#if 0
Ulrich Weigand8142a161999-12-10 03:43:53 +0000633 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000634#endif
Ulrich Weigand8142a161999-12-10 03:43:53 +0000635 } structure32;
636
637 struct
638 {
639 short int len;
640 short int id;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000641 short int count;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000642 short int fieldlist;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000643 short int property;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000644 unsigned short int un_len; /* numeric leaf */
645#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000646 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000647#endif
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000648 } t_union;
649
650 struct
651 {
652 short int len;
653 short int id;
654 short int count;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000655 short int property;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000656 unsigned int fieldlist;
657 unsigned short int un_len; /* numeric leaf */
658#if 0
Ulrich Weigand8142a161999-12-10 03:43:53 +0000659 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000660#endif
Ulrich Weigand8142a161999-12-10 03:43:53 +0000661 } t_union32;
662
663 struct
664 {
665 short int len;
666 short int id;
667 short int count;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000668 short int type;
669 short int field;
670 short int property;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000671 unsigned char name[1];
672 } enumeration;
673
674 struct
675 {
Ulrich Weigand8142a161999-12-10 03:43:53 +0000676 short int len;
677 short int id;
678 short int count;
679 short int property;
680 unsigned int type;
681 unsigned int field;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000682 unsigned char name[1];
683 } enumeration32;
684
685 struct
686 {
Ulrich Weigand164bac92000-04-25 19:53:49 +0000687 short int len;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000688 short int id;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000689 unsigned char list[1];
690 } fieldlist;
691};
692
693union codeview_fieldtype
694{
695 struct
696 {
697 short int id;
698 } generic;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000699
700 struct
701 {
702 short int id;
703 short int type;
704 short int attribute;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000705 unsigned short int offset; /* numeric leaf */
706 } bclass;
707
708 struct
709 {
710 short int id;
711 short int attribute;
712 unsigned int type;
713 unsigned short int offset; /* numeric leaf */
714 } bclass32;
715
716 struct
717 {
718 short int id;
719 short int btype;
720 short int vbtype;
721 short int attribute;
722 unsigned short int vbpoff; /* numeric leaf */
723#if 0
724 unsigned short int vboff; /* numeric leaf */
725#endif
726 } vbclass;
727
728 struct
729 {
730 short int id;
731 short int attribute;
732 unsigned int btype;
733 unsigned int vbtype;
734 unsigned short int vbpoff; /* numeric leaf */
735#if 0
736 unsigned short int vboff; /* numeric leaf */
737#endif
738 } vbclass32;
739
740 struct
741 {
742 short int id;
743 short int attribute;
744 unsigned short int value; /* numeric leaf */
745#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000746 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000747#endif
748 } enumerate;
749
750 struct
751 {
752 short int id;
753 short int type;
754 unsigned char name[1];
755 } friendfcn;
756
757 struct
758 {
759 short int id;
760 short int _pad0;
761 unsigned int type;
762 unsigned char name[1];
763 } friendfcn32;
764
765 struct
766 {
767 short int id;
768 short int type;
769 short int attribute;
770 unsigned short int offset; /* numeric leaf */
771#if 0
772 unsigned char name[1];
773#endif
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000774 } member;
775
776 struct
777 {
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000778 short int id;
Ulrich Weigand8142a161999-12-10 03:43:53 +0000779 short int attribute;
780 unsigned int type;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000781 unsigned short int offset; /* numeric leaf */
782#if 0
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000783 unsigned char name[1];
Ulrich Weigand164bac92000-04-25 19:53:49 +0000784#endif
Ulrich Weigand8142a161999-12-10 03:43:53 +0000785 } member32;
Ulrich Weigand164bac92000-04-25 19:53:49 +0000786
787 struct
788 {
789 short int id;
790 short int type;
791 short int attribute;
792 unsigned char name[1];
793 } stmember;
794
795 struct
796 {
797 short int id;
798 short int attribute;
799 unsigned int type;
800 unsigned char name[1];
801 } stmember32;
802
803 struct
804 {
805 short int id;
806 short int count;
807 short int mlist;
808 unsigned char name[1];
809 } method;
810
811 struct
812 {
813 short int id;
814 short int count;
815 unsigned int mlist;
816 unsigned char name[1];
817 } method32;
818
819 struct
820 {
821 short int id;
822 short int index;
823 unsigned char name[1];
824 } nesttype;
825
826 struct
827 {
828 short int id;
829 short int _pad0;
830 unsigned int index;
831 unsigned char name[1];
832 } nesttype32;
833
834 struct
835 {
836 short int id;
837 short int type;
838 } vfunctab;
839
840 struct
841 {
842 short int id;
843 short int _pad0;
844 unsigned int type;
845 } vfunctab32;
846
847 struct
848 {
849 short int id;
850 short int type;
851 } friendcls;
852
853 struct
854 {
855 short int id;
856 short int _pad0;
857 unsigned int type;
858 } friendcls32;
859
860
861 struct
862 {
863 short int id;
864 short int attribute;
865 short int type;
866 unsigned char name[1];
867 } onemethod;
868 struct
869 {
870 short int id;
871 short int attribute;
872 short int type;
873 unsigned int vtab_offset;
874 unsigned char name[1];
875 } onemethod_virt;
876
877 struct
878 {
879 short int id;
880 short int attribute;
881 unsigned int type;
882 unsigned char name[1];
883 } onemethod32;
884 struct
885 {
886 short int id;
887 short int attribute;
888 unsigned int type;
889 unsigned int vtab_offset;
890 unsigned char name[1];
891 } onemethod32_virt;
892
893 struct
894 {
895 short int id;
896 short int type;
897 unsigned int offset;
898 } vfuncoff;
899
900 struct
901 {
902 short int id;
903 short int _pad0;
904 unsigned int type;
905 unsigned int offset;
906 } vfuncoff32;
907
908 struct
909 {
910 short int id;
911 short int attribute;
912 short int index;
913 unsigned char name[1];
914 } nesttypeex;
915
916 struct
917 {
918 short int id;
919 short int attribute;
920 unsigned int index;
921 unsigned char name[1];
922 } nesttypeex32;
923
924 struct
925 {
926 short int id;
927 short int attribute;
928 unsigned int type;
929 unsigned char name[1];
930 } membermodify;
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000931};
932
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000933
934/*
935 * This covers the basic datatypes that VC++ seems to be using these days.
936 * 32 bit mode only. There are additional numbers for the pointers in 16
937 * bit mode. There are many other types listed in the documents, but these
938 * are apparently not used by the compiler, or represent pointer types
939 * that are not used.
940 */
941#define T_NOTYPE 0x0000 /* Notype */
942#define T_ABS 0x0001 /* Abs */
943#define T_VOID 0x0003 /* Void */
944#define T_CHAR 0x0010 /* signed char */
945#define T_SHORT 0x0011 /* short */
946#define T_LONG 0x0012 /* long */
947#define T_QUAD 0x0013 /* long long */
948#define T_UCHAR 0x0020 /* unsigned char */
949#define T_USHORT 0x0021 /* unsigned short */
950#define T_ULONG 0x0022 /* unsigned long */
951#define T_UQUAD 0x0023 /* unsigned long long */
952#define T_REAL32 0x0040 /* float */
953#define T_REAL64 0x0041 /* double */
954#define T_RCHAR 0x0070 /* real char */
955#define T_WCHAR 0x0071 /* wide char */
956#define T_INT4 0x0074 /* int */
957#define T_UINT4 0x0075 /* unsigned int */
958
959#define T_32PVOID 0x0403 /* 32 bit near pointer to void */
960#define T_32PCHAR 0x0410 /* 16:32 near pointer to signed char */
961#define T_32PSHORT 0x0411 /* 16:32 near pointer to short */
962#define T_32PLONG 0x0412 /* 16:32 near pointer to int */
963#define T_32PQUAD 0x0413 /* 16:32 near pointer to long long */
964#define T_32PUCHAR 0x0420 /* 16:32 near pointer to unsigned char */
965#define T_32PUSHORT 0x0421 /* 16:32 near pointer to unsigned short */
966#define T_32PULONG 0x0422 /* 16:32 near pointer to unsigned int */
967#define T_32PUQUAD 0x0423 /* 16:32 near pointer to long long */
968#define T_32PREAL32 0x0440 /* 16:32 near pointer to float */
969#define T_32PREAL64 0x0441 /* 16:32 near pointer to float */
970#define T_32PRCHAR 0x0470 /* 16:32 near pointer to real char */
971#define T_32PWCHAR 0x0471 /* 16:32 near pointer to real char */
972#define T_32PINT4 0x0474 /* 16:32 near pointer to int */
973#define T_32PUINT4 0x0475 /* 16:32 near pointer to unsigned int */
974
Ulrich Weigand6011e982000-11-07 20:29:20 +0000975
Ulrich Weigand8142a161999-12-10 03:43:53 +0000976#define LF_MODIFIER 0x0001
977#define LF_POINTER 0x0002
978#define LF_ARRAY 0x0003
979#define LF_CLASS 0x0004
980#define LF_STRUCTURE 0x0005
981#define LF_UNION 0x0006
982#define LF_ENUM 0x0007
983#define LF_PROCEDURE 0x0008
984#define LF_MFUNCTION 0x0009
985#define LF_VTSHAPE 0x000a
986#define LF_COBOL0 0x000b
987#define LF_COBOL1 0x000c
988#define LF_BARRAY 0x000d
989#define LF_LABEL 0x000e
990#define LF_NULL 0x000f
991#define LF_NOTTRAN 0x0010
992#define LF_DIMARRAY 0x0011
993#define LF_VFTPATH 0x0012
994#define LF_PRECOMP 0x0013
995#define LF_ENDPRECOMP 0x0014
996#define LF_OEM 0x0015
997#define LF_TYPESERVER 0x0016
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000998
Ulrich Weigand8142a161999-12-10 03:43:53 +0000999#define LF_MODIFIER_32 0x1001 /* variants with new 32-bit type indices */
1000#define LF_POINTER_32 0x1002
1001#define LF_ARRAY_32 0x1003
1002#define LF_CLASS_32 0x1004
1003#define LF_STRUCTURE_32 0x1005
1004#define LF_UNION_32 0x1006
1005#define LF_ENUM_32 0x1007
1006#define LF_PROCEDURE_32 0x1008
1007#define LF_MFUNCTION_32 0x1009
1008#define LF_COBOL0_32 0x100a
1009#define LF_BARRAY_32 0x100b
1010#define LF_DIMARRAY_32 0x100c
1011#define LF_VFTPATH_32 0x100d
1012#define LF_PRECOMP_32 0x100e
1013#define LF_OEM_32 0x100f
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001014
Ulrich Weigand8142a161999-12-10 03:43:53 +00001015#define LF_SKIP 0x0200
1016#define LF_ARGLIST 0x0201
1017#define LF_DEFARG 0x0202
1018#define LF_LIST 0x0203
1019#define LF_FIELDLIST 0x0204
1020#define LF_DERIVED 0x0205
1021#define LF_BITFIELD 0x0206
1022#define LF_METHODLIST 0x0207
1023#define LF_DIMCONU 0x0208
1024#define LF_DIMCONLU 0x0209
1025#define LF_DIMVARU 0x020a
1026#define LF_DIMVARLU 0x020b
1027#define LF_REFSYM 0x020c
1028
1029#define LF_SKIP_32 0x1200 /* variants with new 32-bit type indices */
1030#define LF_ARGLIST_32 0x1201
1031#define LF_DEFARG_32 0x1202
1032#define LF_FIELDLIST_32 0x1203
1033#define LF_DERIVED_32 0x1204
1034#define LF_BITFIELD_32 0x1205
1035#define LF_METHODLIST_32 0x1206
1036#define LF_DIMCONU_32 0x1207
1037#define LF_DIMCONLU_32 0x1208
1038#define LF_DIMVARU_32 0x1209
1039#define LF_DIMVARLU_32 0x120a
1040
1041#define LF_BCLASS 0x0400
1042#define LF_VBCLASS 0x0401
1043#define LF_IVBCLASS 0x0402
1044#define LF_ENUMERATE 0x0403
1045#define LF_FRIENDFCN 0x0404
1046#define LF_INDEX 0x0405
1047#define LF_MEMBER 0x0406
1048#define LF_STMEMBER 0x0407
1049#define LF_METHOD 0x0408
1050#define LF_NESTTYPE 0x0409
1051#define LF_VFUNCTAB 0x040a
1052#define LF_FRIENDCLS 0x040b
1053#define LF_ONEMETHOD 0x040c
1054#define LF_VFUNCOFF 0x040d
1055#define LF_NESTTYPEEX 0x040e
1056#define LF_MEMBERMODIFY 0x040f
1057
1058#define LF_BCLASS_32 0x1400 /* variants with new 32-bit type indices */
1059#define LF_VBCLASS_32 0x1401
1060#define LF_IVBCLASS_32 0x1402
1061#define LF_FRIENDFCN_32 0x1403
1062#define LF_INDEX_32 0x1404
1063#define LF_MEMBER_32 0x1405
1064#define LF_STMEMBER_32 0x1406
1065#define LF_METHOD_32 0x1407
1066#define LF_NESTTYPE_32 0x1408
1067#define LF_VFUNCTAB_32 0x1409
1068#define LF_FRIENDCLS_32 0x140a
1069#define LF_ONEMETHOD_32 0x140b
1070#define LF_VFUNCOFF_32 0x140c
1071#define LF_NESTTYPEEX_32 0x140d
1072
Ulrich Weigand164bac92000-04-25 19:53:49 +00001073#define LF_NUMERIC 0x8000 /* numeric leaf types */
1074#define LF_CHAR 0x8000
1075#define LF_SHORT 0x8001
1076#define LF_USHORT 0x8002
1077#define LF_LONG 0x8003
1078#define LF_ULONG 0x8004
1079#define LF_REAL32 0x8005
1080#define LF_REAL64 0x8006
1081#define LF_REAL80 0x8007
1082#define LF_REAL128 0x8008
1083#define LF_QUADWORD 0x8009
1084#define LF_UQUADWORD 0x800a
1085#define LF_REAL48 0x800b
1086#define LF_COMPLEX32 0x800c
1087#define LF_COMPLEX64 0x800d
1088#define LF_COMPLEX80 0x800e
1089#define LF_COMPLEX128 0x800f
1090#define LF_VARSTRING 0x8010
Ulrich Weigand8142a161999-12-10 03:43:53 +00001091
1092
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001093
1094#define MAX_BUILTIN_TYPES 0x480
1095static struct datatype * cv_basic_types[MAX_BUILTIN_TYPES];
Joerg Mayerd18140c2000-12-26 01:28:51 +00001096static unsigned int num_cv_defined_types = 0;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001097static struct datatype **cv_defined_types = NULL;
1098
Ulrich Weigand6011e982000-11-07 20:29:20 +00001099void
1100DEBUG_InitCVDataTypes(void)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001101{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001102 /*
1103 * These are the common builtin types that are used by VC++.
1104 */
1105 cv_basic_types[T_NOTYPE] = NULL;
1106 cv_basic_types[T_ABS] = NULL;
1107 cv_basic_types[T_VOID] = DEBUG_NewDataType(DT_BASIC, "void");
1108 cv_basic_types[T_CHAR] = DEBUG_NewDataType(DT_BASIC, "char");
1109 cv_basic_types[T_SHORT] = DEBUG_NewDataType(DT_BASIC, "short int");
1110 cv_basic_types[T_LONG] = DEBUG_NewDataType(DT_BASIC, "long int");
1111 cv_basic_types[T_QUAD] = DEBUG_NewDataType(DT_BASIC, "long long int");
1112 cv_basic_types[T_UCHAR] = DEBUG_NewDataType(DT_BASIC, "unsigned char");
1113 cv_basic_types[T_USHORT] = DEBUG_NewDataType(DT_BASIC, "short unsigned int");
1114 cv_basic_types[T_ULONG] = DEBUG_NewDataType(DT_BASIC, "long unsigned int");
1115 cv_basic_types[T_UQUAD] = DEBUG_NewDataType(DT_BASIC, "long long unsigned int");
1116 cv_basic_types[T_REAL32] = DEBUG_NewDataType(DT_BASIC, "float");
1117 cv_basic_types[T_REAL64] = DEBUG_NewDataType(DT_BASIC, "double");
1118 cv_basic_types[T_RCHAR] = DEBUG_NewDataType(DT_BASIC, "char");
1119 cv_basic_types[T_WCHAR] = DEBUG_NewDataType(DT_BASIC, "short");
1120 cv_basic_types[T_INT4] = DEBUG_NewDataType(DT_BASIC, "int");
1121 cv_basic_types[T_UINT4] = DEBUG_NewDataType(DT_BASIC, "unsigned int");
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001122
Ulrich Weigand6011e982000-11-07 20:29:20 +00001123 cv_basic_types[T_32PVOID] = DEBUG_FindOrMakePointerType(cv_basic_types[T_VOID]);
1124 cv_basic_types[T_32PCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_CHAR]);
1125 cv_basic_types[T_32PSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_SHORT]);
1126 cv_basic_types[T_32PLONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_LONG]);
1127 cv_basic_types[T_32PQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_QUAD]);
1128 cv_basic_types[T_32PUCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UCHAR]);
1129 cv_basic_types[T_32PUSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_USHORT]);
1130 cv_basic_types[T_32PULONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_ULONG]);
1131 cv_basic_types[T_32PUQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UQUAD]);
1132 cv_basic_types[T_32PREAL32] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL32]);
1133 cv_basic_types[T_32PREAL64] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL64]);
1134 cv_basic_types[T_32PRCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_RCHAR]);
1135 cv_basic_types[T_32PWCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_WCHAR]);
1136 cv_basic_types[T_32PINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_INT4]);
1137 cv_basic_types[T_32PUINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UINT4]);
1138}
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001139
Ulrich Weigand164bac92000-04-25 19:53:49 +00001140
1141static int
1142numeric_leaf( int *value, unsigned short int *leaf )
1143{
1144 unsigned short int type = *leaf++;
1145 int length = 2;
1146
1147 if ( type < LF_NUMERIC )
1148 {
1149 *value = type;
1150 }
1151 else
1152 {
1153 switch ( type )
1154 {
1155 case LF_CHAR:
1156 length += 1;
1157 *value = *(char *)leaf;
1158 break;
1159
1160 case LF_SHORT:
1161 length += 2;
1162 *value = *(short *)leaf;
1163 break;
1164
1165 case LF_USHORT:
1166 length += 2;
1167 *value = *(unsigned short *)leaf;
1168 break;
1169
1170 case LF_LONG:
1171 length += 4;
1172 *value = *(int *)leaf;
1173 break;
1174
1175 case LF_ULONG:
1176 length += 4;
1177 *value = *(unsigned int *)leaf;
1178 break;
1179
1180 case LF_QUADWORD:
1181 case LF_UQUADWORD:
1182 length += 8;
1183 *value = 0; /* FIXME */
1184 break;
1185
1186 case LF_REAL32:
1187 length += 4;
1188 *value = 0; /* FIXME */
1189 break;
1190
1191 case LF_REAL48:
1192 length += 6;
1193 *value = 0; /* FIXME */
1194 break;
1195
1196 case LF_REAL64:
1197 length += 8;
1198 *value = 0; /* FIXME */
1199 break;
1200
1201 case LF_REAL80:
1202 length += 10;
1203 *value = 0; /* FIXME */
1204 break;
1205
1206 case LF_REAL128:
1207 length += 16;
1208 *value = 0; /* FIXME */
1209 break;
1210
1211 case LF_COMPLEX32:
1212 length += 4;
1213 *value = 0; /* FIXME */
1214 break;
1215
1216 case LF_COMPLEX64:
1217 length += 8;
1218 *value = 0; /* FIXME */
1219 break;
1220
1221 case LF_COMPLEX80:
1222 length += 10;
1223 *value = 0; /* FIXME */
1224 break;
1225
1226 case LF_COMPLEX128:
1227 length += 16;
1228 *value = 0; /* FIXME */
1229 break;
1230
1231 case LF_VARSTRING:
1232 length += 2 + *leaf;
1233 *value = 0; /* FIXME */
1234 break;
1235
1236 default:
1237 DEBUG_Printf( DBG_CHN_MESG, "Unknown numeric leaf type %04x\n", type );
1238 *value = 0;
1239 break;
1240 }
1241 }
1242
1243 return length;
1244}
1245
1246static char *
1247terminate_string( unsigned char *name )
1248{
1249 static char symname[256];
1250
1251 int namelen = name[0];
1252 assert( namelen >= 0 && namelen < 256 );
1253
1254 memcpy( symname, name+1, namelen );
1255 symname[namelen] = '\0';
1256
1257 if ( !*symname || strcmp( symname, "__unnamed" ) == 0 )
1258 return NULL;
1259 else
1260 return symname;
1261}
1262
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001263static
Ulrich Weigand8142a161999-12-10 03:43:53 +00001264struct datatype * DEBUG_GetCVType(unsigned int typeno)
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001265{
Ulrich Weigand164bac92000-04-25 19:53:49 +00001266 struct datatype * dt = NULL;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001267
Ulrich Weigand164bac92000-04-25 19:53:49 +00001268 /*
1269 * Convert Codeview type numbers into something we can grok internally.
1270 * Numbers < 0x1000 are all fixed builtin types. Numbers from 0x1000 and
1271 * up are all user defined (structs, etc).
1272 */
1273 if ( typeno < 0x1000 )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001274 {
Ulrich Weigand164bac92000-04-25 19:53:49 +00001275 if ( typeno < MAX_BUILTIN_TYPES )
1276 dt = cv_basic_types[typeno];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001277 }
Ulrich Weigand164bac92000-04-25 19:53:49 +00001278 else
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001279 {
Ulrich Weigand164bac92000-04-25 19:53:49 +00001280 if ( typeno - 0x1000 < num_cv_defined_types )
1281 dt = cv_defined_types[typeno - 0x1000];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001282 }
1283
Ulrich Weigand164bac92000-04-25 19:53:49 +00001284 return dt;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001285}
1286
1287static int
Ulrich Weigand164bac92000-04-25 19:53:49 +00001288DEBUG_AddCVType( unsigned int typeno, struct datatype *dt )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001289{
Ulrich Weigand164bac92000-04-25 19:53:49 +00001290 while ( typeno - 0x1000 >= num_cv_defined_types )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001291 {
Ulrich Weigand164bac92000-04-25 19:53:49 +00001292 num_cv_defined_types += 0x100;
1293 cv_defined_types = (struct datatype **)
1294 DBG_realloc( cv_defined_types,
1295 num_cv_defined_types * sizeof(struct datatype *) );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001296
Ulrich Weigand164bac92000-04-25 19:53:49 +00001297 memset( cv_defined_types + num_cv_defined_types - 0x100,
1298 0,
1299 0x100 * sizeof(struct datatype *) );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001300
Ulrich Weigand164bac92000-04-25 19:53:49 +00001301 if ( cv_defined_types == NULL )
1302 return FALSE;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001303 }
1304
Ulrich Weigand164bac92000-04-25 19:53:49 +00001305 cv_defined_types[ typeno - 0x1000 ] = dt;
1306 return TRUE;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001307}
1308
Ulrich Weigand164bac92000-04-25 19:53:49 +00001309static void
1310DEBUG_ClearTypeTable( void )
1311{
1312 if ( cv_defined_types )
1313 DBG_free( cv_defined_types );
1314
1315 cv_defined_types = NULL;
1316 num_cv_defined_types = 0;
1317}
1318
1319static int
1320DEBUG_AddCVType_Pointer( unsigned int typeno, unsigned int datatype )
1321{
1322 struct datatype *dt =
1323 DEBUG_FindOrMakePointerType( DEBUG_GetCVType( datatype ) );
1324
1325 return DEBUG_AddCVType( typeno, dt );
1326}
1327
1328static int
1329DEBUG_AddCVType_Array( unsigned int typeno, char *name,
1330 unsigned int elemtype, unsigned int arr_len )
1331{
1332 struct datatype *dt = DEBUG_NewDataType( DT_ARRAY, name );
1333 struct datatype *elem = DEBUG_GetCVType( elemtype );
1334 unsigned int elem_size = elem? DEBUG_GetObjectSize( elem ) : 0;
1335 unsigned int arr_max = elem_size? arr_len / elem_size : 0;
1336
1337 DEBUG_SetArrayParams( dt, 0, arr_max, elem );
1338 return DEBUG_AddCVType( typeno, dt );
1339}
1340
1341static int
1342DEBUG_AddCVType_Bitfield( unsigned int typeno,
1343 unsigned int bitoff, unsigned int nbits,
1344 unsigned int basetype )
1345{
1346 struct datatype *dt = DEBUG_NewDataType( DT_BITFIELD, NULL );
1347 struct datatype *base = DEBUG_GetCVType( basetype );
1348
1349 DEBUG_SetBitfieldParams( dt, bitoff, nbits, base );
1350 return DEBUG_AddCVType( typeno, dt );
1351}
1352
1353static int
1354DEBUG_AddCVType_EnumFieldList( unsigned int typeno, unsigned char *list, int len )
1355{
1356 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, NULL );
1357 unsigned char *ptr = list;
1358
1359 while ( ptr - list < len )
1360 {
1361 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1362
1363 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1364 {
1365 ptr += *ptr & 0x0f;
1366 continue;
1367 }
1368
1369 switch ( type->generic.id )
1370 {
1371 case LF_ENUMERATE:
1372 {
1373 int value, vlen = numeric_leaf( &value, &type->enumerate.value );
1374 unsigned char *name = (unsigned char *)&type->enumerate.value + vlen;
1375
1376 DEBUG_AddStructElement( dt, terminate_string( name ),
1377 NULL, value, 0 );
1378
1379 ptr += 2 + 2 + vlen + (1 + name[0]);
1380 break;
1381 }
1382
1383 default:
1384 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in ENUM field list\n",
1385 type->generic.id );
1386 return FALSE;
1387 }
1388 }
1389
1390 return DEBUG_AddCVType( typeno, dt );
1391}
1392
1393static int
1394DEBUG_AddCVType_StructFieldList( unsigned int typeno, unsigned char *list, int len )
1395{
1396 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, NULL );
1397 unsigned char *ptr = list;
1398
1399 while ( ptr - list < len )
1400 {
1401 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1402
1403 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1404 {
1405 ptr += *ptr & 0x0f;
1406 continue;
1407 }
1408
1409 switch ( type->generic.id )
1410 {
1411 case LF_BCLASS:
1412 {
1413 int offset, olen = numeric_leaf( &offset, &type->bclass.offset );
1414
1415 /* FIXME: ignored for now */
1416
1417 ptr += 2 + 2 + 2 + olen;
1418 break;
1419 }
1420
1421 case LF_BCLASS_32:
1422 {
1423 int offset, olen = numeric_leaf( &offset, &type->bclass32.offset );
1424
1425 /* FIXME: ignored for now */
1426
1427 ptr += 2 + 2 + 4 + olen;
1428 break;
1429 }
1430
1431 case LF_VBCLASS:
1432 case LF_IVBCLASS:
1433 {
1434 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass.vbpoff );
1435 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass.vbpoff + vbpoff);
1436 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1437
1438 /* FIXME: ignored for now */
1439
1440 ptr += 2 + 2 + 2 + 2 + vbplen + vplen;
1441 break;
1442 }
1443
1444 case LF_VBCLASS_32:
1445 case LF_IVBCLASS_32:
1446 {
1447 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass32.vbpoff );
1448 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass32.vbpoff + vbpoff);
1449 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1450
1451 /* FIXME: ignored for now */
1452
1453 ptr += 2 + 2 + 4 + 4 + vbplen + vplen;
1454 break;
1455 }
1456
1457 case LF_MEMBER:
1458 {
1459 int offset, olen = numeric_leaf( &offset, &type->member.offset );
1460 unsigned char *name = (unsigned char *)&type->member.offset + olen;
1461
1462 struct datatype *subtype = DEBUG_GetCVType( type->member.type );
1463 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1464
1465 DEBUG_AddStructElement( dt, terminate_string( name ),
1466 subtype, offset << 3, elem_size << 3 );
1467
1468 ptr += 2 + 2 + 2 + olen + (1 + name[0]);
1469 break;
1470 }
1471
1472 case LF_MEMBER_32:
1473 {
1474 int offset, olen = numeric_leaf( &offset, &type->member32.offset );
1475 unsigned char *name = (unsigned char *)&type->member32.offset + olen;
1476
1477 struct datatype *subtype = DEBUG_GetCVType( type->member32.type );
1478 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1479
1480 DEBUG_AddStructElement( dt, terminate_string( name ),
1481 subtype, offset << 3, elem_size << 3 );
1482
1483 ptr += 2 + 2 + 4 + olen + (1 + name[0]);
1484 break;
1485 }
1486
1487 case LF_STMEMBER:
1488 /* FIXME: ignored for now */
1489 ptr += 2 + 2 + 2 + (1 + type->stmember.name[0]);
1490 break;
1491
1492 case LF_STMEMBER_32:
1493 /* FIXME: ignored for now */
1494 ptr += 2 + 4 + 2 + (1 + type->stmember32.name[0]);
1495 break;
1496
1497 case LF_METHOD:
1498 /* FIXME: ignored for now */
1499 ptr += 2 + 2 + 2 + (1 + type->method.name[0]);
1500 break;
1501
1502 case LF_METHOD_32:
1503 /* FIXME: ignored for now */
1504 ptr += 2 + 2 + 4 + (1 + type->method32.name[0]);
1505 break;
1506
1507 case LF_NESTTYPE:
1508 /* FIXME: ignored for now */
1509 ptr += 2 + 2 + (1 + type->nesttype.name[0]);
1510 break;
1511
1512 case LF_NESTTYPE_32:
1513 /* FIXME: ignored for now */
1514 ptr += 2 + 2 + 4 + (1 + type->nesttype32.name[0]);
1515 break;
1516
1517 case LF_VFUNCTAB:
1518 /* FIXME: ignored for now */
1519 ptr += 2 + 2;
1520 break;
1521
1522 case LF_VFUNCTAB_32:
1523 /* FIXME: ignored for now */
1524 ptr += 2 + 2 + 4;
1525 break;
1526
1527 case LF_ONEMETHOD:
1528 /* FIXME: ignored for now */
1529 switch ( (type->onemethod.attribute >> 2) & 7 )
1530 {
1531 case 4: case 6: /* (pure) introducing virtual method */
1532 ptr += 2 + 2 + 2 + 4 + (1 + type->onemethod_virt.name[0]);
1533 break;
1534
1535 default:
1536 ptr += 2 + 2 + 2 + (1 + type->onemethod.name[0]);
1537 break;
1538 }
1539 break;
1540
1541 case LF_ONEMETHOD_32:
1542 /* FIXME: ignored for now */
1543 switch ( (type->onemethod32.attribute >> 2) & 7 )
1544 {
1545 case 4: case 6: /* (pure) introducing virtual method */
1546 ptr += 2 + 2 + 4 + 4 + (1 + type->onemethod32_virt.name[0]);
1547 break;
1548
1549 default:
1550 ptr += 2 + 2 + 4 + (1 + type->onemethod32.name[0]);
1551 break;
1552 }
1553 break;
1554
1555 default:
1556 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in STRUCT field list\n",
1557 type->generic.id );
1558 return FALSE;
1559 }
1560 }
1561
1562 return DEBUG_AddCVType( typeno, dt );
1563}
1564
1565static int
1566DEBUG_AddCVType_Enum( unsigned int typeno, char *name, unsigned int fieldlist )
1567{
1568 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, name );
1569 struct datatype *list = DEBUG_GetCVType( fieldlist );
1570
1571 if ( list )
1572 DEBUG_CopyFieldlist( dt, list );
1573
1574 return DEBUG_AddCVType( typeno, dt );
1575}
1576
1577static int
1578DEBUG_AddCVType_Struct( unsigned int typeno, char *name, int structlen, unsigned int fieldlist )
1579{
1580 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, name );
1581 struct datatype *list = DEBUG_GetCVType( fieldlist );
1582
1583 if ( list )
1584 {
1585 DEBUG_SetStructSize( dt, structlen );
1586 DEBUG_CopyFieldlist( dt, list );
1587 }
1588
1589 return DEBUG_AddCVType( typeno, dt );
1590}
1591
1592static int
1593DEBUG_ParseTypeTable( char *table, int len )
1594{
1595 unsigned int curr_type = 0x1000;
1596 char *ptr = table;
1597
1598 while ( ptr - table < len )
1599 {
1600 union codeview_type *type = (union codeview_type *) ptr;
1601 int retv = TRUE;
1602
1603 switch ( type->generic.id )
1604 {
1605 case LF_POINTER:
1606 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer.datatype );
1607 break;
1608 case LF_POINTER_32:
1609 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer32.datatype );
1610 break;
1611
1612 case LF_ARRAY:
1613 {
1614 int arrlen, alen = numeric_leaf( &arrlen, &type->array.arrlen );
1615 unsigned char *name = (unsigned char *)&type->array.arrlen + alen;
1616
1617 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1618 type->array.elemtype, arrlen );
1619 break;
1620 }
1621 case LF_ARRAY_32:
1622 {
1623 int arrlen, alen = numeric_leaf( &arrlen, &type->array32.arrlen );
1624 unsigned char *name = (unsigned char *)&type->array32.arrlen + alen;
1625
1626 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1627 type->array32.elemtype, type->array32.arrlen );
1628 break;
1629 }
1630
1631 case LF_BITFIELD:
1632 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield.bitoff,
1633 type->bitfield.nbits,
1634 type->bitfield.type );
1635 break;
1636 case LF_BITFIELD_32:
1637 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield32.bitoff,
1638 type->bitfield32.nbits,
1639 type->bitfield32.type );
1640 break;
1641
1642 case LF_FIELDLIST:
1643 case LF_FIELDLIST_32:
1644 {
1645 /*
1646 * A 'field list' is a CodeView-specific data type which doesn't
1647 * directly correspond to any high-level data type. It is used
1648 * to hold the collection of members of a struct, class, union
1649 * or enum type. The actual definition of that type will follow
1650 * later, and refer to the field list definition record.
1651 *
1652 * As we don't have a field list type ourselves, we look ahead
1653 * in the field list to try to find out whether this field list
1654 * will be used for an enum or struct type, and create a dummy
1655 * type of the corresponding sort. Later on, the definition of
1656 * the 'real' type will copy the member / enumeration data.
1657 */
1658
1659 char *list = type->fieldlist.list;
1660 int len = (ptr + type->generic.len + 2) - list;
1661
1662 if ( ((union codeview_fieldtype *)list)->generic.id == LF_ENUMERATE )
1663 retv = DEBUG_AddCVType_EnumFieldList( curr_type, list, len );
1664 else
1665 retv = DEBUG_AddCVType_StructFieldList( curr_type, list, len );
1666 break;
1667 }
1668
1669 case LF_STRUCTURE:
1670 case LF_CLASS:
1671 {
1672 int structlen, slen = numeric_leaf( &structlen, &type->structure.structlen );
1673 unsigned char *name = (unsigned char *)&type->structure.structlen + slen;
1674
1675 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1676 structlen, type->structure.fieldlist );
1677 break;
1678 }
1679 case LF_STRUCTURE_32:
1680 case LF_CLASS_32:
1681 {
1682 int structlen, slen = numeric_leaf( &structlen, &type->structure32.structlen );
1683 unsigned char *name = (unsigned char *)&type->structure32.structlen + slen;
1684
1685 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1686 structlen, type->structure32.fieldlist );
1687 break;
1688 }
1689
1690 case LF_UNION:
1691 {
1692 int un_len, ulen = numeric_leaf( &un_len, &type->t_union.un_len );
1693 unsigned char *name = (unsigned char *)&type->t_union.un_len + ulen;
1694
1695 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1696 un_len, type->t_union.fieldlist );
1697 break;
1698 }
1699 case LF_UNION_32:
1700 {
1701 int un_len, ulen = numeric_leaf( &un_len, &type->t_union32.un_len );
1702 unsigned char *name = (unsigned char *)&type->t_union32.un_len + ulen;
1703
1704 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1705 un_len, type->t_union32.fieldlist );
1706 break;
1707 }
1708
1709 case LF_ENUM:
1710 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration.name ),
1711 type->enumeration.field );
1712 break;
1713 case LF_ENUM_32:
1714 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration32.name ),
1715 type->enumeration32.field );
1716 break;
1717
1718 default:
1719 break;
1720 }
1721
1722 if ( !retv )
1723 return FALSE;
1724
1725 curr_type++;
1726 ptr += type->generic.len + 2;
1727 }
1728
1729 return TRUE;
1730}
1731
1732
Ulrich Weigand6011e982000-11-07 20:29:20 +00001733/*========================================================================
1734 * Process CodeView line number information.
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001735 */
Ulrich Weigand6011e982000-11-07 20:29:20 +00001736
1737union any_size
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001738{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001739 char * c;
1740 short * s;
1741 int * i;
1742 unsigned int * ui;
1743};
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001744
Ulrich Weigand6011e982000-11-07 20:29:20 +00001745struct startend
Eric Pouechac11a682000-03-26 13:37:39 +00001746{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001747 unsigned int start;
1748 unsigned int end;
1749};
Eric Pouechac11a682000-03-26 13:37:39 +00001750
Ulrich Weigand6011e982000-11-07 20:29:20 +00001751struct codeview_linetab_hdr
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001752{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001753 unsigned int nline;
1754 unsigned int segno;
1755 unsigned int start;
1756 unsigned int end;
1757 char * sourcefile;
1758 unsigned short * linetab;
1759 unsigned int * offtab;
1760};
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001761
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001762static struct codeview_linetab_hdr *
Ulrich Weigand6011e982000-11-07 20:29:20 +00001763DEBUG_SnarfLinetab(char * linetab,
1764 int size)
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001765{
1766 int file_segcount;
1767 char filename[PATH_MAX];
1768 unsigned int * filetab;
1769 char * fn;
1770 int i;
1771 int k;
1772 struct codeview_linetab_hdr * lt_hdr;
1773 unsigned int * lt_ptr;
1774 int nfile;
1775 int nseg;
1776 union any_size pnt;
1777 union any_size pnt2;
1778 struct startend * start;
1779 int this_seg;
1780
1781 /*
1782 * Now get the important bits.
1783 */
Patrik Stridvall896889f1999-05-08 12:50:36 +00001784 pnt.c = linetab;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001785 nfile = *pnt.s++;
1786 nseg = *pnt.s++;
1787
1788 filetab = (unsigned int *) pnt.c;
1789
1790 /*
1791 * Now count up the number of segments in the file.
1792 */
1793 nseg = 0;
1794 for(i=0; i<nfile; i++)
1795 {
Patrik Stridvall896889f1999-05-08 12:50:36 +00001796 pnt2.c = linetab + filetab[i];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001797 nseg += *pnt2.s;
1798 }
1799
1800 /*
1801 * Next allocate the header we will be returning.
1802 * There is one header for each segment, so that we can reach in
1803 * and pull bits as required.
1804 */
1805 lt_hdr = (struct codeview_linetab_hdr *)
Ove Kaavendda17c61999-04-25 12:24:42 +00001806 DBG_alloc((nseg + 1) * sizeof(*lt_hdr));
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001807 if( lt_hdr == NULL )
1808 {
1809 goto leave;
1810 }
1811
1812 memset(lt_hdr, 0, sizeof(*lt_hdr) * (nseg+1));
1813
1814 /*
1815 * Now fill the header we will be returning, one for each segment.
1816 * Note that this will basically just contain pointers into the existing
1817 * line table, and we do not actually copy any additional information
1818 * or allocate any additional memory.
1819 */
1820
1821 this_seg = 0;
1822 for(i=0; i<nfile; i++)
1823 {
1824 /*
1825 * Get the pointer into the segment information.
1826 */
Patrik Stridvall896889f1999-05-08 12:50:36 +00001827 pnt2.c = linetab + filetab[i];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001828 file_segcount = *pnt2.s;
1829
1830 pnt2.ui++;
1831 lt_ptr = (unsigned int *) pnt2.c;
1832 start = (struct startend *) (lt_ptr + file_segcount);
1833
1834 /*
1835 * Now snarf the filename for all of the segments for this file.
1836 */
1837 fn = (unsigned char *) (start + file_segcount);
1838 memset(filename, 0, sizeof(filename));
1839 memcpy(filename, fn + 1, *fn);
Ove Kaavendda17c61999-04-25 12:24:42 +00001840 fn = DBG_strdup(filename);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001841
1842 for(k = 0; k < file_segcount; k++, this_seg++)
1843 {
Patrik Stridvall896889f1999-05-08 12:50:36 +00001844 pnt2.c = linetab + lt_ptr[k];
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001845 lt_hdr[this_seg].start = start[k].start;
1846 lt_hdr[this_seg].end = start[k].end;
1847 lt_hdr[this_seg].sourcefile = fn;
1848 lt_hdr[this_seg].segno = *pnt2.s++;
1849 lt_hdr[this_seg].nline = *pnt2.s++;
1850 lt_hdr[this_seg].offtab = pnt2.ui;
1851 lt_hdr[this_seg].linetab = (unsigned short *)
1852 (pnt2.ui + lt_hdr[this_seg].nline);
1853 }
1854 }
1855
1856leave:
1857
1858 return lt_hdr;
1859
1860}
1861
Ulrich Weigand6011e982000-11-07 20:29:20 +00001862
1863/*========================================================================
1864 * Process CodeView symbol information.
1865 */
1866
1867union codeview_symbol
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001868{
Ulrich Weigand6011e982000-11-07 20:29:20 +00001869 struct
1870 {
1871 short int len;
1872 short int id;
1873 } generic;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001874
Ulrich Weigand6011e982000-11-07 20:29:20 +00001875 struct
1876 {
1877 short int len;
1878 short int id;
1879 unsigned int offset;
1880 unsigned short seg;
1881 unsigned short symtype;
1882 unsigned char namelen;
1883 unsigned char name[1];
1884 } data;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00001885
Ulrich Weigand6011e982000-11-07 20:29:20 +00001886 struct
1887 {
1888 short int len;
1889 short int id;
1890 unsigned int symtype;
1891 unsigned int offset;
1892 unsigned short seg;
1893 unsigned char namelen;
1894 unsigned char name[1];
1895 } data32;
1896
1897 struct
1898 {
1899 short int len;
1900 short int id;
1901 unsigned int pparent;
1902 unsigned int pend;
1903 unsigned int next;
1904 unsigned int offset;
1905 unsigned short segment;
1906 unsigned short thunk_len;
1907 unsigned char thtype;
1908 unsigned char namelen;
1909 unsigned char name[1];
1910 } thunk;
1911
1912 struct
1913 {
1914 short int len;
1915 short int id;
1916 unsigned int pparent;
1917 unsigned int pend;
1918 unsigned int next;
1919 unsigned int proc_len;
1920 unsigned int debug_start;
1921 unsigned int debug_end;
1922 unsigned int offset;
1923 unsigned short segment;
1924 unsigned short proctype;
1925 unsigned char flags;
1926 unsigned char namelen;
1927 unsigned char name[1];
1928 } proc;
1929
1930 struct
1931 {
1932 short int len;
1933 short int id;
1934 unsigned int pparent;
1935 unsigned int pend;
1936 unsigned int next;
1937 unsigned int proc_len;
1938 unsigned int debug_start;
1939 unsigned int debug_end;
1940 unsigned int proctype;
1941 unsigned int offset;
1942 unsigned short segment;
1943 unsigned char flags;
1944 unsigned char namelen;
1945 unsigned char name[1];
1946 } proc32;
1947
1948 struct
1949 {
1950 short int len; /* Total length of this entry */
1951 short int id; /* Always S_BPREL32 */
1952 unsigned int offset; /* Stack offset relative to BP */
1953 unsigned short symtype;
1954 unsigned char namelen;
1955 unsigned char name[1];
1956 } stack;
1957
1958 struct
1959 {
1960 short int len; /* Total length of this entry */
1961 short int id; /* Always S_BPREL32 */
1962 unsigned int offset; /* Stack offset relative to BP */
1963 unsigned int symtype;
1964 unsigned char namelen;
1965 unsigned char name[1];
1966 } stack32;
1967
1968};
1969
1970#define S_COMPILE 0x0001
1971#define S_REGISTER 0x0002
1972#define S_CONSTANT 0x0003
1973#define S_UDT 0x0004
1974#define S_SSEARCH 0x0005
1975#define S_END 0x0006
1976#define S_SKIP 0x0007
1977#define S_CVRESERVE 0x0008
1978#define S_OBJNAME 0x0009
1979#define S_ENDARG 0x000a
1980#define S_COBOLUDT 0x000b
1981#define S_MANYREG 0x000c
1982#define S_RETURN 0x000d
1983#define S_ENTRYTHIS 0x000e
1984
1985#define S_BPREL 0x0200
1986#define S_LDATA 0x0201
1987#define S_GDATA 0x0202
1988#define S_PUB 0x0203
1989#define S_LPROC 0x0204
1990#define S_GPROC 0x0205
1991#define S_THUNK 0x0206
1992#define S_BLOCK 0x0207
1993#define S_WITH 0x0208
1994#define S_LABEL 0x0209
1995#define S_CEXMODEL 0x020a
1996#define S_VFTPATH 0x020b
1997#define S_REGREL 0x020c
1998#define S_LTHREAD 0x020d
1999#define S_GTHREAD 0x020e
2000
2001#define S_PROCREF 0x0400
2002#define S_DATAREF 0x0401
2003#define S_ALIGN 0x0402
2004#define S_LPROCREF 0x0403
2005
2006#define S_REGISTER_32 0x1001 /* Variants with new 32-bit type indices */
2007#define S_CONSTANT_32 0x1002
2008#define S_UDT_32 0x1003
2009#define S_COBOLUDT_32 0x1004
2010#define S_MANYREG_32 0x1005
2011
2012#define S_BPREL_32 0x1006
2013#define S_LDATA_32 0x1007
2014#define S_GDATA_32 0x1008
2015#define S_PUB_32 0x1009
2016#define S_LPROC_32 0x100a
2017#define S_GPROC_32 0x100b
2018#define S_VFTTABLE_32 0x100c
2019#define S_REGREL_32 0x100d
2020#define S_LTHREAD_32 0x100e
2021#define S_GTHREAD_32 0x100f
2022
2023
2024
2025static unsigned int
2026DEBUG_MapCVOffset( DBG_MODULE *module, unsigned int offset )
2027{
Eric Poueche9392062000-11-15 22:16:26 +00002028 int nomap = module->msc_info->nomap;
2029 OMAP_DATA *omapp = module->msc_info->omapp;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002030 int i;
2031
2032 if ( !nomap || !omapp )
2033 return offset;
2034
2035 /* FIXME: use binary search */
2036 for ( i = 0; i < nomap-1; i++ )
2037 if ( omapp[i].from <= offset && omapp[i+1].from > offset )
2038 return !omapp[i].to? 0 : omapp[i].to + (offset - omapp[i].from);
2039
2040 return 0;
2041}
2042
2043static struct name_hash *
2044DEBUG_AddCVSymbol( DBG_MODULE *module, char *name, int namelen,
Joerg Mayerd18140c2000-12-26 01:28:51 +00002045 int type, unsigned int seg, unsigned int offset,
2046 int size, int cookie, int flags,
Ulrich Weigand6011e982000-11-07 20:29:20 +00002047 struct codeview_linetab_hdr *linetab )
2048{
Eric Poueche9392062000-11-15 22:16:26 +00002049 int nsect = module->msc_info->nsect;
2050 PIMAGE_SECTION_HEADER sectp = module->msc_info->sectp;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002051
2052 struct name_hash *symbol;
2053 char symname[PATH_MAX];
2054 DBG_VALUE value;
2055
2056 /*
2057 * Some sanity checks
2058 */
2059
2060 if ( !name || !namelen )
2061 return NULL;
2062
2063 if ( !seg || seg > nsect )
2064 return NULL;
2065
2066 /*
2067 * Convert type, address, and symbol name
2068 */
2069 value.type = type? DEBUG_GetCVType( type ) : NULL;
2070 value.cookie = cookie;
2071
2072 value.addr.seg = 0;
2073 value.addr.off = (unsigned int) module->load_addr +
2074 DEBUG_MapCVOffset( module, sectp[seg-1].VirtualAddress + offset );
2075
2076 memcpy( symname, name, namelen );
2077 symname[namelen] = '\0';
2078
2079
2080 /*
2081 * Check whether we have line number information
2082 */
2083 if ( linetab )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002084 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002085 for ( ; linetab->linetab; linetab++ )
2086 if ( linetab->segno == seg
2087 && linetab->start <= offset
2088 && linetab->end > offset )
2089 break;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002090
Ulrich Weigand6011e982000-11-07 20:29:20 +00002091 if ( !linetab->linetab )
2092 linetab = NULL;
2093 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002094
Ulrich Weigand6011e982000-11-07 20:29:20 +00002095
2096 /*
2097 * Create Wine symbol record
2098 */
2099 symbol = DEBUG_AddSymbol( symname, &value,
2100 linetab? linetab->sourcefile : NULL, flags );
2101
2102 if ( size )
2103 DEBUG_SetSymbolSize( symbol, size );
2104
2105
2106 /*
2107 * Add line numbers if found
2108 */
2109 if ( linetab )
2110 {
Joerg Mayerd18140c2000-12-26 01:28:51 +00002111 unsigned int i;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002112 for ( i = 0; i < linetab->nline; i++ )
2113 if ( linetab->offtab[i] >= offset
2114 && linetab->offtab[i] < offset + size )
2115 {
2116 DEBUG_AddLineNumber( symbol, linetab->linetab[i],
2117 linetab->offtab[i] - offset );
2118 }
2119 }
2120
2121 return symbol;
2122}
2123
2124static struct wine_locals *
2125DEBUG_AddCVLocal( struct name_hash *func, char *name, int namelen,
2126 int type, int offset )
2127{
2128 struct wine_locals *local;
2129 char symname[PATH_MAX];
2130
2131 memcpy( symname, name, namelen );
2132 symname[namelen] = '\0';
2133
2134 local = DEBUG_AddLocal( func, 0, offset, 0, 0, symname );
2135 DEBUG_SetLocalSymbolType( local, DEBUG_GetCVType( type ) );
2136
2137 return local;
2138}
2139
2140static int
2141DEBUG_SnarfCodeView( DBG_MODULE *module, LPBYTE root, int offset, int size,
2142 struct codeview_linetab_hdr *linetab )
2143{
2144 struct name_hash *curr_func = NULL;
2145 int i, length;
2146
2147
2148 /*
2149 * Loop over the different types of records and whenever we
2150 * find something we are interested in, record it and move on.
2151 */
2152 for ( i = offset; i < size; i += length )
2153 {
2154 union codeview_symbol *sym = (union codeview_symbol *)(root + i);
2155 length = sym->generic.len + 2;
2156
2157 switch ( sym->generic.id )
2158 {
2159 /*
2160 * Global and local data symbols. We don't associate these
2161 * with any given source file.
2162 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002163 case S_GDATA:
2164 case S_LDATA:
2165 case S_PUB:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002166 DEBUG_AddCVSymbol( module, sym->data.name, sym->data.namelen,
2167 sym->data.symtype, sym->data.seg,
2168 sym->data.offset, 0,
2169 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2170 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002171 case S_GDATA_32:
2172 case S_LDATA_32:
2173 case S_PUB_32:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002174 DEBUG_AddCVSymbol( module, sym->data32.name, sym->data32.namelen,
2175 sym->data32.symtype, sym->data32.seg,
2176 sym->data32.offset, 0,
2177 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2178 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002179
Ulrich Weigand6011e982000-11-07 20:29:20 +00002180 /*
2181 * Sort of like a global function, but it just points
2182 * to a thunk, which is a stupid name for what amounts to
2183 * a PLT slot in the normal jargon that everyone else uses.
2184 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002185 case S_THUNK:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002186 DEBUG_AddCVSymbol( module, sym->thunk.name, sym->thunk.namelen,
2187 0, sym->thunk.segment,
2188 sym->thunk.offset, sym->thunk.thunk_len,
2189 DV_TARGET, SYM_WIN32 | SYM_FUNC, NULL );
2190 break;
2191
2192 /*
2193 * Global and static functions.
2194 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002195 case S_GPROC:
2196 case S_LPROC:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002197 DEBUG_Normalize( curr_func );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002198
Ulrich Weigand6011e982000-11-07 20:29:20 +00002199 curr_func = DEBUG_AddCVSymbol( module, sym->proc.name, sym->proc.namelen,
2200 sym->proc.proctype, sym->proc.segment,
2201 sym->proc.offset, sym->proc.proc_len,
2202 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002203
Ulrich Weigand6011e982000-11-07 20:29:20 +00002204 DEBUG_SetSymbolBPOff( curr_func, sym->proc.debug_start );
2205 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002206 case S_GPROC_32:
2207 case S_LPROC_32:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002208 DEBUG_Normalize( curr_func );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002209
Ulrich Weigand6011e982000-11-07 20:29:20 +00002210 curr_func = DEBUG_AddCVSymbol( module, sym->proc32.name, sym->proc32.namelen,
2211 sym->proc32.proctype, sym->proc32.segment,
2212 sym->proc32.offset, sym->proc32.proc_len,
2213 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002214
Ulrich Weigand6011e982000-11-07 20:29:20 +00002215 DEBUG_SetSymbolBPOff( curr_func, sym->proc32.debug_start );
2216 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002217
Ulrich Weigand6011e982000-11-07 20:29:20 +00002218
2219 /*
2220 * Function parameters and stack variables.
2221 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002222 case S_BPREL:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002223 DEBUG_AddCVLocal( curr_func, sym->stack.name, sym->stack.namelen,
2224 sym->stack.symtype, sym->stack.offset );
2225 break;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002226 case S_BPREL_32:
Ulrich Weigand6011e982000-11-07 20:29:20 +00002227 DEBUG_AddCVLocal( curr_func, sym->stack32.name, sym->stack32.namelen,
2228 sym->stack32.symtype, sym->stack32.offset );
2229 break;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002230
Ulrich Weigand6011e982000-11-07 20:29:20 +00002231
2232 /*
2233 * These are special, in that they are always followed by an
2234 * additional length-prefixed string which is *not* included
2235 * into the symbol length count. We need to skip it.
2236 */
2237 case S_PROCREF:
2238 case S_DATAREF:
2239 case S_LPROCREF:
2240 {
2241 LPBYTE name = (LPBYTE)sym + length;
2242 length += (*name + 1 + 3) & ~3;
2243 break;
2244 }
2245 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002246 }
2247
Ulrich Weigand6011e982000-11-07 20:29:20 +00002248 DEBUG_Normalize( curr_func );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002249
Ulrich Weigand6011e982000-11-07 20:29:20 +00002250 if ( linetab ) DBG_free(linetab);
2251 return TRUE;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002252}
2253
2254
Ulrich Weigand6011e982000-11-07 20:29:20 +00002255
2256/*========================================================================
2257 * Process PDB file.
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002258 */
Ulrich Weigand8142a161999-12-10 03:43:53 +00002259
2260#pragma pack(1)
2261typedef struct _PDB_FILE
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002262{
Ulrich Weigand8142a161999-12-10 03:43:53 +00002263 DWORD size;
2264 DWORD unknown;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002265
Ulrich Weigand8142a161999-12-10 03:43:53 +00002266} PDB_FILE, *PPDB_FILE;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002267
Ulrich Weigand8142a161999-12-10 03:43:53 +00002268typedef struct _PDB_HEADER
2269{
2270 CHAR ident[40];
2271 DWORD signature;
2272 DWORD blocksize;
2273 WORD freelist;
2274 WORD total_alloc;
2275 PDB_FILE toc;
2276 WORD toc_block[ 1 ];
2277
2278} PDB_HEADER, *PPDB_HEADER;
2279
2280typedef struct _PDB_TOC
2281{
2282 DWORD nFiles;
2283 PDB_FILE file[ 1 ];
2284
2285} PDB_TOC, *PPDB_TOC;
2286
2287typedef struct _PDB_ROOT
2288{
2289 DWORD version;
2290 DWORD TimeDateStamp;
2291 DWORD unknown;
2292 DWORD cbNames;
2293 CHAR names[ 1 ];
2294
2295} PDB_ROOT, *PPDB_ROOT;
2296
2297typedef struct _PDB_TYPES_OLD
2298{
2299 DWORD version;
2300 WORD first_index;
2301 WORD last_index;
2302 DWORD type_size;
2303 WORD file;
2304 WORD pad;
2305
2306} PDB_TYPES_OLD, *PPDB_TYPES_OLD;
2307
2308typedef struct _PDB_TYPES
2309{
2310 DWORD version;
2311 DWORD type_offset;
2312 DWORD first_index;
2313 DWORD last_index;
2314 DWORD type_size;
2315 WORD file;
2316 WORD pad;
2317 DWORD hash_size;
2318 DWORD hash_base;
2319 DWORD hash_offset;
2320 DWORD hash_len;
2321 DWORD search_offset;
2322 DWORD search_len;
2323 DWORD unknown_offset;
2324 DWORD unknown_len;
2325
2326} PDB_TYPES, *PPDB_TYPES;
2327
2328typedef struct _PDB_SYMBOL_RANGE
2329{
2330 WORD segment;
2331 WORD pad1;
2332 DWORD offset;
2333 DWORD size;
2334 DWORD characteristics;
2335 WORD index;
2336 WORD pad2;
2337
2338} PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
2339
2340typedef struct _PDB_SYMBOL_RANGE_EX
2341{
2342 WORD segment;
2343 WORD pad1;
2344 DWORD offset;
2345 DWORD size;
2346 DWORD characteristics;
2347 WORD index;
2348 WORD pad2;
2349 DWORD timestamp;
2350 DWORD unknown;
2351
2352} PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
2353
2354typedef struct _PDB_SYMBOL_FILE
2355{
2356 DWORD unknown1;
2357 PDB_SYMBOL_RANGE range;
2358 WORD flag;
2359 WORD file;
2360 DWORD symbol_size;
2361 DWORD lineno_size;
2362 DWORD unknown2;
2363 DWORD nSrcFiles;
2364 DWORD attribute;
2365 CHAR filename[ 1 ];
2366
2367} PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
2368
2369typedef struct _PDB_SYMBOL_FILE_EX
2370{
2371 DWORD unknown1;
2372 PDB_SYMBOL_RANGE_EX range;
2373 WORD flag;
2374 WORD file;
2375 DWORD symbol_size;
2376 DWORD lineno_size;
2377 DWORD unknown2;
2378 DWORD nSrcFiles;
2379 DWORD attribute;
2380 DWORD reserved[ 2 ];
2381 CHAR filename[ 1 ];
2382
2383} PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
2384
2385typedef struct _PDB_SYMBOL_SOURCE
2386{
2387 WORD nModules;
2388 WORD nSrcFiles;
2389 WORD table[ 1 ];
2390
2391} PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
2392
2393typedef struct _PDB_SYMBOL_IMPORT
2394{
2395 DWORD unknown1;
2396 DWORD unknown2;
2397 DWORD TimeDateStamp;
2398 DWORD nRequests;
2399 CHAR filename[ 1 ];
2400
2401} PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
2402
2403typedef struct _PDB_SYMBOLS_OLD
2404{
2405 WORD hash1_file;
2406 WORD hash2_file;
2407 WORD gsym_file;
2408 WORD pad;
2409 DWORD module_size;
2410 DWORD offset_size;
2411 DWORD hash_size;
2412 DWORD srcmodule_size;
2413
2414} PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
2415
2416typedef struct _PDB_SYMBOLS
2417{
2418 DWORD signature;
2419 DWORD version;
Ulrich Weigand90394212000-10-22 23:48:06 +00002420 DWORD unknown;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002421 DWORD hash1_file;
2422 DWORD hash2_file;
2423 DWORD gsym_file;
2424 DWORD module_size;
2425 DWORD offset_size;
2426 DWORD hash_size;
2427 DWORD srcmodule_size;
2428 DWORD pdbimport_size;
2429 DWORD resvd[ 5 ];
2430
2431} PDB_SYMBOLS, *PPDB_SYMBOLS;
2432#pragma pack()
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002433
2434
Ulrich Weigand8142a161999-12-10 03:43:53 +00002435static void *pdb_read( LPBYTE image, WORD *block_list, int size )
2436{
2437 PPDB_HEADER pdb = (PPDB_HEADER)image;
2438 int i, nBlocks;
2439 LPBYTE buffer;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002440
Ulrich Weigand8142a161999-12-10 03:43:53 +00002441 if ( !size ) return NULL;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002442
Ulrich Weigand8142a161999-12-10 03:43:53 +00002443 nBlocks = (size + pdb->blocksize-1) / pdb->blocksize;
2444 buffer = DBG_alloc( nBlocks * pdb->blocksize );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002445
Ulrich Weigand8142a161999-12-10 03:43:53 +00002446 for ( i = 0; i < nBlocks; i++ )
2447 memcpy( buffer + i*pdb->blocksize,
2448 image + block_list[i]*pdb->blocksize, pdb->blocksize );
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002449
Ulrich Weigand8142a161999-12-10 03:43:53 +00002450 return buffer;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002451}
2452
Joerg Mayerd18140c2000-12-26 01:28:51 +00002453static void *pdb_read_file( LPBYTE image, PPDB_TOC toc, DWORD fileNr )
Ulrich Weigand8142a161999-12-10 03:43:53 +00002454{
2455 PPDB_HEADER pdb = (PPDB_HEADER)image;
2456 WORD *block_list;
Joerg Mayerd18140c2000-12-26 01:28:51 +00002457 DWORD i;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002458
2459 if ( !toc || fileNr >= toc->nFiles )
2460 return NULL;
2461
2462 block_list = (WORD *) &toc->file[ toc->nFiles ];
2463 for ( i = 0; i < fileNr; i++ )
2464 block_list += (toc->file[i].size + pdb->blocksize-1) / pdb->blocksize;
2465
2466 return pdb_read( image, block_list, toc->file[fileNr].size );
2467}
2468
2469static void pdb_free( void *buffer )
2470{
2471 DBG_free( buffer );
2472}
2473
2474static void pdb_convert_types_header( PDB_TYPES *types, char *image )
2475{
2476 memset( types, 0, sizeof(PDB_TYPES) );
2477 if ( !image ) return;
2478
2479 if ( *(DWORD *)image < 19960000 ) /* FIXME: correct version? */
2480 {
2481 /* Old version of the types record header */
2482 PDB_TYPES_OLD *old = (PDB_TYPES_OLD *)image;
2483 types->version = old->version;
2484 types->type_offset = sizeof(PDB_TYPES_OLD);
2485 types->type_size = old->type_size;
2486 types->first_index = old->first_index;
2487 types->last_index = old->last_index;
2488 types->file = old->file;
2489 }
2490 else
2491 {
2492 /* New version of the types record header */
2493 *types = *(PDB_TYPES *)image;
2494 }
2495}
2496
2497static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols,
2498 int *header_size, char *image )
2499{
2500 memset( symbols, 0, sizeof(PDB_SYMBOLS) );
2501 if ( !image ) return;
2502
2503 if ( *(DWORD *)image != 0xffffffff )
2504 {
2505 /* Old version of the symbols record header */
2506 PDB_SYMBOLS_OLD *old = (PDB_SYMBOLS_OLD *)image;
2507 symbols->version = 0;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002508 symbols->module_size = old->module_size;
2509 symbols->offset_size = old->offset_size;
2510 symbols->hash_size = old->hash_size;
2511 symbols->srcmodule_size = old->srcmodule_size;
2512 symbols->pdbimport_size = 0;
2513 symbols->hash1_file = old->hash1_file;
2514 symbols->hash2_file = old->hash2_file;
2515 symbols->gsym_file = old->gsym_file;
2516
2517 *header_size = sizeof(PDB_SYMBOLS_OLD);
2518 }
2519 else
2520 {
2521 /* New version of the symbols record header */
2522 *symbols = *(PDB_SYMBOLS *)image;
2523
2524 *header_size = sizeof(PDB_SYMBOLS);
2525 }
2526}
2527
Eric Poueche9392062000-11-15 22:16:26 +00002528static enum DbgInfoLoad DEBUG_ProcessPDBFile( DBG_MODULE *module,
2529 const char *filename, DWORD timestamp )
Ulrich Weigand8142a161999-12-10 03:43:53 +00002530{
Eric Poueche9392062000-11-15 22:16:26 +00002531 enum DbgInfoLoad dil = DIL_ERROR;
Eric Poueche5efa0c2000-04-13 19:31:58 +00002532 HANDLE hFile, hMap;
2533 char *image = NULL;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002534 PDB_HEADER *pdb = NULL;
2535 PDB_TOC *toc = NULL;
2536 PDB_ROOT *root = NULL;
2537 char *types_image = NULL;
2538 char *symbols_image = NULL;
2539 PDB_TYPES types;
2540 PDB_SYMBOLS symbols;
2541 int header_size = 0;
2542 char *modimage, *file;
2543
Ulrich Weigand6011e982000-11-07 20:29:20 +00002544 DEBUG_Printf( DBG_CHN_TRACE, "Processing PDB file %s\n", filename );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002545
2546 /*
Eric Poueche5efa0c2000-04-13 19:31:58 +00002547 * Open and map() .PDB file
Ulrich Weigand8142a161999-12-10 03:43:53 +00002548 */
Ulrich Weigand6011e982000-11-07 20:29:20 +00002549 image = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2550 if ( !image )
2551 {
2552 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .PDB file %s\n", filename );
2553 goto leave;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002554 }
2555
2556 /*
2557 * Read in TOC and well-known files
2558 */
2559
2560 pdb = (PPDB_HEADER)image;
2561 toc = pdb_read( image, pdb->toc_block, pdb->toc.size );
2562 root = pdb_read_file( image, toc, 1 );
2563 types_image = pdb_read_file( image, toc, 2 );
2564 symbols_image = pdb_read_file( image, toc, 3 );
2565
2566 pdb_convert_types_header( &types, types_image );
2567 pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
2568
2569 /*
2570 * Check for unknown versions
2571 */
2572
2573 switch ( root->version )
2574 {
2575 case 19950623: /* VC 4.0 */
2576 case 19950814:
2577 case 19960307: /* VC 5.0 */
2578 case 19970604: /* VC 6.0 */
2579 break;
2580 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +00002581 DEBUG_Printf( DBG_CHN_ERR, "-Unknown root block version %ld\n", root->version );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002582 }
2583
2584 switch ( types.version )
2585 {
2586 case 19950410: /* VC 4.0 */
2587 case 19951122:
2588 case 19961031: /* VC 5.0 / 6.0 */
2589 break;
2590 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +00002591 DEBUG_Printf( DBG_CHN_ERR, "-Unknown type info version %ld\n", types.version );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002592 }
2593
2594 switch ( symbols.version )
2595 {
2596 case 0: /* VC 4.0 */
2597 case 19960307: /* VC 5.0 */
2598 case 19970606: /* VC 6.0 */
2599 break;
2600 default:
Eric Poueche5efa0c2000-04-13 19:31:58 +00002601 DEBUG_Printf( DBG_CHN_ERR, "-Unknown symbol info version %ld\n", symbols.version );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002602 }
2603
2604
2605 /*
2606 * Check .PDB time stamp
2607 */
2608
Ulrich Weigand6011e982000-11-07 20:29:20 +00002609 if ( root->TimeDateStamp != timestamp )
Ulrich Weigand8142a161999-12-10 03:43:53 +00002610 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002611 DEBUG_Printf( DBG_CHN_ERR, "-Wrong time stamp of .PDB file %s (0x%08lx, 0x%08lx)\n",
2612 filename, root->TimeDateStamp, timestamp );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002613 }
2614
2615 /*
2616 * Read type table
2617 */
2618
2619 DEBUG_ParseTypeTable( types_image + types.type_offset, types.type_size );
2620
2621 /*
2622 * Read type-server .PDB imports
2623 */
2624
2625 if ( symbols.pdbimport_size )
2626 {
2627 /* FIXME */
Eric Poueche5efa0c2000-04-13 19:31:58 +00002628 DEBUG_Printf(DBG_CHN_ERR, "-Type server .PDB imports ignored!\n" );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002629 }
2630
2631 /*
2632 * Read global symbol table
2633 */
2634
2635 modimage = pdb_read_file( image, toc, symbols.gsym_file );
2636 if ( modimage )
2637 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002638 DEBUG_SnarfCodeView( module, modimage, 0,
Ulrich Weigand8142a161999-12-10 03:43:53 +00002639 toc->file[symbols.gsym_file].size, NULL );
2640 pdb_free( modimage );
2641 }
2642
2643 /*
2644 * Read per-module symbol / linenumber tables
2645 */
2646
2647 file = symbols_image + header_size;
2648 while ( file - symbols_image < header_size + symbols.module_size )
2649 {
2650 int file_nr, file_index, symbol_size, lineno_size;
2651 char *file_name;
2652
Ulrich Weigand90394212000-10-22 23:48:06 +00002653 if ( symbols.version < 19970000 )
Ulrich Weigand8142a161999-12-10 03:43:53 +00002654 {
2655 PDB_SYMBOL_FILE *sym_file = (PDB_SYMBOL_FILE *) file;
2656 file_nr = sym_file->file;
2657 file_name = sym_file->filename;
2658 file_index = sym_file->range.index;
2659 symbol_size = sym_file->symbol_size;
2660 lineno_size = sym_file->lineno_size;
2661 }
2662 else
2663 {
2664 PDB_SYMBOL_FILE_EX *sym_file = (PDB_SYMBOL_FILE_EX *) file;
2665 file_nr = sym_file->file;
2666 file_name = sym_file->filename;
2667 file_index = sym_file->range.index;
2668 symbol_size = sym_file->symbol_size;
2669 lineno_size = sym_file->lineno_size;
2670 }
2671
2672 modimage = pdb_read_file( image, toc, file_nr );
2673 if ( modimage )
2674 {
2675 struct codeview_linetab_hdr *linetab = NULL;
2676
2677 if ( lineno_size )
2678 linetab = DEBUG_SnarfLinetab( modimage + symbol_size, lineno_size );
2679
2680 if ( symbol_size )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002681 DEBUG_SnarfCodeView( module, modimage, sizeof(DWORD),
2682 symbol_size, linetab );
Ulrich Weigand8142a161999-12-10 03:43:53 +00002683
2684 pdb_free( modimage );
2685 }
2686
2687 file_name += strlen(file_name) + 1;
2688 file = (char *)( (DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3 );
2689 }
2690
Eric Poueche9392062000-11-15 22:16:26 +00002691 dil = DIL_LOADED;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002692
2693 leave:
2694
2695 /*
2696 * Cleanup
2697 */
2698
Ulrich Weigand164bac92000-04-25 19:53:49 +00002699 DEBUG_ClearTypeTable();
2700
Ulrich Weigand8142a161999-12-10 03:43:53 +00002701 if ( symbols_image ) pdb_free( symbols_image );
2702 if ( types_image ) pdb_free( types_image );
2703 if ( root ) pdb_free( root );
2704 if ( toc ) pdb_free( toc );
2705
Eric Poueche5efa0c2000-04-13 19:31:58 +00002706 DEBUG_UnmapDebugInfoFile(hFile, hMap, image);
Ulrich Weigand8142a161999-12-10 03:43:53 +00002707
Eric Poueche9392062000-11-15 22:16:26 +00002708 return dil;
Ulrich Weigand8142a161999-12-10 03:43:53 +00002709}
2710
2711
Ulrich Weigand6011e982000-11-07 20:29:20 +00002712
2713
2714/*========================================================================
2715 * Process CodeView debug information.
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002716 */
Ulrich Weigand6011e982000-11-07 20:29:20 +00002717
2718#define CODEVIEW_NB09_SIG ( 'N' | ('B' << 8) | ('0' << 16) | ('9' << 24) )
2719#define CODEVIEW_NB10_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('0' << 24) )
2720#define CODEVIEW_NB11_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('1' << 24) )
2721
2722typedef struct _CODEVIEW_HEADER
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002723{
Ulrich Weigand6011e982000-11-07 20:29:20 +00002724 DWORD dwSignature;
2725 DWORD lfoDirectory;
2726
2727} CODEVIEW_HEADER, *PCODEVIEW_HEADER;
2728
2729typedef struct _CODEVIEW_PDB_DATA
2730{
2731 DWORD timestamp;
2732 DWORD unknown;
2733 CHAR name[ 1 ];
2734
2735} CODEVIEW_PDB_DATA, *PCODEVIEW_PDB_DATA;
2736
2737typedef struct _CV_DIRECTORY_HEADER
2738{
2739 WORD cbDirHeader;
2740 WORD cbDirEntry;
2741 DWORD cDir;
2742 DWORD lfoNextDir;
2743 DWORD flags;
2744
2745} CV_DIRECTORY_HEADER, *PCV_DIRECTORY_HEADER;
2746
2747typedef struct _CV_DIRECTORY_ENTRY
2748{
2749 WORD subsection;
2750 WORD iMod;
2751 DWORD lfo;
2752 DWORD cb;
2753
2754} CV_DIRECTORY_ENTRY, *PCV_DIRECTORY_ENTRY;
Sergey Turchanovd72e2de1999-01-24 09:46:21 +00002755
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002756
Ulrich Weigand6011e982000-11-07 20:29:20 +00002757#define sstAlignSym 0x125
2758#define sstSrcModule 0x127
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002759
Ulrich Weigand6011e982000-11-07 20:29:20 +00002760
Eric Poueche9392062000-11-15 22:16:26 +00002761static enum DbgInfoLoad DEBUG_ProcessCodeView( DBG_MODULE *module, LPBYTE root )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002762{
2763 PCODEVIEW_HEADER cv = (PCODEVIEW_HEADER)root;
Eric Poueche9392062000-11-15 22:16:26 +00002764 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002765
2766 switch ( cv->dwSignature )
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002767 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002768 case CODEVIEW_NB09_SIG:
2769 case CODEVIEW_NB11_SIG:
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002770 {
Ulrich Weigand6011e982000-11-07 20:29:20 +00002771 PCV_DIRECTORY_HEADER hdr = (PCV_DIRECTORY_HEADER)(root + cv->lfoDirectory);
2772 PCV_DIRECTORY_ENTRY ent, prev, next;
Joerg Mayerd18140c2000-12-26 01:28:51 +00002773 unsigned int i;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002774
Ulrich Weigand6011e982000-11-07 20:29:20 +00002775 ent = (PCV_DIRECTORY_ENTRY)((LPBYTE)hdr + hdr->cbDirHeader);
2776 for ( i = 0; i < hdr->cDir; i++, ent = next )
2777 {
2778 next = (i == hdr->cDir-1)? NULL :
2779 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent + hdr->cbDirEntry);
2780 prev = (i == 0)? NULL :
2781 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent - hdr->cbDirEntry);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002782
Ulrich Weigand6011e982000-11-07 20:29:20 +00002783 if ( ent->subsection == sstAlignSym )
2784 {
2785 /*
2786 * Check the next and previous entry. If either is a
2787 * sstSrcModule, it contains the line number info for
2788 * this file.
2789 *
2790 * FIXME: This is not a general solution!
2791 */
2792 struct codeview_linetab_hdr *linetab = NULL;
Juergen Schmied7493ead2000-10-29 18:03:41 +00002793
Ulrich Weigand6011e982000-11-07 20:29:20 +00002794 if ( next && next->iMod == ent->iMod
2795 && next->subsection == sstSrcModule )
2796 linetab = DEBUG_SnarfLinetab( root + next->lfo, next->cb );
Juergen Schmied7493ead2000-10-29 18:03:41 +00002797
Ulrich Weigand6011e982000-11-07 20:29:20 +00002798 if ( prev && prev->iMod == ent->iMod
2799 && prev->subsection == sstSrcModule )
2800 linetab = DEBUG_SnarfLinetab( root + prev->lfo, prev->cb );
2801
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002802
Ulrich Weigand6011e982000-11-07 20:29:20 +00002803 DEBUG_SnarfCodeView( module, root + ent->lfo, sizeof(DWORD),
2804 ent->cb, linetab );
2805 }
2806 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002807
Eric Poueche9392062000-11-15 22:16:26 +00002808 dil = DIL_LOADED;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002809 break;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002810 }
Ulrich Weigand6011e982000-11-07 20:29:20 +00002811
2812 case CODEVIEW_NB10_SIG:
2813 {
2814 PCODEVIEW_PDB_DATA pdb = (PCODEVIEW_PDB_DATA)(cv + 1);
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002815
Eric Poueche9392062000-11-15 22:16:26 +00002816 dil = DEBUG_ProcessPDBFile( module, pdb->name, pdb->timestamp );
Ulrich Weigand6011e982000-11-07 20:29:20 +00002817 break;
2818 }
2819
2820 default:
2821 DEBUG_Printf( DBG_CHN_ERR, "Unknown CODEVIEW signature %08lX in module %s\n",
2822 cv->dwSignature, module->module_name );
2823 break;
2824 }
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002825
Eric Poueche9392062000-11-15 22:16:26 +00002826 return dil;
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002827}
2828
Ulrich Weigand6011e982000-11-07 20:29:20 +00002829
2830/*========================================================================
2831 * Process debug directory.
2832 */
Eric Poueche9392062000-11-15 22:16:26 +00002833static enum DbgInfoLoad DEBUG_ProcessDebugDirectory( DBG_MODULE *module,
2834 LPBYTE file_map,
2835 PIMAGE_DEBUG_DIRECTORY dbg,
2836 int nDbg )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00002837{
Eric Poueche9392062000-11-15 22:16:26 +00002838 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002839 int i;
2840
Ulrich Weigand6011e982000-11-07 20:29:20 +00002841 /* First, watch out for OMAP data */
2842 for ( i = 0; i < nDbg; i++ )
2843 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC )
2844 {
Eric Poueche9392062000-11-15 22:16:26 +00002845 module->msc_info->nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
2846 module->msc_info->omapp = (OMAP_DATA *)(file_map + dbg[i].PointerToRawData);
Ulrich Weigand6011e982000-11-07 20:29:20 +00002847 break;
2848 }
2849
2850
2851 /* Now, try to parse CodeView debug info */
Eric Poueche9392062000-11-15 22:16:26 +00002852 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002853 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW )
Eric Poueche9392062000-11-15 22:16:26 +00002854 dil = DEBUG_ProcessCodeView( module, file_map + dbg[i].PointerToRawData );
Ulrich Weigand6011e982000-11-07 20:29:20 +00002855
2856
2857 /* If not found, try to parse COFF debug info */
Eric Poueche9392062000-11-15 22:16:26 +00002858 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002859 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_COFF )
Eric Poueche9392062000-11-15 22:16:26 +00002860 dil = DEBUG_ProcessCoff( module, file_map + dbg[i].PointerToRawData );
Ulrich Weigand6011e982000-11-07 20:29:20 +00002861
Eric Poueche9392062000-11-15 22:16:26 +00002862#if 0
2863 /* FIXME: this should be supported... this is the debug information for
2864 * functions compiled without a frame pointer (FPO = frame pointer omission)
2865 * the associated data helps finding out the relevant information
2866 */
2867 for ( i = 0; i < nDbg; i++ )
2868 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_FPO )
2869 DEBUG_Printf(DBG_CHN_MESG, "This guy has FPO information\n");
Ulrich Weigand6011e982000-11-07 20:29:20 +00002870
Eric Poueche9392062000-11-15 22:16:26 +00002871#define FRAME_FPO 0
2872#define FRAME_TRAP 1
2873#define FRAME_TSS 2
2874
2875typedef struct _FPO_DATA {
2876 DWORD ulOffStart; /* offset 1st byte of function code */
2877 DWORD cbProcSize; /* # bytes in function */
2878 DWORD cdwLocals; /* # bytes in locals/4 */
2879 WORD cdwParams; /* # bytes in params/4 */
2880
2881 WORD cbProlog : 8; /* # bytes in prolog */
2882 WORD cbRegs : 3; /* # regs saved */
2883 WORD fHasSEH : 1; /* TRUE if SEH in func */
2884 WORD fUseBP : 1; /* TRUE if EBP has been allocated */
2885 WORD reserved : 1; /* reserved for future use */
2886 WORD cbFrame : 2; /* frame type */
2887} FPO_DATA;
2888#endif
2889
2890 return dil;
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00002891}
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002892
Alexandre Julliardc6c09441997-01-12 18:32:19 +00002893
Ulrich Weigand6011e982000-11-07 20:29:20 +00002894/*========================================================================
2895 * Process DBG file.
2896 */
Eric Poueche9392062000-11-15 22:16:26 +00002897static enum DbgInfoLoad DEBUG_ProcessDBGFile( DBG_MODULE *module,
2898 const char *filename, DWORD timestamp )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002899{
Eric Poueche9392062000-11-15 22:16:26 +00002900 enum DbgInfoLoad dil = DIL_ERROR;
Marcus Meissnerbb72c3d2001-08-03 18:11:00 +00002901 HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002902 LPBYTE file_map = NULL;
2903 PIMAGE_SEPARATE_DEBUG_HEADER hdr;
2904 PIMAGE_DEBUG_DIRECTORY dbg;
2905 int nDbg;
2906
2907
2908 DEBUG_Printf( DBG_CHN_TRACE, "Processing DBG file %s\n", filename );
2909
2910 file_map = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2911 if ( !file_map )
2912 {
2913 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .DBG file %s\n", filename );
2914 goto leave;
2915 }
2916
2917 hdr = (PIMAGE_SEPARATE_DEBUG_HEADER) file_map;
2918
2919 if ( hdr->TimeDateStamp != timestamp )
2920 {
2921 DEBUG_Printf( DBG_CHN_ERR, "Warning - %s has incorrect internal timestamp\n",
2922 filename );
2923 /*
2924 * Well, sometimes this happens to DBG files which ARE REALLY the right .DBG
2925 * files but nonetheless this check fails. Anyway, WINDBG (debugger for
2926 * Windows by Microsoft) loads debug symbols which have incorrect timestamps.
2927 */
2928 }
2929
2930
2931 dbg = (PIMAGE_DEBUG_DIRECTORY) ( file_map + sizeof(*hdr)
2932 + hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)
2933 + hdr->ExportedNamesSize );
2934
2935 nDbg = hdr->DebugDirectorySize / sizeof(*dbg);
2936
Eric Poueche9392062000-11-15 22:16:26 +00002937 dil = DEBUG_ProcessDebugDirectory( module, file_map, dbg, nDbg );
Ulrich Weigand6011e982000-11-07 20:29:20 +00002938
2939
2940 leave:
2941 DEBUG_UnmapDebugInfoFile( hFile, hMap, file_map );
Eric Poueche9392062000-11-15 22:16:26 +00002942 return dil;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002943}
2944
2945
2946/*========================================================================
2947 * Process MSC debug information in PE file.
2948 */
Eric Poueche9392062000-11-15 22:16:26 +00002949enum DbgInfoLoad DEBUG_RegisterMSCDebugInfo( DBG_MODULE *module, HANDLE hFile,
2950 void *_nth, unsigned long nth_ofs )
Ulrich Weigand6011e982000-11-07 20:29:20 +00002951{
Eric Poueche9392062000-11-15 22:16:26 +00002952 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002953 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
2954 PIMAGE_DATA_DIRECTORY dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
2955 PIMAGE_DEBUG_DIRECTORY dbg = NULL;
2956 int nDbg;
2957 MSC_DBG_INFO extra_info = { 0, NULL, 0, NULL };
2958 HANDLE hMap = 0;
2959 LPBYTE file_map = NULL;
2960
2961
2962 /* Read in section data */
2963
Eric Poueche9392062000-11-15 22:16:26 +00002964 module->msc_info = &extra_info;
Ulrich Weigand6011e982000-11-07 20:29:20 +00002965 extra_info.nsect = nth->FileHeader.NumberOfSections;
2966 extra_info.sectp = DBG_alloc( extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) );
2967 if ( !extra_info.sectp )
2968 goto leave;
2969
2970 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr +
2971 nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
2972 nth->FileHeader.SizeOfOptionalHeader,
2973 extra_info.sectp,
2974 extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) ) )
2975 goto leave;
2976
Ulrich Weigand6011e982000-11-07 20:29:20 +00002977 /* Read in debug directory */
2978
2979 nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
2980 if ( !nDbg )
2981 goto leave;
2982
2983 dbg = (PIMAGE_DEBUG_DIRECTORY) DBG_alloc( nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) );
2984 if ( !dbg )
2985 goto leave;
2986
2987 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr + dir->VirtualAddress,
2988 dbg, nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) ) )
2989 goto leave;
2990
2991
2992 /* Map in PE file */
2993 file_map = DEBUG_MapDebugInfoFile( NULL, 0, 0, &hFile, &hMap );
2994 if ( !file_map )
2995 goto leave;
2996
2997
2998 /* Parse debug directory */
2999
3000 if ( nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED )
3001 {
3002 /* Debug info is stripped to .DBG file */
3003
3004 PIMAGE_DEBUG_MISC misc = (PIMAGE_DEBUG_MISC)(file_map + dbg->PointerToRawData);
3005
3006 if ( nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC
3007 || misc->DataType != IMAGE_DEBUG_MISC_EXENAME )
3008 {
3009 DEBUG_Printf( DBG_CHN_ERR, "-Debug info stripped, but no .DBG file in module %s\n",
3010 module->module_name );
3011 goto leave;
3012 }
3013
Eric Poueche9392062000-11-15 22:16:26 +00003014 dil = DEBUG_ProcessDBGFile( module, misc->Data, nth->FileHeader.TimeDateStamp );
Ulrich Weigand6011e982000-11-07 20:29:20 +00003015 }
3016 else
3017 {
3018 /* Debug info is embedded into PE module */
3019
Eric Poueche9392062000-11-15 22:16:26 +00003020 dil = DEBUG_ProcessDebugDirectory( module, file_map, dbg, nDbg );
Ulrich Weigand6011e982000-11-07 20:29:20 +00003021 }
3022
3023
3024 leave:
Eric Poueche9392062000-11-15 22:16:26 +00003025 module->msc_info = NULL;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003026
3027 DEBUG_UnmapDebugInfoFile( 0, hMap, file_map );
3028 if ( extra_info.sectp ) DBG_free( extra_info.sectp );
3029 if ( dbg ) DBG_free( dbg );
Eric Poueche9392062000-11-15 22:16:26 +00003030 return dil;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003031}
3032
3033
3034/*========================================================================
3035 * look for stabs information in PE header (it's how mingw compiler provides its
Francois Gouget588ff372001-08-21 17:07:17 +00003036 * debugging information), and also wine PE <-> ELF linking through .wsolnk sections
Ulrich Weigand6011e982000-11-07 20:29:20 +00003037 */
Eric Poueche9392062000-11-15 22:16:26 +00003038enum DbgInfoLoad DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile,
3039 void* _nth, unsigned long nth_ofs)
Ulrich Weigand6011e982000-11-07 20:29:20 +00003040{
3041 IMAGE_SECTION_HEADER pe_seg;
3042 unsigned long pe_seg_ofs;
3043 int i, stabsize = 0, stabstrsize = 0;
3044 unsigned int stabs = 0, stabstr = 0;
3045 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
Eric Poueche9392062000-11-15 22:16:26 +00003046 enum DbgInfoLoad dil = DIL_ERROR;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003047
3048 pe_seg_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
3049 nth->FileHeader.SizeOfOptionalHeader;
3050
3051 for (i = 0; i < nth->FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg)) {
3052 if (!DEBUG_READ_MEM_VERBOSE((void*)((char *)module->load_addr + pe_seg_ofs),
3053 &pe_seg, sizeof(pe_seg)))
3054 continue;
3055
3056 if (!strcasecmp(pe_seg.Name, ".stab")) {
3057 stabs = pe_seg.VirtualAddress;
3058 stabsize = pe_seg.SizeOfRawData;
3059 } else if (!strncasecmp(pe_seg.Name, ".stabstr", 8)) {
3060 stabstr = pe_seg.VirtualAddress;
3061 stabstrsize = pe_seg.SizeOfRawData;
3062 }
3063 }
3064
3065 if (stabstrsize && stabsize) {
3066 char* s1 = DBG_alloc(stabsize+stabstrsize);
3067
3068 if (s1) {
3069 if (DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabs, s1, stabsize) &&
3070 DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabstr,
3071 s1 + stabsize, stabstrsize)) {
Eric Poueche9392062000-11-15 22:16:26 +00003072 dil = DEBUG_ParseStabs(s1, 0, 0, stabsize, stabsize, stabstrsize);
Ulrich Weigand6011e982000-11-07 20:29:20 +00003073 } else {
3074 DEBUG_Printf(DBG_CHN_MESG, "couldn't read data block\n");
3075 }
3076 DBG_free(s1);
3077 } else {
3078 DEBUG_Printf(DBG_CHN_MESG, "couldn't alloc %d bytes\n",
3079 stabsize + stabstrsize);
3080 }
Eric Poueche9392062000-11-15 22:16:26 +00003081 } else {
3082 dil = DIL_NOINFO;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003083 }
Eric Poueche9392062000-11-15 22:16:26 +00003084 return dil;
Ulrich Weigand6011e982000-11-07 20:29:20 +00003085}
Alexandre Julliardc6c09441997-01-12 18:32:19 +00003086