📄 cv.c
字号:
#include "c.h"
#include "cv.h"
typedef struct tagLocal {
char data[50];
short len;
} LocalVariable;
LocalVariable LocalsTable[256];
static ProcList *LastProc;
ProcList *ProceduresList;
static int DebugSymbolPtr = 0;
DataList *DataSymbolsInfo;
static DataList *LastDataSymbolsInfo;
DataList *DataTypesInfo;
static DataList *LastDataTypesInfo;
static int AddToEmittedTypes(Type ty,int cvType);
int AddNewType(char *data,int len,char *name);
int AddArrayType(Type ty,char *name);
int BuildPointerType(int xrefIdx);
static int Typesidx = 0;
static int GetTypeInternal(Type ty,char *name);
void PutInSymbolBuffer(char *data,int len)
{
if (DebugSymbolPtr > 255) return;
if (len < 50) {
memcpy(LocalsTable[DebugSymbolPtr].data,data,len);
LocalsTable[DebugSymbolPtr].len = len;
DebugSymbolPtr++;
}
}
void PutSymbolRecord(int type,char *data,int len,char *name)
{
char tmprec[256];
int i;
for (i=4; i<len+4;i++) {
tmprec[i] = data[i-4];
}
tmprec[i++] = strlen(name);
while (*name) {
tmprec[i++] = *name++;
}
*((unsigned short *)tmprec) = i-2;
*((unsigned short *)(tmprec+2)) = type;
PutInSymbolBuffer(tmprec,i);
}
int BuildFunctionPointerRecord(Type ty,char *name)
{
Type *tp;
int nrOfArgs,len,idx,result;
unsigned short *data;
char tmpbuffer[12],*p;
nrOfArgs = 0;
tp = ty->type->u.f.proto;
if (tp) {
while (*tp) {
nrOfArgs++;
tp++;
}
}
len = 3 + nrOfArgs;
len = len * sizeof(short);
data = (unsigned short *)malloc(len);
data[0] = len-2;
data[1] = LF_ARGLIST;
data[2] = nrOfArgs;
tp = ty->type->u.f.proto;
idx = 3;
if (tp) {
while (*tp) {
data[idx++] = GetTypeInternal(*tp,"");
tp++;
}
}
result = AddNewType((char *)data,len,name);
free(data);
p = tmpbuffer;
*(unsigned short *)p = 10;
p += 2;
*(unsigned short *)p = 0x8; /* Procedure */
p += 2;
*(unsigned short *)p = 116; /* ??? */
p += 2;
*p++ = 0; /* no special call flags */
*p++ = 0; /* reserved */
*(unsigned short *)p = nrOfArgs;
p += 2;
*(unsigned short *)p = Typesidx+4096 - 1;
result = AddNewType(tmpbuffer,12,name);
return(BuildPointerType(4096+result));
}
static int GetTypeInternal(Type ty,char *name)
{
int st;
switch (ty->op) {
case CHAR:
if (ty->u.sym->name[0] == 'u')
return(0x20);
return(0x10);
case DOUBLE:
return(0x41);
case FLOAT:
return(0x40);
case STRUCT:
return(AddToEmittedTypes(ty,LF_STRUCTURE));
case ENUM:
return(0x74); /* signed int */
case INT:
case UNSIGNED:
if (ty->u.sym->name[0] == 'u')
return(0x75);
return(0x74); /* signed int */
case SHORT:
if (ty->u.sym->name[0] == 'u')
return(0x73);
return(0x72); /* signed int */
case FUNCTION:
if (ty->type)
return GetTypeInternal(ty->type,name);
break;
case LONGLONG:
return 0x76;
case ARRAY:
return(AddArrayType(ty,name));
case UNION:
return(AddToEmittedTypes(ty,LF_UNION));
case POINTER:
assert(ty->type);
redo:
st = ty->type->op;
switch(st) {
case CONST:
ty = ty->type;
goto redo;
case CHAR:
return(0x470);
case DOUBLE:
return(0x441);
case FLOAT:
return(0x440);
case STRUCT:
return(AddToEmittedTypes(ty,LF_STRUCTURE));
case UNION:
return(AddToEmittedTypes(ty,LF_UNION));
case ENUM:
case INT:
if (ty->type->type && ty->type->type->u.sym->name &&
ty->type->u.sym->name[0] == 'u')
return(0x475);
return(0x474);
case UNSIGNED:
if (ty->type->type == NULL) return(0x475);
break;
case SHORT:
if (ty->type->type && ty->type->type->u.sym->name &&
ty->type->u.sym->name[0] == 'u')
return(0x473);
return(0x472);
case LONGLONG:
return 0x476;
case VOID:
return(0x403);
case FUNCTION:
return(4096+BuildFunctionPointerRecord(ty,name));
break;
case ARRAY:
return 4096 + BuildPointerType(AddArrayType(ty->type,name));
case POINTER:
return 4096 + BuildPointerType(GetTypeInternal(ty->type,name));
default:
warning(StrTab[390],name,st);// <Unknown type %s (%d) when generating debug info\n>
break;
}
break;
}
return(0);
}
int GetType(Symbol p)
{
return(GetTypeInternal(p->type,p->name));
}
/*
17 EAX
18 ECX
19 EDX
20 EBX
21 ESP
22 EBP
23 ESI
24 EDI
*/
static int FindRegisterNumber(char *regName)
{
if (regName[2] == 'a') return 17;
else if (regName[2] == 'b') return 20;
else if (regName[2] == 'c') return 18;
else if (regName[2] == 's') return 23;
else if (regName[2] == 'd' && regName[3] == 'x')
return 19;
else if (regName[2] == 'd' && regName[3] == 'i')
return 24;
return 0;
}
void GenLocalDebugInfo(Symbol p)
{
struct autoDataInfo info;
int regNumber;
char buf[150],*pt;
int i;
if (glevel == 0) return;
if (p->x.offset == 0 && p->x.regnode) {
/*
This symbol record describes a symbol that has been enregistered. Provisions
for enabling future implementation tracking of a symbol into and out of
registers is provided in this symbol. When the symbol processor is examining
a register symbol, the length field of the symbol is compared with the offset of
the byte following the symbol name field. If these are the same, there is no
register tracking information. If the length and offset are different, the byte
following the end of the symbol name is examined. If the byte is zero, there is
no register tracking information following the symbol. If the byte is not zero,
then the byte indexes into the list of stack machine implementations and styles
of register tracking. Microsoft does not currently emit or process register
tracking information.
2 2 2 2 * *
length S_REGISTER @type register name tracking
@type The type of the symbol
register Enumerate of the registers in which the symbol value is stored.
This field is treated as two bytes. The high order byte specifies the register
in which the high order part of the value is stored. The low byte specifies
the register for the low order part of the value. If the value is not stored
in two registers then high order register field contains the enumerate value
for no register. For register enumeration values, see Section 6. The
register index enumeration is specific to the processor model for the module.
name Length-prefixed name of the symbol stored in the register
tracking Register tracking information. Format unspecified.
32-bit registers
17 EAX
18 ECX
19 EDX
20 EBX
21 ESP
22 EBP
23 ESI
24 EDI
*/
regNumber = FindRegisterNumber(p->x.name);
pt = buf + 2;
*(unsigned short *)pt = S_REGISTER;
pt += 2;
*(unsigned short *)pt = GetType(p);
pt += 2;
*(unsigned short *)pt = regNumber;
pt += 2;
pt = PutLengthPrefixedName(pt,p->name);
*pt++ = 0;
i = pt - buf;
if (i & 1) {
*pt++ = 0;
}
i = pt - buf;
pt = buf;
*(unsigned short *)pt = i-2;
PutInSymbolBuffer(buf,i);
return;
}
else
info.offset = p->x.offset;
info.type = GetType(p);
PutSymbolRecord(S_BPREL32,(char *)&info,6,p->name);
}
void GenBlockDebugInfo(Code cp)
{
Symbol *p = cp->u.block.locals;
for (; *p; p++) {
GenLocalDebugInfo(*p);
}
}
ProcList *newProcList(char *name)
{
ProcList *result;
result = (ProcList *)malloc(sizeof(ProcList));
memset(result,0,sizeof(ProcList));
result->procInfo.u.Name = malloc(strlen(name)+1);
strcpy(result->procInfo.u.Name,name);
return(result);
}
DataList *newDataList(int len,char *name)
{
DataList *result;
result = allocate(sizeof(DataList),PERM);
result->Next = NULL;
result->data = allocate(len,PERM);
result->len = len;
result->Name = name;
return(result);
}
#if 0
int FindArgListType(int nrOfArguments,unsigned short *typesVector)
{
ProcList *pl;
pl = ProceduresList;
while (pl) {
if (pl->NrOfArguments == nrOfArguments) {
if (pl->FunctionRecord) {
if (!memcmp(pl->FunctionRecord->data+6,typesVector,nrOfArguments*sizeof(short))) {
return(pl->procInfo.procType);
}
}
}
pl = pl->Next;
}
return(-1);
}
#endif
static int BuildFunctionType(ProcList *pl,Symbol f)
{
char tmpbuffer[12],*p;
p = tmpbuffer;
*(unsigned short *)p = 10;
p += 2;
*(unsigned short *)p = 0x8; /* Procedure */
p += 2;
*(unsigned short *)p = GetTypeInternal(f->type,f->x.name);
p += 2;
*p++ = 0; /* no special call flags */
*p++ = 0; /* reserved */
*(unsigned short *)p = pl->NrOfArguments;
p += 2;
*(unsigned short *)p = Typesidx+4096 - 1;
return(AddNewType(tmpbuffer,12,pl->FunctionRecord->Name));
}
void WriteFunctionTypeRecord(Symbol f,int nrOfArguments,unsigned short *typesVector)
{
int len,topad;
unsigned short *data;
// ti = FindArgListType(nrOfArguments,typesVector);
#if 0
if (ti != -1) {
LastProc->procInfo.procType = ti;
LastProc->FunctionRecord = NULL;
return;
}
#endif
len = 3 + nrOfArguments;
topad = 0;
len = len * sizeof(short);
data = (unsigned short *)allocate(len,PERM);
data[0] = len-2;
data[1] = LF_ARGLIST;
data[2] = nrOfArguments;
memcpy(&data[3],typesVector,nrOfArguments * sizeof(short));
if (topad) {
unsigned char *p;
p = (unsigned char *)data + len - 2;
*p++ = (unsigned char)0xF2;
*p++ = (unsigned char)0xF1;
}
LastProc->FunctionRecord = newDataList(len,f->x.name);
LastProc->FunctionRecord->data = (char *)data;
LastProc->FunctionRecord->len = len;
/* This points to the type index record */
LastProc->procInfo.procType = 4096 + Typesidx+1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -