⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cv.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -