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

📄 dbg386.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 
Copyright 1994-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.  

This program is derived from the cc68k complier by 
Matthew Brandt (mattb@walkingdog.net) 

You may contact the author of this derivative at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
 */
#include <stdio.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include "cvinfo.h"
#include "gen386.h"   
#include "diag.h"

extern int packdata[], packlevel;
extern int global_flag;
extern int prm_debug, prm_cplusplus;
extern char version[];
extern char outfile[];
extern SYM *currentfunc;
extern EMIT_TAB segs[];
extern int startlab, retlab;
extern int packdata[], packlevel;
extern int outcode_base_address;
extern int lineno;
extern HASHREC **gsyms;
int dbgblocknum;
DBGBLOCK *DbgBlocks[2048];

int intrinsxlate[] = 
{
    T_BOOL08, T_CHAR, T_UCHAR, T_INT8, T_SHORT, T_USHORT, T_INT4, T_UINT4,
        T_INT4, T_UINT4, T_INT8, T_UINT8, T_REAL32, T_REAL64, T_REAL80,
        T_IMAGINARY32, T_IMAGINARY64, T_IMAGINARY80, T_CPLX32, T_CPLX64, T_CPLX80, T_VOID
};
int debug_outputtype(TYP *type);
static void emitsym(char *buf);
static void out_sym_header(void);

static DBGBLOCK *dbgblock,  *currentblock;
static int nexttype, funcSyms, blockSyms, symSize;
static int lastfuncoffset;

void dbginit(void)
{
    int v = CV_SIGNATURE_32BIT;
    nexttype = CV_FIRST_NONPRIM;
    if (prm_debug)
    {
        emit(typeseg, &v, 4);
        emit(symseg, &v, 4);
    }
    lastfuncoffset = 0;
}

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

static int emittype(char *buf)
{
    int v = 0, len;
    len = *((short*)buf) + 2;
    if (len % 4)
    {
        *(int*)(buf + len) = 0;
        *(short*)buf += 4-len % 4;
        len += 4-len % 4;
    }
    emit(typeseg, buf, len);
}

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

static void emitsym(char *buf)
{
    int v = 0, len;
    len = *((short*)buf) + 2;
    if (len % 4)
    {
        *(int*)(buf + len) = 0;
        *(short*)buf += 4-len % 4;
        len += 4-len % 4;
    }
    emit(symseg, buf, len);
}

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

static int isintrins(TYP *type, int allowptr)
{
    int v;
    if (type->typeindex &&  *type->typeindex)
    {
        return  *type->typeindex; /* its in the table or an intrinsic that has
            been looked up */
    }
    if (allowptr && type->type == bt_pointer)
    {
        if (type->val_flag &VARARRAY)
            return 0;
        // will be handled separately
        if (type->btp == bt_pointer && (type->btp->val_flag &VARARRAY))
            return 0;
        if (v = isintrins(type, FALSE))
            if (v < CV_FIRST_NONPRIM && !(type->cflags &(DF_CONST | DF_VOL)))
                return v | (CV_TM_NPTR32 << CV_MSHIFT);
    }
    else if (allowptr && type->type == bt_farpointer)
    {
        if (v = isintrins(type, FALSE))
            if (v < CV_FIRST_NONPRIM && !(type->cflags &(DF_CONST | DF_VOL)))
                return v | (CV_TM_FPTR32 << CV_MSHIFT);
    }
    else if (allowptr && type->type == bt_segpointer)
    {
        v = CV_SP_SEGMENT << CV_SSHIFT;
    }
    else
    {
        if (type->type < sizeof(intrinsxlate) / sizeof(int) && type->type !=
            bt_enum)
            return intrinsxlate[type->type];
        // relies on the type table being ordered
    }

    return 0;
}

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

int numeric_leaf(char *buf, unsigned int size)
{
    if (size < LF_NUMERIC)
    {
        *(short*)buf = size;
        return 2;
    }
    else
    {
        *(short*)buf = LF_LONG;
        *(int*)(buf + 2) = size;
        return 6;
    }
}

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

int debug_outputpointer(TYP *type)
{
    char buf[100];
    int val;
    if (!type->val_flag)
    {
        lfPointer *ptr = buf + 2;
        val = debug_outputtype(type->btp);
        if (CV_IS_PRIMITIVE(val) && CV_MODE(val) == CV_TM_DIRECT)
        {
            if (type->type == bt_pointer)
                val = CV_NEWMODE(val, CV_TM_NPTR32);
            else
                val = CV_NEWMODE(val, CV_TM_FPTR32);
        }
        else
        {
            memset(buf, 0, 100);
            ptr->u.leaf = LF_POINTER;
            if (type->type == bt_pointer)
                ptr->u.attr.ptrtype = CV_PTR_NEAR32;
            else
                ptr->u.attr.ptrtype = CV_PTR_FAR32;
            ptr->u.attr.ptrmode = CV_PTR_MODE_PTR;
            ptr->u.attr.isflat32 = TRUE;
            ptr->u.attr.isvolatile = !!(type->cflags &DF_VOL);
            ptr->u.attr.isconst = !!(type->cflags &DF_CONST);
            ptr->u.utype = val;
            *(short*)buf = sizeof(lfPointer); // we are cheating here
            emittype(buf);
            val = nexttype++;
        }
    }
    else
    {
        int indexes[100];
        int i = 0, len;
        lfArray *ptr = buf + 2;
        if (type->val_flag &VARARRAY)
        {
            varjoin: ptr->leaf = LF_VARARRAY; 
                // LF_VARARRAY is NOT one of the original types
            type = type->btp;
            while (type->esize)
                type = type->btp;
        }
        else if (type->btp == bt_pointer && (type->btp->val_flag &VARARRAY))
        {
            type = type->btp;
            goto varjoin;
        }
        else
        {
            ptr->leaf = LF_ARRAY;
            type = type->btp;
        }
        val = debug_outputtype(type);
        ptr->elemtype = val;
        ptr->idxtype = T_INT4;
        len = numeric_leaf(ptr->data, type->size); 
            // size of base type for vararray
        len = sizeof(lfArray) - 1+len;
        *(short*)buf = len;
        emittype(buf);
        val = nexttype++;
    }
    return val;
}

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

int debug_outputref(TYP *type)
{
    char buf[100];
    int val = debug_outputtype(type->btp);
    lfPointer *ptr = buf + 2;
    ptr->u.leaf = LF_POINTER;
    ptr->u.attr.ptrtype = CV_PTR_NEAR32;
    ptr->u.attr.ptrmode = CV_PTR_MODE_REF;
    ptr->u.attr.isflat32 = TRUE;
    ptr->u.attr.isvolatile = !!(type->cflags &DF_VOL);
    ptr->u.attr.isconst = !!(type->cflags &DF_CONST);
    ptr->u.utype = val;
    *(short*)buf[0] = sizeof(lfPointer);
    emittype(buf);
    val = nexttype++;
    return val;
}

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

static int putname(char *buf, char *name)
{
    char internal[256];
    int len;
    unmangle(internal, name);
    len = strlen(internal);
    *buf++ = len++;
    strcpy(buf, internal);
    return len;
}

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

static int outputFields(SYM *field, int *count)
{
    char buffer[1024],  *p = buffer + 4;
    int val = 0;
    memset(buffer, 0, 1024);
    while (field)
    {
        if (field->tp->type != bt_defunc)
        {
            char qbuf[256];
            int len;
            lfMember *ptr = qbuf;
            memset(qbuf, 0, 256);
            ptr->leaf = LF_MEMBER;
            ptr->index = debug_outputtype(field->tp);
            len = numeric_leaf(ptr->offset, field->value.i);
            len += putname(ptr->offset + len, field->name) + sizeof(lfMember) -
                1;
            if (len % 4)
            {
                qbuf[len] = 0xf0 + 4-len % 4;
                len += 4-len % 4;
            }
            if (p - buffer + len < 1024-sizeof(lfIndex))
            {
                memcpy(p, qbuf, len);
                p += len;
                (*count)++;
            }
            else
            {
                lfIndex *ptr = p;
                val = outputFields(field, count);
                ptr->leaf = LF_INDEX;
                ptr->index = val;
                p += sizeof(lfIndex);
                break;
            }
        }
        field = field->next;
    }
    *(short*)(buffer + 2) = LF_FIELDLIST;
    *(short*)buffer = p - buffer - 2;
    emittype(buffer);
    return nexttype++;
}

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

static int debug_outputnamesym(TYP *type, int idx)
{
    char buf[256];
    if (type->sp->name)
    {
        UDTSYM *us = buf;
        us->reclen = sizeof(UDTSYM) + putname(us->name, type->sp->name);
        us->rectyp = S_UDT;
        us->typind = idx;
        emitsym(buf);
    }
}

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

static int debug_outputstruct(TYP *type)
{
    char buf[256];
    int thetype = nexttype++;
    int count = 0, len;
    int val, offset, typeofs, countofs;
    memset(buf, 0, 256);

    offset = segs[typeseg].last->filled + segs[typeseg].last->address;

    /* fill in the type now to prevent recursion */
    if (!type->typeindex)
    {
        global_flag++;
        type->typeindex = xalloc(sizeof(int));
        global_flag--;
    }
    *type->typeindex = thetype;

    if (type->type == bt_union)
    {
        lfUnion *ptr = buf + 2;
        ptr->leaf = LF_UNION;
        ptr->count = 0;
        ptr->property.packed = type->alignment < 2;
        ptr->field = 0;
        len = numeric_leaf(ptr->data, type->size);
        len += putname(ptr->data + len, type->sp->name);
        len += sizeof(lfUnion) - 1;
        typeofs = (char*) &ptr->field - (char*)ptr + 2;
        countofs = (char*) &ptr->count - (char*)ptr + 2;
    }
    else
    {
        lfClass *ptr = buf + 2;
        ptr->leaf = type->type == bt_class ? LF_CLASS : LF_STRUCTURE;
        ptr->count = 0;
        ptr->property.packed = type->alignment < 2;
        ptr->field = 0;
        len = numeric_leaf(ptr->data, type->size);
        len += putname(ptr->data + len, type->sp->name);
        len += sizeof(lfClass) - 1;
        typeofs = (char*) &ptr->field - (char*)ptr + 2;
        countofs = (char*) &ptr->count - (char*)ptr + 2;
    }

    *(short*)buf = len;
    emittype(buf);

    val = outputFields(type->lst.head, &count);

    /* have to go back after the fact and fill in the type and count */
    write_to_seg(typeseg, offset + typeofs, &val, sizeof(CV_typ_t));
    write_to_seg(typeseg, offset + countofs, &count, sizeof(unsigned short));

    debug_outputnamesym(type, thetype);

    return thetype;

}

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

static int enumfields(SYM *field, int *count)
{
    char buffer[1024],  *p = buffer + 4;
    int val = 0;
    memset(buffer, 0, 1024);
    while (field)
    {
        char qbuf[256];
        int len;
        lfEnumerate *ptr = qbuf;
        memset(qbuf, 0, 256);
        ptr->leaf = LF_ENUMERATE;
        len = numeric_leaf(ptr->value, field->value.i);
        len += putname(ptr->value + len, field->name);
        len += sizeof(lfEnumerate) - 1;
        if (len % 4)
        {
            qbuf[len] = 0xf0 + 4-len % 4;
            len += 4-len % 4;
        }
        if (p - buffer + len < 1024-sizeof(lfIndex))
        {
            memcpy(p, qbuf, len);
            p += len;
            (*count)++;
        }
        else
        {
            lfIndex *ptr = p;
            val = enumfields(field, count);
            ptr->leaf = LF_INDEX;
            ptr->index = val;
            p += sizeof(lfIndex);
            break;
        }
        field = field->enumlist;
    }
    *(short*)(buffer + 2) = LF_FIELDLIST;
    *(short*)buffer = p - buffer - 2;
    emittype(buffer);
    return nexttype++;
}

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

int debug_outputenum(TYP *type)
{
    char buf[256];

    lfEnum *enu = buf + 2;
    int count = 0, val, len;
    memset(buf, 0, 256);
    val = enumfields(type->enumlist, &count);
    enu->leaf = LF_ENUM;
    enu->utype = T_INT4;
    enu->count = count;
    enu->field = val;
    putname(enu->Name, type->sp->name);
    len =  *enu->Name + 1+sizeof(lfEnum) - 1;
    *(short*)buf = len;
    emittype(buf);

    debug_outputnamesym(type, nexttype);

    return nexttype++;
}

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

int debug_outputtypell(TYP *type)
{
    int val = 0;
    if (val = isintrins(type, TRUE))
    {
        if (!type->typeindex)
        {
            global_flag++;
            type->typeindex = xalloc(sizeof(int));
            global_flag--;
        }
        return  *type->typeindex = val;
    }
    switch (type->type)
    {
        case bt_pointer:
            val = debug_outputpointer(type);
            break;
        case bt_ref:
            val = debug_outputref(type);
            break;
        case bt_struct:
            val = debug_outputstruct(type);
            break;
        case bt_union:
            val = debug_outputstruct(type);
            break;
        case bt_class:
            val = debug_outputstruct(type);
            break;
        case bt_enum:
            val = debug_outputenum(type);
            break;
        case bt_func:
             /* function ptr */
            /* FIXME - should do something more elaborate than this but don't know what
             * and need to work on something else
             */
            val = T_VOID;
            break;
        default:
            DIAG("debug_outputtype: unhandled type");
            break;
    }
    if (!type->typeindex)
        type->typeindex = xalloc(sizeof(int));
    return  *type->typeindex = val;

⌨️ 快捷键说明

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