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

📄 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 页
字号:
                return offset;
            }
            offset = p->pNext;
        }
    }
    return 0;
}

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

static int FindFunctionByAddress(DEBUG_INFO *dbg, char **symtab, int *offset,
    int Address, int SelAddress)
{
    OMFSignature *sig;
    OMFDirHeader *dh;
    OMFDirEntry *e;
    int i, j, k, l;

    sig = dbg->info;
    dh = dbg->info + sig->filepos;
    e = (unsigned char*)dh + dh->cbDirHeader;
    for (i = 0; i < dh->cDir; i++)
    {
        if (e->SubSection == sstModule)
        {
            OMFModule *m;
            OMFSegDesc *s;
            m = dbg->info + e->lfo;
            s = &m->SegInfo;
            for (j = 0; j < m->cSeg; j++)
            {
                if (s->Seg == 1)
                {
                     /* code seg */
                    if (Address >= s->Off && Address < s->Off + s->cbSeg)
                    {
                        OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;
                        for (k = 0; k < dh->cDir; k++)
                        {
                            if (e1->SubSection == sstAlignSym && e->iMod == e1
                                ->iMod)
                            {
                                DWORD offs = FindFunctionInSymtab(dbg, e1->lfo,
                                    Address, SelAddress);
                                if (offs)
                                {
                                    *symtab = dbg->info + e1->lfo;
                                    *offset = offs;
                                    return TRUE;
                                }
                                break;
                            }
                            e1++;
                        }
                    }
                    break;
                }
                s++;
            }
        }
        e++;
    }
    e = (unsigned char*)dh + dh->cbDirHeader;
    for (i = 0; i < dh->cDir; i++)
    {
        if (e->SubSection == sstGlobalSym)
        {
            DWORD offs = FindFunctionInSymtab(dbg, e->lfo + sizeof(OMFSymHash),
                Address, SelAddress);
            if (offs)
            {
                *symtab = dbg->info + e->lfo + sizeof(OMFSymHash);
                *offset = offs;
                return TRUE;
            }
            else
                return FALSE;
        }
        e++;
    }
    return 0;
}

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

static int namematch(SYMTYPE *s, char *name)
{
    char *funcname;
    switch (s->rectyp)
    {
        case S_BPREL32:
            funcname = ((BPRELSYM32*)s)->name;
            break;
        case S_REGISTER:

            funcname = ((REGSYM*)s)->name;
            break;
        case S_LDATA32:
        case S_GDATA32:
            funcname = ((DATASYM32*)s)->name;
            break;
        case S_LPROC32:
        case S_GPROC32:
            funcname = ((PROCSYM32*)s)->name;
            break;
        case S_UDT:
            funcname = ((UDTSYM*)s)->name;
            break;
        case S_LABEL32:
            funcname = ((LABELSYM32*)s)->name;
            break;
        default:
            return FALSE;
    }
    if (strlen(name) != funcname[0])
        return 0;
    return !strncmp(funcname + 1, name, funcname[0]);
}

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

static int FindSymbolInFunction(char *symtab, int offset, char *name, int
    Address)
{
    PROCSYM32 *func = symtab + offset;
    int endoffs = func->pEnd;
    int blockoffs = offset;
    int findoffs = blockoffs;
    BLOCKSYM32 *blk;

    // First find the enclosing block
    while (findoffs < endoffs)
    {
        BLOCKSYM32 *b = symtab + findoffs;
        if (b->rectyp == S_BLOCK32)
        {
            if (b->off <= Address && Address < b->off + b->len)
            {
                blockoffs = findoffs;
                endoffs = b->pEnd;
                findoffs += b->reclen + 2;
            }
            else
                findoffs = b->pEnd;
        }
        else
            findoffs += b->reclen + 2;
    }
    // now blockoffs has the point to the innermost block
    blk = symtab + blockoffs;
    while (blk)
    {
        int end = blk->rectyp == S_BLOCK32 ? blk->pEnd: func->pEnd;
        findoffs = (unsigned char*)blk - (unsigned char*)symtab + blk->reclen +
            2;
        while (findoffs < end)
        {
            BLOCKSYM32 *p = findoffs + symtab;
            if (p->rectyp == S_BLOCK32)
                findoffs = p->pEnd;
            else
            {
                if (namematch(p, name))
                {
                    return findoffs;
                }
                findoffs += p->reclen + 2;
            }
        }
        if (blk->rectyp == S_BLOCK32)
            blk = symtab + blk->pParent;
        else
            blk = 0;
    }
    return 0;
}

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

static int FindSymbolInSymtab(char *symtab, int len, char *name)
{
    int offset = 0;

    while (offset < len)
    {
        struct SYMTYPE *s = symtab + offset;
        if (s->rectyp == S_LPROC32 || s->rectyp == S_GPROC32)
        {
            PROCSYM32 *p = s;
            if (namematch(s, name))
                return offset;
            offset = p->pEnd;
        } 
        else
        {
            if (namematch(s, name))
            {
                return offset;
            }
            offset = offset + s->reclen + 2;
        }
    }
    return 0;
}

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

int FindSymbol(DEBUG_INFO **dbg_info, char **typetab, char **symtab, int
    *offset, int Address, int SelAddress, char *name)
{
    OMFSignature *sig;
    OMFDirHeader *dh;
    OMFDirEntry *e;
    int i, j;
    DEBUG_INFO *dbg = DebugProcess.dbg_info;
    DLL_INFO *dll = DebugProcess.dll_info;
    int funcoffs;

    *typetab = 0;

    while (dll && (unsigned)dll->base <= (unsigned)Address)
    {
        dbg = dll->dbg_info;
        dll = dll->next;
    }
    if (!dbg)
        return 0;

    *dbg_info = dbg;
    // Find the types table
    sig = dbg->info;
    dh = dbg->info + sig->filepos;

    // See if it is a function argument or variable
    funcoffs = FindFunctionByAddress(dbg, symtab, offset, Address - dbg->base,
        SelAddress - dbg->base);
    if (funcoffs)
    {
        int offs = FindSymbolInFunction(*symtab,  *offset, name, Address - dbg
            ->base);
        if (offs)
        {
            e = (unsigned char*)dh + dh->cbDirHeader;
            for (i = 0; i < dh->cDir; i++)
            {
                if (e->SubSection == sstGlobalTypes)
                {
                    *typetab = dbg->info + e->lfo;
                    break;
                }
                e++;
            }
            *offset = offs;
            return TRUE;
        }
    }
    if (dbg)
    {
        sig = dbg->info;
        dh = dbg->info + sig->filepos;
        *dbg_info = dbg;
        // check the local symbol table
        e = (unsigned char*)dh + dh->cbDirHeader;
        for (i = 0; i < dh->cDir; i++)
        {
            if (e->SubSection == sstModule)
            {
                OMFModule *m;
                OMFSegDesc *s;
                m = dbg->info + e->lfo;
                s = &m->SegInfo;
                for (j = 0; j < m->cSeg; j++)
                {
                    if (s->Seg == 1)
                    {
                         /* code seg */
                        //                  if (SelAddress-dbg->base >= s->Off && SelAddress-dbg->base < s->Off + s->cbSeg) {
                        int k, l;
                        OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;

                        for (k = 0; k < dh->cDir; k++)
                        {
                            if (e1->SubSection == sstAlignSym && e->iMod == e1
                                ->iMod)
                            {
                                int offs = FindSymbolInSymtab(dbg->info + e1
                                    ->lfo, e1->cb, name);
                                if (offs)
                                {
                                    e = (unsigned char*)dh + dh->cbDirHeader;
                                    for (l = 0; l < dh->cDir; l++)
                                    {
                                        if (e->SubSection == sstGlobalTypes)
                                        {
                                            *typetab = dbg->info + e->lfo;
                                            break;
                                        }
                                        e++;
                                    }
                                    *symtab = dbg->info + e1->lfo;
                                    *offset = offs;
                                    return 1;
                                }
                                break;
                            }
                            e1++;
                        }
                        //                  }
                        break;
                    }
                    s++;
                }
            }
            e++;
        }
        // And check the global symtab for the program this is a part of
        e = (unsigned char*)dh + dh->cbDirHeader;
        for (i = 0; i < dh->cDir; i++)
        {
            if (e->SubSection == sstGlobalSym)
            {
                int offs = FindSymbolInSymtab(dbg->info + e->lfo + sizeof
                    (OMFSymHash), e->cb - sizeof(OMFSymHash), name);
                if (offs)
                {
                    OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;
                    for (i = 0; i < dh->cDir; i++)
                    {
                        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;
}

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

int FindAddressInSymtab(DEBUG_INFO *dbg, char *symtab, int len, int address,
    char *buf)
{
    int offset = 0;

    while (offset < len)
    {
        struct SYMTYPE *s = symtab + offset;
        switch (s->rectyp)
        {
            case S_LDATA32:
            case S_GDATA32:
                if (address == ((DATASYM32*)s)->off + dbg->base)
                {
                    memcpy(buf, ((DATASYM32*)s)->name + 1, ((DATASYM32*)s)
                        ->name[0]);
                    buf[((DATASYM32*)s)->name[0]] = 0;
                    return offset;
                }
                offset = offset + s->reclen + 2;
                break;
            case S_LPROC32:
            case S_GPROC32:
                if (address == ((PROCSYM32*)s)->off + dbg->base)
                {
                    memcpy(buf, ((PROCSYM32*)s)->name + 1, ((PROCSYM32*)s)
                        ->name[0]);
                    buf[((PROCSYM32*)s)->name[0]] = 0;
                    return offset;
                }
                offset = ((PROCSYM32*)s)->pEnd;
                break;
            case S_LABEL32:
                if (address == ((LABELSYM32*)s)->off + dbg->base)
                {
                    memcpy(buf, ((LABELSYM32*)s)->name + 1, ((LABELSYM32*)s)
                        ->name[0]);
                    buf[((LABELSYM32*)s)->name[0]] = 0;
                    return offset;
                }
                // fallthrough
            default:
                offset = offset + s->reclen + 2;
                break;

        }
    }
    return 0;
}

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

int FindSymbolByAddress(DEBUG_INFO **dbg_info, char **typetab, char **symtab,
    int *offset, int Address, char *buf)
{
    OMFSignature *sig;
    OMFDirHeader *dh;
    OMFDirEntry *e;
    int i, j;
    DEBUG_INFO *dbg = DebugProcess.dbg_info;
    DLL_INFO *dll = DebugProcess.dll_info;
    int funcoffs;

    *typetab = 0;

    while (dll && (unsigned)dll->base <= (unsigned)Address)
    {
        dbg = dll->dbg_info;
        dll = dll->next;
    }
    if (!dbg)
        return 0;

    *dbg_info = dbg;
    // Find the types table
    sig = dbg->info;
    dh = dbg->info + sig->filepos;

    if (dbg)
    {
        sig = dbg->info;
        dh = dbg->info + sig->filepos;
        *dbg_info = dbg;
        // check the local symbol table
        e = (unsigned char*)dh + dh->cbDirHeader;
        for (i = 0; i < dh->cDir; i++)
        {
            if (e->SubSection == sstModule)
            {
                OMFModule *m;
                OMFSegDesc *s;
                m = dbg->info + e->lfo;
                s = &m->SegInfo;
                for (j = 0; j < m->cSeg; j++)
                {
                    if (s->Seg == 1)
                    {
                         /* code seg */
                        if (Address - dbg->base >= s->Off && Address - dbg
                            ->base < s->Off + s->cbSeg)
                        {
                            OMFDirEntry *e1 = (unsigned char*)dh + dh
                                ->cbDirHeader;
                            for (i = 0; i < dh->cDir; i++)
                            {
                                if (e1->SubSection == sstAlignSym && e->iMod ==
                                    e1->iMod)
                                {
                                    int offs = FindAddressInSymtab(dbg, dbg
                                        ->info + e1->lfo, e1->cb, Address, buf);
                                    if (offs)
                                    {
                                        e = (unsigned char*)dh + dh
                                            ->cbDirHeader;
                                        for (i = 0; i < dh->cDir; i++)
                                        {
                                            if (e->SubSection == sstGlobalTypes)
                                            {
                                                *typetab = dbg->info + e->lfo;
                                                break;
                                            }
                                            e++;
                                        }
                                        *symtab = dbg->info + e1->lfo;
                                        *offset = offs;
                                        return 1;
                                    }
                                }
                                e1++;
                            }
                        }
                        break;
                    }
                    s++;
                }
            }
            e++;
        }
        // And check the global symtab for the program this is a part of
        e = (unsigned char*)dh + dh->cbDirHeader;
        for (i = 0; i < dh->cDir; i++)
        {
            if (e->SubSection == sstGlobalSym)
            {
                int offs = FindAddressInSymtab(dbg, dbg->info + e->lfo + sizeof
                    (OMFSymHash), e->cb - sizeof(OMFSymHash), Address, buf);
                if (offs)
                {
                    OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;
                    for (i = 0; i < dh->cDir; i++)
                    {

⌨️ 快捷键说明

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