📄 msc.c
字号:
/*
* File msc.c - read VC++ debug information from COFF and eventually
* from PDB files.
*
* Copyright (C) 1996, Eric Youngdale.
* Copyright (C) 1999-2000, Ulrich Weigand.
* Copyright (C) 2004, Eric Pouech.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Note - this handles reading debug information for 32 bit applications
* that run under Windows-NT for example. I doubt that this would work well
* for 16 bit applications, but I don't think it really matters since the
* file format is different, and we should never get in here in such cases.
*
* TODO:
* Get 16 bit CV stuff working.
* Add symbol size to internal symbol table.
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
#endif
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include <pseh/pseh.h>
#include "wine/debug.h"
#include "dbghelp_private.h"
#include "mscvpdb.h"
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_msc);
#define MAX_PATHNAME_LEN 1024
/*========================================================================
* Debug file access helper routines
*/
static _SEH_FILTER(page_fault)
{
if (_SEH_GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
return _SEH_EXECUTE_HANDLER;
return _SEH_CONTINUE_SEARCH;
}
static void dump(const void* ptr, unsigned len)
{
int i, j;
BYTE msg[128];
const char* hexof = "0123456789abcdef";
const BYTE* x = (const BYTE*)ptr;
for (i = 0; i < len; i += 16)
{
sprintf(msg, "%08x: ", i);
memset(msg + 10, ' ', 3 * 16 + 1 + 16);
for (j = 0; j < min(16, len - i); j++)
{
msg[10 + 3 * j + 0] = hexof[x[i + j] >> 4];
msg[10 + 3 * j + 1] = hexof[x[i + j] & 15];
msg[10 + 3 * j + 2] = ' ';
msg[10 + 3 * 16 + 1 + j] = (x[i + j] >= 0x20 && x[i + j] < 0x7f) ?
x[i + j] : '.';
}
msg[10 + 3 * 16] = ' ';
msg[10 + 3 * 16 + 1 + 16] = '\0';
FIXME("%s\n", msg);
}
}
/*========================================================================
* Process CodeView type information.
*/
#define MAX_BUILTIN_TYPES 0x0480
#define FIRST_DEFINABLE_TYPE 0x1000
static struct symt* cv_basic_types[MAX_BUILTIN_TYPES];
#define SymTagCVBitField (SymTagMax + 0x100)
struct codeview_bitfield
{
struct symt symt;
unsigned subtype;
unsigned bitposition;
unsigned bitlength;
};
struct cv_defined_module
{
BOOL allowed;
unsigned int num_defined_types;
struct symt** defined_types;
struct codeview_bitfield* bitfields;
unsigned num_bitfields;
unsigned used_bitfields;
};
/* FIXME: don't make it static */
#define CV_MAX_MODULES 32
static struct cv_defined_module cv_zmodules[CV_MAX_MODULES];
static struct cv_defined_module*cv_current_module;
static void codeview_init_basic_types(struct module* module)
{
/*
* These are the common builtin types that are used by VC++.
*/
cv_basic_types[T_NOTYPE] = NULL;
cv_basic_types[T_ABS] = NULL;
cv_basic_types[T_VOID] = &symt_new_basic(module, btVoid, "void", 0)->symt;
cv_basic_types[T_CHAR] = &symt_new_basic(module, btChar, "char", 1)->symt;
cv_basic_types[T_SHORT] = &symt_new_basic(module, btInt, "short int", 2)->symt;
cv_basic_types[T_LONG] = &symt_new_basic(module, btInt, "long int", 4)->symt;
cv_basic_types[T_QUAD] = &symt_new_basic(module, btInt, "long long int", 8)->symt;
cv_basic_types[T_UCHAR] = &symt_new_basic(module, btUInt, "unsigned char", 1)->symt;
cv_basic_types[T_USHORT] = &symt_new_basic(module, btUInt, "unsigned short", 2)->symt;
cv_basic_types[T_ULONG] = &symt_new_basic(module, btUInt, "unsigned long", 4)->symt;
cv_basic_types[T_UQUAD] = &symt_new_basic(module, btUInt, "unsigned long long", 8)->symt;
cv_basic_types[T_REAL32] = &symt_new_basic(module, btFloat, "float", 4)->symt;
cv_basic_types[T_REAL64] = &symt_new_basic(module, btFloat, "double", 8)->symt;
cv_basic_types[T_RCHAR] = &symt_new_basic(module, btInt, "signed char", 1)->symt;
cv_basic_types[T_WCHAR] = &symt_new_basic(module, btWChar, "wchar_t", 2)->symt;
cv_basic_types[T_INT4] = &symt_new_basic(module, btInt, "INT4", 4)->symt;
cv_basic_types[T_UINT4] = &symt_new_basic(module, btUInt, "UINT4", 4)->symt;
cv_basic_types[T_32PVOID] = &symt_new_pointer(module, cv_basic_types[T_VOID])->symt;
cv_basic_types[T_32PCHAR] = &symt_new_pointer(module, cv_basic_types[T_CHAR])->symt;
cv_basic_types[T_32PSHORT] = &symt_new_pointer(module, cv_basic_types[T_SHORT])->symt;
cv_basic_types[T_32PLONG] = &symt_new_pointer(module, cv_basic_types[T_LONG])->symt;
cv_basic_types[T_32PQUAD] = &symt_new_pointer(module, cv_basic_types[T_QUAD])->symt;
cv_basic_types[T_32PUCHAR] = &symt_new_pointer(module, cv_basic_types[T_UCHAR])->symt;
cv_basic_types[T_32PUSHORT] = &symt_new_pointer(module, cv_basic_types[T_USHORT])->symt;
cv_basic_types[T_32PULONG] = &symt_new_pointer(module, cv_basic_types[T_ULONG])->symt;
cv_basic_types[T_32PUQUAD] = &symt_new_pointer(module, cv_basic_types[T_UQUAD])->symt;
cv_basic_types[T_32PREAL32] = &symt_new_pointer(module, cv_basic_types[T_REAL32])->symt;
cv_basic_types[T_32PREAL64] = &symt_new_pointer(module, cv_basic_types[T_REAL64])->symt;
cv_basic_types[T_32PRCHAR] = &symt_new_pointer(module, cv_basic_types[T_RCHAR])->symt;
cv_basic_types[T_32PWCHAR] = &symt_new_pointer(module, cv_basic_types[T_WCHAR])->symt;
cv_basic_types[T_32PINT4] = &symt_new_pointer(module, cv_basic_types[T_INT4])->symt;
cv_basic_types[T_32PUINT4] = &symt_new_pointer(module, cv_basic_types[T_UINT4])->symt;
}
static int numeric_leaf(int* value, const unsigned short int* leaf)
{
unsigned short int type = *leaf++;
int length = 2;
if (type < LF_NUMERIC)
{
*value = type;
}
else
{
switch (type)
{
case LF_CHAR:
length += 1;
*value = *(const char*)leaf;
break;
case LF_SHORT:
length += 2;
*value = *(const short*)leaf;
break;
case LF_USHORT:
length += 2;
*value = *(const unsigned short*)leaf;
break;
case LF_LONG:
length += 4;
*value = *(const int*)leaf;
break;
case LF_ULONG:
length += 4;
*value = *(const unsigned int*)leaf;
break;
case LF_QUADWORD:
case LF_UQUADWORD:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 8;
*value = 0; /* FIXME */
break;
case LF_REAL32:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 4;
*value = 0; /* FIXME */
break;
case LF_REAL48:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 6;
*value = 0; /* FIXME */
break;
case LF_REAL64:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 8;
*value = 0; /* FIXME */
break;
case LF_REAL80:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 10;
*value = 0; /* FIXME */
break;
case LF_REAL128:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 16;
*value = 0; /* FIXME */
break;
case LF_COMPLEX32:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 4;
*value = 0; /* FIXME */
break;
case LF_COMPLEX64:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 8;
*value = 0; /* FIXME */
break;
case LF_COMPLEX80:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 10;
*value = 0; /* FIXME */
break;
case LF_COMPLEX128:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 16;
*value = 0; /* FIXME */
break;
case LF_VARSTRING:
FIXME("Unsupported numeric leaf type %04x\n", type);
length += 2 + *leaf;
*value = 0; /* FIXME */
break;
default:
FIXME("Unknown numeric leaf type %04x\n", type);
*value = 0;
break;
}
}
return length;
}
/* convert a pascal string (as stored in debug information) into
* a C string (null terminated).
*/
static const char* terminate_string(const struct p_string* p_name)
{
static char symname[256];
memcpy(symname, p_name->name, p_name->namelen);
symname[p_name->namelen] = '\0';
return (!*symname || strcmp(symname, "__unnamed") == 0) ? NULL : symname;
}
static struct symt* codeview_get_type(unsigned int typeno, BOOL allow_special)
{
struct symt* symt = NULL;
/*
* Convert Codeview type numbers into something we can grok internally.
* Numbers < FIRST_DEFINABLE_TYPE are all fixed builtin types.
* Numbers from FIRST_DEFINABLE_TYPE and up are all user defined (structs, etc).
*/
if (typeno < FIRST_DEFINABLE_TYPE)
{
if (typeno < MAX_BUILTIN_TYPES)
symt = cv_basic_types[typeno];
}
else
{
unsigned mod_index = typeno >> 24;
unsigned mod_typeno = typeno & 0x00FFFFFF;
struct cv_defined_module* mod;
mod = (mod_index == 0) ? cv_current_module : &cv_zmodules[mod_index];
if (mod_index >= CV_MAX_MODULES || !mod->allowed)
FIXME("Module of index %d isn't loaded yet (%x)\n", mod_index, typeno);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -