📄 cv.c
字号:
if (LastProc->procInfo.procType > 8000) {
fprintf(stderr,StrTab[391]);// <bad synch in debug info\n>
}
AddNewType(LastProc->FunctionRecord->data,LastProc->FunctionRecord->len,f->x.name);
BuildFunctionType(LastProc,f);
}
void WriteLocalsDebugInfo(Symbol f,int lineno)
{
int i,len,nrOfArguments;
char *p,*pname;
Symbol *Arguments,sym;
struct autoDataInfo info;
unsigned short typesVector[512];
if (glevel == 0) return;
Arguments = f->u.f.callee;
nrOfArguments = 0;
while (*Arguments) {
Arguments++;
nrOfArguments++;
}
#if 0
if (nrOfArguments)
typesVector = (unsigned short *)malloc(sizeof(short)*nrOfArguments);
else
typesVector = NULL;
#endif
Arguments = f->u.f.callee;
for (i=0;i<nrOfArguments;i++) {
sym = *Arguments++;
info.offset = sym->x.offset;
info.type = GetType(sym);
PutSymbolRecord(S_BPREL32,(char *)&info,6,sym->name);
typesVector[i] = info.type;
}
for (i=0,len=0;i<DebugSymbolPtr;i++) {
len += LocalsTable[i].len;
}
pname = f->x.name;
/* maybe use f->name? */
if (ProceduresList == NULL) {
ProceduresList = newProcList(pname);
LastProc = ProceduresList;
}
else {
LastProc->Next = newProcList(pname);
LastProc = LastProc->Next;
}
LastProc->data = allocate(len,PERM);
p = LastProc->data;
for (i=0; i<DebugSymbolPtr;i++) {
memcpy(p,LocalsTable[i].data,LocalsTable[i].len);
p += LocalsTable[i].len;
}
LastProc->len = len;
LastProc->Sym = f;
DebugSymbolPtr = 0;
LastProc->NrOfArguments = nrOfArguments;
WriteFunctionTypeRecord(f,nrOfArguments,typesVector);
#if 0
if (typesVector)
free(typesVector);
#endif
}
char *PutLengthPrefixedName(char *dst,char *src)
{
if (src == NULL) src = "_unnamed";
*dst++ = strlen(src);
while (*src) {
*dst++ = *src++;
}
return(dst);
}
DataList *AddToCVData(char *data,int len,char *name)
{
if (DataSymbolsInfo == NULL) {
DataSymbolsInfo = newDataList(len,name);
LastDataSymbolsInfo = DataSymbolsInfo;
}
else {
LastDataSymbolsInfo->Next = newDataList(len,name);
LastDataSymbolsInfo = LastDataSymbolsInfo->Next;
}
memcpy(LastDataSymbolsInfo->data,data,len);
return(LastDataSymbolsInfo);
}
int AddNewType(char *data,int len,char *name)
{
if (DataTypesInfo == NULL) {
DataTypesInfo = newDataList(len,name);
LastDataTypesInfo = DataTypesInfo;
}
else {
LastDataTypesInfo->Next = newDataList(len,name);
LastDataTypesInfo = LastDataTypesInfo->Next;
}
memcpy(LastDataTypesInfo->data,data,len);
return(Typesidx++);
}
extern int NrOfTypes;
/*
(0x0406) Data Member
This leaf specifies nonstatic data members of a class.
2 2 2 * *
LF_MEMBER @type attribute offset name
@type Index to type record for field
attribute Member attribute bit field
offset Numeric leaf specifying the offset of field in the structure
name Length-prefixed name of the member field
*/
int BuildFieldList(Field flist,int count)
{
char *buffer,*p;
int memberType,len,result,padCount;
p = buffer = malloc(16000);
*(unsigned short *)p = 0;
p += 2;
*(unsigned short *)p = 0x204;
p += 2;
while (flist) {
*(unsigned short *)p = LF_MEMBER; /* (0x406) */
p += 2;
memberType = GetTypeInternal(flist->type,flist->name);
*(unsigned short *)p = memberType;
p += 2;
*(unsigned short *)p = 0;
p += 2;
*(unsigned short *)p = flist->offset;
p += 2;
p = PutLengthPrefixedName(p,flist->name);
flist = flist->link;
len = (p - buffer);
/*
Because of the requirement for natural alignment, there may be padding
between elements of the field list. As a program walks down the field
list, the address of the next subfield is calculated by adding the length
of the previous field to the address of the previous field. The byte at
the new address is examined and if it is greater than 0xf0, the low four
bits are extracted and added to the address to find the address of the next
subfield. These padding fields are not included in the count field of the
class, structure, union, or enumeration type records.
*/
padCount = len % 4;
if (padCount) {
padCount = 4 - padCount;
*p++ = (char)(0xF0 | padCount--);
while (padCount > 0) {
*p++ = (char)(0xF0|padCount--);
}
}
}
len = p - buffer;
p = buffer;
*(unsigned short *)p = len-2;
result = AddNewType(buffer,len,"");
free(buffer);
return(result);
}
char *PutNumericValue(char *dst,int size)
{
if (size < 0x8000) {
*(unsigned short *)dst = size;
dst += 2;
}
else {
*(unsigned short *)dst = LF_LONG;
dst += 2;
*(unsigned long *)dst = size;
dst += 4;
}
return(dst);
}
/*
(0x0004) Classes and Structures
The format for structures and classes is as follows:
2 2 2 2 2 2 * *
leaf count @field property @dList @vshape length name
leaf LF_CLASS or LF_STRUCTURE
count Number of elements in the class or structure. This count includes direct,
virtual, and indirect virtual bases, and methods including overloads, data
members, static data members, friends, and so on.
@field Type index of the field list for this class.
property Property bit field
packed :1 Structure is packed
ctor :1 Class has constructors and/or destructors
overops :1 Class has overloaded operators
isnested :1 Class is a nested class
cnested :1 Class contains nested classes
opassign :1 Class has overloaded assignment
opcast :1 Class has casting methods
fwdref :1 Class/structure is a forward (incomplete) reference
scoped :1 This is a scoped definition
reserved :8
@dList Type index of the derivation list. This is output by the compiler as
0x0000 and is filled in by the CVPACK utility to a LF_DERIVED record
containing the type indices of those classes which immediately inherit
the current class. A zero index indicates that no derivation information
is available. A LF_NULL index indicates that the class is not inherited
by other classes.
@vshape Type index of the virtual function table shape descriptor
length Numeric leaf specifying size in bytes of the structure
name Length-prefixed name this type
(0x0005) Structures
Structures have the same format as classes. Structure type records are used
exclusively by the C compiler. The C++ compiler emits both class and structure
records depending upon the declaration.
*/
int BuildStructType(Type ty,int cvType)
{
char *name;
Field flist;
int size = ty->size;
int count,len,padCount,result;
Symbol sym;
char buffer[200],*p;
sym = ty->u.sym;
name = sym->name;
flist = sym->u.s.flist;
count = 0;
while (flist) {
count++;
flist = flist->link;
}
flist = sym->u.s.flist;
memset(buffer,0,200);
p = buffer + 2;
*(unsigned short *)p = cvType;
p += 2;
*(unsigned short *)p = count;
p += 2;
*(unsigned short *)p = 0;
p += 2;
if (cvType == LF_STRUCTURE) {
/* ignore for the moment the problem of knowing if
this structure is packed */
p += 2;
/* leave the derived field as zero */
p += 2;
/* no virtual functions */
p += 2;
}
else if (cvType == LF_UNION) {
/* Property bit field undocumented */
p += 2;
}
p = PutNumericValue(p,size);
*p++ = strlen(name);
while (*name) {
*p++ = *name++;
}
len = (p-buffer);
padCount = len % 4;
if (padCount) {
padCount = 4 - padCount;
*p++ = (char)(0xF0 | padCount--);
while (padCount > 0) {
*p++ = (char)(0xF0|padCount--);
}
}
len = (p - buffer)-2;
p = buffer;
*(unsigned short *)p = len;
result = AddNewType(buffer,len+2,sym->name);
p = LastDataTypesInfo->data + 6;
*(unsigned short *)p = BuildFieldList(flist,count)+4096;
return(result);
}
int BuildPointerType(int xrefIdx)
{
char buffer[8];
short *p;
p = (short *)buffer;
p[0] = 6;
p[1] = LF_POINTER;
p[2] = 0xA; /* near 32 bit pointer */
p[3] = xrefIdx;
return(AddNewType(buffer,8,""));
}
static int AddToEmittedTypes(Type typ,int cvType)
{
DataList *save;
if (typ == NULL) return(0);
if (typ->op == POINTER) {
Type ty;
ty = typ->type;
assert(ty);
if (ty->x.marked == 0) {
if (ty->op != STRUCT && ty->op != UNION) {
return(0);
}
ty->x.typeno = Typesidx;
ty->x.marked = 1;
save = LastDataTypesInfo ;
if (ty->op == STRUCT) {
BuildStructType(ty,LF_STRUCTURE);
}
else if (ty->op == UNION) {
BuildStructType(ty,LF_UNION);
}
else return(0);
}
if (ty->x.pointerEmitted) {
return(ty->x.pointerIndex+4096);
}
ty->x.pointerEmitted = 1;
ty->x.pointerIndex = BuildPointerType(ty->x.typeno+4096);
return(ty->x.pointerIndex+4096);
}
if (typ->x.marked == 0) {
if (typ->op != STRUCT && typ->op != UNION) {
return(0);
}
typ->x.typeno = Typesidx;
typ->x.marked = 1;
save = LastDataTypesInfo;
if (typ->op == STRUCT) {
BuildStructType(typ,LF_STRUCTURE);
}
else if (typ->op == UNION) {
BuildStructType(typ,LF_UNION);
}
}
return(typ->x.typeno+4096);
}
/*
(0x0003) Simple Array
2 2 2 * *
LF_ARRAY @elemtype @idxtype length name
@elemtype Type index of each array element
@idxtype Type index of indexing variable
length Length of array in bytes
name Length-prefixed name of array
*/
int AddArrayType(Type ty,char *name)
{
int len,result;
char buf[256],*p,*n;
assert(ty->type);
p = buf;
p += 2;
*(unsigned short *)p = LF_ARRAY;
p += 2;
n = NULL;
if (ty->type->u.sym)
n = ty->type->u.sym->name;
if (n == NULL) n = "";
*(unsigned short *)p = GetTypeInternal(ty->type,n);
p += 2;
*(unsigned short *)p = 0x74; /* index is signed int... */
p += 2;
p = PutNumericValue(p,ty->size);
p = PutLengthPrefixedName(p,name);
len = p - buf;
*(unsigned short *)buf = len - 2;
result = AddNewType(buf,len,name);
return result+4096;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -