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

📄 symtab.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
                        if (e1->SubSection == sstGlobalTypes)
                        {
                            *typetab = dbg->info + e1->lfo;
                            break;
                        }
                        e1++;
                    }
                    *symtab = dbg->info + e->lfo + sizeof(OMFSymHash);
                    *offset = offs;
                    return TRUE;
                }
                else
                    return FALSE;
            }
            e++;
        }
    }


    return 0;
}

//-------------------------------------------------------------------------

PROCSYM32 *FindFunctionSymbol(int Address)
{
    char *symtab;
    DEBUG_INFO *dbg = DebugProcess.dbg_info;
    int offset;
    DLL_INFO *dll;

    dll = DebugProcess.dll_info;

    while (dll && (unsigned)dll->base <= (unsigned)Address)
    {
        dbg = dll->dbg_info;
        dll = dll->next;
    }
    if (dbg && FindFunctionByAddress(dbg, &symtab, &offset, Address - dbg->base,
        Address - dbg->base))
    {

        PROCSYM32 *p = symtab + offset;
        return p;
    }
    return 0;
}

//-------------------------------------------------------------------------

int FindFunctionName(char *buf, int Address)
{
    char *symtab;
    DEBUG_INFO *dbg = DebugProcess.dbg_info;
    int offset;
    DLL_INFO *dll;
    buf[0] = 0;

    dll = DebugProcess.dll_info;

    while (dll && (unsigned)dll->base <= (unsigned)Address)
    {
        dbg = dll->dbg_info;
        dll = dll->next;
    }
    if (dbg && FindFunctionByAddress(dbg, &symtab, &offset, Address - dbg->base,
        Address - dbg->base))
    {
        PROCSYM32 *p = symtab + offset;
        getname(buf, p->name);
        return 1;
    }
    return 0;
}

//-------------------------------------------------------------------------

char *LookupType(char *typetab, int typenum)
{
    OMFGlobalTypes *p = typetab;
    int offset;
    typenum -= CV_FIRST_NONPRIM;
    if (typenum < 0 || typenum >= p->cTypes)
        return 0;

    offset = p->typeOffset[typenum] + (char*) &p->cTypes - typetab;

    return offset + typetab;
}

//-------------------------------------------------------------------------

int GetNumericLeaf(short *ptr)
{
    int val = *(ptr);
    if (val < LF_NUMERIC)
        return val;
    // LF_LONG is the only thing we are supporting
    return *(int*)(ptr + 1);
}

//-------------------------------------------------------------------------

int GetNumericLeafSize(short *ptr)
{
    int val = *(ptr);
    if (val < LF_NUMERIC)
        return 2;
    // LF_LONG is the only thing we are supporting
    return 5;
}

//-------------------------------------------------------------------------

void GetStructInfo(char *typetab, short *type, VARINFO *var)
{
    short *typeptr = LookupType(typetab, ((lfStructure*)(type + 1))->field);
    VARINFO **v = &var->subtype;
    if (!typeptr)
        return ;
    while (*(typeptr + 1) == LF_FIELDLIST)
    {
        int done = FALSE;
        int len;
        len =  *typeptr - 2;
        typeptr += 2;
        while (len && !done)
        {
            VARINFO *vx;
            int xlen;
            char *nmptr;
            switch (*typeptr)
            {
                case LF_MEMBER:
                    vx =  *v = calloc(sizeof(VARINFO), 1);
                    if (!vx)
                        return ;
                    vx->thread = var->thread;
                    v = &(*v)->link;
                    vx->offset = GetNumericLeaf(&((lfMember*)typeptr)->offset);
                    vx->address = var->address + vx->offset;
                    vx->type = ((lfMember*)typeptr)->index;
                    DeclType(typetab, vx);
                    xlen = sizeof(lfMember) - CV_ZEROLEN;
                    if ((*(short*)((char*)typeptr) + xlen) < LF_NUMERIC)
                        xlen += 2;
                    else
                        xlen += 6;
                    nmptr = (char*)typeptr + xlen;
                    strncpy(vx->membername, nmptr + 1,  *nmptr);
                    vx->membername[ *nmptr] = 0;
                    xlen +=  *nmptr + 1;
                    if ((*(((char*)typeptr) + xlen) &0xf0) == 0xf0)
                        xlen += *(((char*)typeptr) + xlen) &15;
                    (char*)typeptr += xlen;
                    break;
                case LF_INDEX:
                    typeptr = LookupType(typetab, ((lfIndex*)typeptr)->index);
                    done = TRUE;
                    break;
                default:
                    return ;
            }
        }
    }
}

//-------------------------------------------------------------------------

int basictypesize(int type)
{
    if (CV_MODE(type) != CV_TM_DIRECT)
        return 4;
    switch (CV_TYPE(type))
    {
        case CV_SIGNED:
        case CV_UNSIGNED:
        case CV_BOOLEAN:
            return 1 << CV_SUBT(type);
        case CV_REAL:
        case CV_IMAGINARY:
            switch (CV_SUBT(type))
            {
            case CV_RC_REAL32:
                return 4;
            case CV_RC_REAL64:
                return 8;
            default:
                return 10;
            }
            break;
        case CV_COMPLEX:
            switch (CV_SUBT(type))
            {
            case CV_RC_REAL32:
                return 8;
            case CV_RC_REAL64:
                return 16;
            default:
                return 20;
            }
            break;
        case CV_INT:
            return 1 << (CV_SUBT(type) / 2);
    }
    return 0;
}

//-------------------------------------------------------------------------

void GetArrayInfo(char *typetab, short *type, VARINFO *var)
{
    int i = 0, z = 0;
    VARINFO **nextptr = &var->subtype;
    while (i < var->arraysize)
    {
        VARINFO *vx = calloc(sizeof(VARINFO), 1);
        if (!vx)
            return ;
        vx->thread = var->thread;
        vx->offset = i;
        vx->address = var->address;
        if (var->vararray && var->vararraylist && var->vararraylevel < var
            ->vararraylist[0] - 1)
        {
            vx->vararraylevel = var->vararraylevel + 1;
            vx->vararraylist = var->vararraylist;
            vx->vararray = TRUE;
            vx->array = TRUE;
        }
        vx->type = var->type;
        sprintf(vx->membername, "%s[%d]", var->membername, z++);
        i += var->itemsize = DeclType(typetab, vx);
        *nextptr = vx;
        nextptr = &vx->link;
    }
}

//-------------------------------------------------------------------------

void GetVararrayInfo(char *typetab, short *type, VARINFO *var)
{
    int aa[100];
    if (ReadValue(var->address + 4, aa, 4, &var->thread->regs) == 4)
    {
        ReadValue(var->address + 8, aa + 1, (aa[0] + 1) *4, &var->thread->regs);
    }
    else
        aa[0] = 0;

    if (aa[0] > 98)
        aa[0] = 0;
    ReadValue(var->address, &var->address, 4, &var->thread->regs);

    var->vararraylisttofree = var->vararraylist = calloc((aa[0] + 2), sizeof
        (int));
    if (var->vararraylist)
        memcpy(var->vararraylist, aa, (aa[0] + 2) *sizeof(int));
}

//-------------------------------------------------------------------------

void GetPointerInfo(char *typetab, VARINFO *v)
{
    VARINFO *vx = calloc(sizeof(VARINFO), 1);
    if (!vx)
        return ;
    v->subtype = vx;
    vx->type = v->type;
    vx->thread = v->thread;
    sprintf(vx->membername, "*%s", v->membername);
    DeclType(typetab, vx);
}

//-------------------------------------------------------------------------

int DeclType(char *typetab, VARINFO *v)
{
    short *typeptr;
    char *p;
    if (v->vararray && v->vararraylist)
    {
        v->arraysize = v->vararraylist[v->vararraylevel + 1];
        GetArrayInfo(typetab, typeptr, v);
        return v->arraysize;
    }
    if (CV_IS_PRIMITIVE(v->type))
    {
        if (CV_TYP_IS_PTR(v->type))
        {
            v->pointer = TRUE;
            v->type = CV_NEWMODE(v->type, CV_TM_DIRECT);
            v->subtype = 0;
            return 4;
        }
        return basictypesize(v->type);
    }
    typeptr = LookupType(typetab, v->type);
    if (!typeptr)
        return 0;
    v->typetab = typeptr;

    switch (typeptr[1])
    {
        case LF_POINTER:
            v->pointer = TRUE;
            v->type = ((lfPointer*)(typeptr + 1))->u.utype;
            v->typetab = LookupType(typetab, v->type);
            v->subtype = 0;
            return 4;
        case LF_ARRAY:
            v->array = TRUE;
            v->type = ((lfArray*)(typeptr + 1))->elemtype;
            v->arraysize = GetNumericLeaf(&((lfArray*)(typeptr + 1))->data);
            GetArrayInfo(typetab, typeptr, v);
            return v->arraysize;
        case LF_VARARRAY:
            v->array = TRUE;
            v->vararray = TRUE;
            v->type = ((lfArray*)(typeptr + 1))->elemtype;
            GetVararrayInfo(typetab, typeptr, v);
            v->arraysize = DeclType(typetab, v);
            return v->arraysize;
        case LF_UNION:
            v->unionx = TRUE;
            GetStructInfo(typetab, typeptr, v);
            v->arraysize = GetNumericLeaf(((lfUnion*)(typeptr + 1))->data);
            p = (char*)(((lfUnion*)(typeptr + 1))->data) + GetNumericLeafSize((
                (lfUnion*)(typeptr + 1))->data);
            memcpy(v->structtag, p + 1,  *p);
            return GetNumericLeaf(((lfUnion*)(typeptr + 1))->data);
        case LF_STRUCTURE:
        case LF_CLASS:
            v->structure = TRUE;
            GetStructInfo(typetab, typeptr, v);
            v->arraysize = GetNumericLeaf(((lfClass*)(typeptr + 1))->data);
            p = (char*)(((lfClass*)(typeptr + 1))->data) + GetNumericLeafSize((
                (lfClass*)(typeptr + 1))->data);
            memcpy(v->structtag, p + 1,  *p);
            return GetNumericLeaf(((lfClass*)(typeptr + 1))->data);
        case LF_ENUM:
            v->enumx = TRUE;
            v->type = ((lfEnum*)(typeptr + 1))->utype;
            v->typetab = LookupType(typetab, ((lfEnum*)(typeptr + 1))->field);
            p = (char*)(((lfEnum*)(typeptr + 1))->Name);
            memcpy(v->structtag, p + 1,  *p);
            return basictypesize(v->type);
        case LF_BITFIELD:
            // Should only appear in structures
            v->bitfield = TRUE;
            v->bitstart = ((lfBitfield*)(typeptr + 1))->position;
            v->bitlength = ((lfBitfield*)(typeptr + 1))->length;
            v->type = ((lfBitfield*)(typeptr + 1))->type;
            return 0;
    }
    return 0;
}

//-------------------------------------------------------------------------

VARINFO *GetVarInfo(DEBUG_INFO *dbg, char *typetab, char *symtab, int offset,
    char *name, int ebp, THREAD *thread)
{
    SYMTYPE *s = symtab + offset;
    VARINFO *v = calloc(sizeof(VARINFO), 1);
    if (!v)
        return 0;
    strcpy(v->membername, name);
    v->thread = thread;
    switch (s->rectyp)
    {
        case S_BPREL32:
            v->address = ((BPRELSYM32*)s)->off + ebp;
            v->type = ((BPRELSYM32*)s)->typind;
            break;
        case S_REGISTER:
            v->inreg = TRUE;
            v->outofscopereg = ebp != thread->regs.Ebp;
            v->address = ((REGSYM*)s)->reg;
            v->type = ((REGSYM*)s)->typind;
            break;
        case S_LDATA32:
        case S_GDATA32:
            v->address = ((DATASYM32*)s)->off + dbg->base;
            v->type = ((DATASYM32*)s)->typind;
            break;
        case S_LPROC32:
        case S_GPROC32:
            v->address = ((PROCSYM32*)s)->off + dbg->base;
            v->type = T_PVOID;
            break;
        case S_UDT:
            v->udt = TRUE;
            v->type = ((UDTSYM*)s)->typind;
            v->address = 0;
            break;
        case S_LABEL32:
            v->constant = TRUE;
            v->type = T_PVOID;
            v->ival = ((LABELSYM32*)s)->off + dbg->base;
            break;
        default:
            free(v);
            return 0;
    }
    DeclType(typetab, v);
    return v;

}

//-------------------------------------------------------------------------

void FreeVarInfo(VARINFO *info)
{
    while (info)
    {
        VARINFO *chain = info->link;
        FreeVarInfo(info->subtype);
        if (info->vararraylisttofree)
            free(info->vararraylisttofree);
        free(info);
        info = chain;
    }
}

//-------------------------------------------------------------------------

int ReadValue(int address, void *val, int size, CONTEXT *regs)
{
    int len;
    if (address < 0x1000 && regs)
    {
        // register
        switch (address)
        {
            case CV_REG_AL:
                *(char*)val = regs->Eax &0xff;
                return 1;
            case CV_REG_CL:
                *(char*)val = regs->Ecx &0xff;
                return 1;
            case CV_REG_DL:
                *(char*)val = regs->Edx &0xff;
                return 1;
            case CV_REG_BL:
                *(char*)val = regs->Ebx &0xff;
                return 1;
            case CV_REG_AH:
                *(char*)val = (regs->Eax >> 8) &0xff;
                return 1;
            case CV_REG_CH:
                *(char*)val = (regs->Ecx >> 8) &0xff;
                return 1;
            case CV_REG_DH:
                *(char*)val = (regs->Edx >> 8) &0xff;
                return 1;
            case CV_REG_BH:
                *(char*)val = (regs->Ebx >> 8) &0xff;
                return 1;
            case CV_REG_AX:
                *(short*)val = regs->Eax &0xffff;
                return 2;
            case CV_REG_CX:
                *(short*)val = regs->Ecx &0xffff;
                return 2;
            case CV_REG_DX:
                *(short*)val = regs->Edx &0xffff;
                return 2;
            case CV_REG_BX:
                *(short*)val = regs->Ebx &0xffff;
                return 2;
            case CV_REG_SP:
                *(short*)val = regs->Esp &0xffff;
                return 2;
            case CV_REG_BP:
                *(short*)val = regs->Ebp &0xffff;
                return 2;
            case CV_REG_SI:
                *(short*)val = regs->Esi &0xffff;
                return 2;
            case CV_REG_DI:
                *(short*)val = regs->Edi &0xffff;
                return 2;
            case CV_REG_EAX:
                *(int*)val = regs->Eax;
                return 4;
            case CV_REG_ECX:
                *(int*)val = regs->Ecx;
                return 4;
            case CV_REG_EDX:
                *(int*)val = regs->Edx;
                return 4;
            case CV_REG_EBX:
                *(int*)val = regs->Ebx;
                return 4;
            case CV_REG_ESP:
                *(int*)val = regs->Esp;
                return 4;
            case CV_REG_EBP:
                *(int*)val = regs->Ebp;
                return 4;
            case CV_REG_ESI:
                *(int*)val = regs->Esi;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -