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

📄 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 页
字号:
/* 
Copyright 2001-2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

You may contact the author at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222

 **********************************************************************

SYMTAB.C holds the routines for dealing with the debug info symbol
file.  It also holds the basic routines for formatting the hint data
for the edit window, and basic routines for finding and loading
debug data for the watch window
 **********************************************************************

 */
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <ctype.h>

#include "header.h"
#include "cvinfo.h"
#include "cvexefmt.h"

extern PROCESS DebugProcess;

unsigned bitmask[] = 
{
    1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff,
        0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff,
        0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff,
        0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff, 

};

int DeclType(char *typetab, VARINFO *v);

static int comparefiletime(char *name, char *name1)
{
    int rv;
    BY_HANDLE_FILE_INFORMATION info, info1;

    HANDLE handle = CreateFile(name, GENERIC_READ, FILE_SHARE_READ |
        FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if (handle == INVALID_HANDLE_VALUE)
        return 1;

    if (!GetFileInformationByHandle((HANDLE)handle, &info))
    {
        CloseHandle(handle);
        return 1;
    }

    CloseHandle(handle);
    handle = CreateFile(name1, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
        0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if (handle == INVALID_HANDLE_VALUE)
        return 1;

    if (!GetFileInformationByHandle((HANDLE)handle, &info1))
    {
        CloseHandle(handle);
        return 1;
    }

    CloseHandle(handle);

    if (info1.ftLastWriteTime.dwHighDateTime >
        info.ftLastWriteTime.dwHighDateTime)
        return 0;
    if (info1.ftLastWriteTime.dwHighDateTime <
        info.ftLastWriteTime.dwHighDateTime)
        return 1;
    if (info1.ftLastWriteTime.dwLowDateTime >=
        info.ftLastWriteTime.dwLowDateTime)
        return 0;

    return 1;
}

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

DEBUG_INFO *GetDebugInfo(LPVOID imageBase, char *name, int primary)
{
    char buf[256],  *p = buf,  *q = name, realname[256],  *r = realname;
    DEBUG_INFO *rv;
    unsigned char *info;
    FILE *fil;
    int len;

    if (name[0] == '"')
    {
        q++;
        while (*q &&  *q != '"')
            *p++ =  *r++ =  *q++;
        *p =  *r = 0;
    }
    else
    {
        strcpy(buf, name);
        strcpy(realname, name);
    }

    p = strrchr(buf, '.');
    if (p)
        strcpy(p, ".lss");
    else
        strcat(buf, ".lss");

    if (comparefiletime(buf, realname))
        return 0;

    fil = fopen(buf, "rb");
    if (!fil)
        return 0;

    fseek(fil, 0L, SEEK_END);
    len = ftell(fil);
    fseek(fil, 0L, SEEK_SET);

    info = malloc(len);
    if (info == 0)
    {
        fclose(fil);
        return 0;
    }
    fread(info, len, 1, fil);
    fclose(fil);

    if (memcmp(info, "LS11", 4))
    {
        free(info);
        return 0;
    }

    rv = (DEBUG_INFO*)malloc(sizeof(DEBUG_INFO));
    if (!rv)
    {
        free(info);
        return 0;
    }
    rv->size = len;
    rv->info = info;
    rv->base = imageBase;
    return rv;
    /* if we get here everything is kosher and it loaded ok. */
}

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

void FreeDebugInfo(DEBUG_INFO *dbg)
{
    if (dbg)
    {
        free(dbg->info);
        free(dbg);
    }
}

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

static void getname(char *buf, unsigned char *cname)
{
    memcpy(buf, cname + 1, cname[0]);
    buf[cname[0]] = 0;
}

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

DWORD GetMainAddress(DEBUG_INFO *dbg)
{
    OMFSignature *sig;
    OMFDirHeader *dh;
    OMFDirEntry *e;
    int i;

    if (!dbg)
        return 0;

    sig = dbg->info;
    dh = dbg->info + sig->filepos;
    e = (unsigned char*)dh + dh->cbDirHeader;

    for (i = 0; i < dh->cDir; i++)
    {
        if (e->SubSection == sstGlobalSym)
        {
            int base = e->lfo + sizeof(OMFSymHash);
            int count = e->cb - sizeof(OMFSymHash);
            if (*((short*)(dbg->info + base + 2)) == S_SSEARCH)
            {
                SEARCHSYM *s = base + dbg->info;
                if (s->startsym)
                {
                    int pos = base + s->startsym;
                    PROCSYM32 *p = dbg->info + pos;
                    char namebuf[256];
                    while (p->rectyp == S_GPROC32)
                    {
                        getname(namebuf, p->name);
                        if (!strcmp(namebuf, "main"))
                            return p->off + dbg->base;
                        if (!strcmp(namebuf, "WinMain"))
                            return p->off + dbg->base;
                        if (!strcmp(namebuf, "DllEntryPoint"))
                            return p->off + dbg->base;
                        pos = base + p->pNext;
                        p = dbg->info + pos;
                    }
                }
            }
            return 0;
        }

        e++;
    }
    return 0;
}

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

int GetBreakpointLine(int Address, char *module, int *linenum)
{
    OMFSignature *sig;
    OMFDirHeader *dh;
    OMFDirEntry *e;
    int i, j;
    DEBUG_INFO *dbg = DebugProcess.dbg_info;
    DLL_INFO *dll = DebugProcess.dll_info;

    while (dll)
    {
        if (Address - (unsigned)dbg->base > Address - (unsigned)dll->base)
            if (dll->dbg_info)
                dbg = dll->dbg_info;
        dll = dll->next;
    }

    if (!dbg)
        return 0;

    Address -= dbg->base;
    *linenum = 0;
    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)
                    {
                        char *str = (char*)m->SegInfo + sizeof(OMFSegDesc) *m
                            ->cSeg;
                        OMFDirEntry *e1;
                        memcpy(module, str + 1, str[0]);
                        module[str[0]] = 0;
                        e1 = (unsigned char*)dh + dh->cbDirHeader;
                        for (i = 0; i < dh->cDir; i++)
                        {
                            if (e1->SubSection == sstSrcModule && e->iMod == e1
                                ->iMod)
                            {
                                OMFSourceLine *sl = dbg->info + e1->lfo;
                                short *lines = (char*) &sl->offset + 4 * sl
                                    ->cLnOff;
                                *linenum = lines[0];
                                for (i = 1; i < sl->cLnOff; i++)
                                {
                                    if (Address < sl->offset[i])
                                        break;
                                    *linenum = lines[i];
                                }
                                if (i > 0)
                                {
                                    return sl->offset[i - 1] + dbg->base;
                                }
                                return 1;
                            }
                            e1++;
                        }
                        return 0;
                    }
                }
                s++;
            }

        }
        e++;
    }
    return 0;
}

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

static int MatchedModule(char *module, char *dbgname)
{
    char buf[256],  *p;
    memcpy(buf, dbgname + 1, dbgname[0]);
    buf[dbgname[0]] = 0;
    if (!xstricmpz(module, buf))
        return TRUE;
    p = strrchr(module, '\\');
    if (p)
        return !xstricmpz(buf, p + 1);

    return FALSE;
}

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

int GetBreakpointAddressByProgram(char *module, int *linenum, DEBUG_INFO *dbg,
    int inmodule)
{
    OMFSignature *sig;
    OMFDirHeader *dh;
    OMFDirEntry *e;
    int i, j;

    if (!dbg)
        return 0;
    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 = dbg->info + e->lfo;
            char *str = (char*)m->SegInfo + sizeof(OMFSegDesc) *m->cSeg;
            if (MatchedModule(module, str))
            {
                OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;
                for (i = 0; i < dh->cDir; i++)
                {
                    if (e1->SubSection == sstSrcModule && e->iMod == e1->iMod)
                    {
                        OMFSourceLine *sl = dbg->info + e1->lfo;
                        short *lines = (char*) &sl->offset + 4 * sl->cLnOff;
                        for (i = 0; i < sl->cLnOff; i++)
                        {
                            if (*linenum == lines[i])
                            {
                                return sl->offset[i] + dbg->base;
                            }
                            else if (*linenum < lines[i])
                            {
                                if (inmodule && i)
                                    return sl->offset[i - 1] + dbg->base;
                                return 0;
                            }
                        }
                        return 0;
                    }
                    e1++;
                }
                return 0;
            }

        }
        e++;
    }
    return 0;
}

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

int GetBreakpointAddress(char *module, int *linenum, int inmodule)
{
    DLL_INFO *dll = DebugProcess.dll_info;
    int rv = GetBreakpointAddressByProgram(module, linenum,
        DebugProcess.dbg_info, inmodule);
    if (rv)
        return rv;

    while (dll)
    {
        rv = GetBreakpointAddressByProgram(module, linenum, dll->dbg_info,
            inmodule);
        if (rv)
            return rv;
        dll = dll->next;
    }
    return 0;
}

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

SHORT *GetLineTableByDBG(char *module, DEBUG_INFO *dbg, int *count)
{
    OMFSignature *sig;
    OMFDirHeader *dh;
    OMFDirEntry *e;
    int i, j;

    if (!dbg)
        return 0;
    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 = dbg->info + e->lfo;
            char *str = (char*)m->SegInfo + sizeof(OMFSegDesc) *m->cSeg;
            if (MatchedModule(module, str))
            {
                OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;
                for (i = 0; i < dh->cDir; i++)
                {
                    if (e1->SubSection == sstSrcModule && e->iMod == e1->iMod)
                    {
                        OMFSourceLine *sl = dbg->info + e1->lfo;
                        *count = sl->cLnOff;
                        return (char*) &sl->offset + 4 * sl->cLnOff;
                    }
                    e1++;
                }
                return 0;
            }

        }
        e++;
    }
    return 0;
}

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

SHORT *GetLineTable(char *module, int *count)
{
    DLL_INFO *dll = DebugProcess.dll_info;
    short *rv = 0;
    *count = 0;
    rv = GetLineTableByDBG(module, DebugProcess.dbg_info, count);
    if (rv)
        return rv;

    while (dll)
    {
        rv = GetLineTableByDBG(module, dll->dbg_info, count);
        if (rv)
            return rv;
        dll = dll->next;
    }
    return 0;
}

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

static int FindFunctionInSymtab(DEBUG_INFO *dbg, int symtab, int address, int
    seladdress)
{
    char *symtab_base = dbg->info + symtab;
    int offset = 0;

    SEARCHSYM *s = symtab_base;
    if (s->rectyp == S_SSEARCH)
    {
        offset = s->startsym;
        while (offset)
        {
            PROCSYM32 *p = symtab_base + offset;
            if (p->rectyp != S_GPROC32 && p->rectyp != S_LPROC32)
                return 0;
            if (address >= p->off && address < p->off + p->len && seladdress >=
                p->off && seladdress < p->off + p->len)
            {

⌨️ 快捷键说明

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