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

📄 obj386.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 2 页
字号:
                return sp->mainsym->value.i;
            }
        default:
            DIAG("Unknown segment type in omfGetSeg");
            DIAG(sp->name);
            return codeseg;
    }
    // also fix the value.i field of local funcs...
}

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

void omfputpub(SYM *sp)
{
    int l = 0;
    char buf[512], obuf[512];

    int seg, group, pos;
    if (sp->gennedvirtfunc)
        return ;
    if (sp->value.classdata.templatedata)
        return ;
    if (sp->value.classdata.cppflags &PF_INLINE)
        return ;
    if ((sp->tp->cflags &DF_CONST) && scalarnonfloat(sp->tp) && sp
        ->storage_class == sc_static)
        return ;
    seg = omfgetseg(sp);
    putsym(buf, sp, sp->name);
    if (seg != 1 && !(seg &0xc0000000))
        group = 1;
    else
        group = 0;
    obuf[0] = group;
    l += put_ident(obuf + 1, seg) - 1;
    pos = (obuf[2+l] = strlen(buf)) + 3;
    strcpy(obuf + 3+l, buf);
    *(int*)(obuf + pos + l) = sp->mainsym->offset;
    obuf[pos + 4+l] = 0;
    emit_record(PUBDEF, obuf, pos + 5+l);
}

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

void omfpubdumphash(HASHREC **syms)
{
    int i;
    SYM *sp;
    for (i = 0; i < HASHTABLESIZE; i++)
    {
        if ((sp = (SYM*)syms[i]) != 0)
        {
            while (sp)
            {
                if (sp->storage_class == sc_global && !(sp
                    ->value.classdata.cppflags &PF_INLINE))
                {
                    omfputpub(sp);
                }
                if (sp->storage_class == sc_defunc)
                {
                    SYM *sp1 = sp->tp->lst.head;
                    while (sp1)
                    {
                        if (sp1->storage_class == sc_global && !(sp
                            ->value.classdata.cppflags &PF_INLINE))
                        {
                            omfputpub(sp1);
                        }
                        sp1 = sp1->next;
                    }
                }
                if (sp->storage_class == sc_namespace && !sp
                    ->value.classdata.parentns->anonymous)
                    omfpubdumphash(sp->value.classdata.parentns->table);


                sp = sp->next;
            }
        }
    }
}

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

void omfPublics(void)
{
    SYM *sp;
    LIST *lf = localfuncs;
    int i;
    omfpubdumphash(gsyms);
    while (lf)
    {
        SYM *sp = lf->data;
        if (sp->storage_class == sc_global && !(sp->value.classdata.cppflags
            &PF_INLINE))
        {
            omfputpub(sp);
        }
        lf = lf->link;
    }
    for (i = 0; i < HASHTABLESIZE; i++)
    {
        struct _templatelist *tl;
        if ((tl = (struct templatelist*)templateFuncs[i]) != 0)
        {
            while (tl)
            {
                if (tl->sp->value.classdata.templatedata->hasbody && tl
                    ->finalsp)
                {
                    omfputpub(tl->finalsp);
                } tl = tl->next;
            }
        }
    }
}

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

void omfputexport(SYM *sp)
{
    char buf[512], obuf[512];
    int l;
    putsym(buf, sp, sp->name);
    l = strlen(buf);
    *(short*)obuf = 0xa000;
    obuf[2] = 2; // export
    obuf[3] = 0; // export flags
    obuf[4] = l;
    strcpy(obuf + 5, buf);
    buf[5+l] = l;
    strcpy(obuf + 6+l, buf);

    emit_record(COMENT, obuf, 6+2 * l);
}

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

void omfExports(void)
{
    SYM *sp;
    int i;
    LIST *lf = localfuncs;
    while (lf)
    {
        sp = lf->data;
        if (sp->storage_class == sc_global && sp->mainsym->exportable && !(sp->value.classdata.cppflags & PF_INLINE))
        {
            omfputexport(sp);
        }
        lf = lf->link;
    }
    for (i = 0; i < HASHTABLESIZE; i++)
    {
        if ((sp = (SYM*)gsyms[i]) != 0)
        {
            while (sp)
            {
                if (sp->storage_class == sc_global && sp->mainsym->exportable)
                {
                    omfputexport(sp);
                }
                if (sp->storage_class == sc_defunc) {
                    SYM *sp1 = sp->tp->lst.head ;
                    while (sp1) {
                        if (sp1->storage_class == sc_global && sp1->mainsym->exportable && 
                                !(sp1->value.classdata.cppflags & PF_INLINE))
                        {
                            omfputexport(sp1);
                        }
                        sp1 = sp1->next;
                    }
                }
                sp = sp->next;
            }
        }
    }
}

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

void omfPassSeperator(void)
{
    char buf[3];
    buf[0] = 0x40;
    buf[1] = 0xa2;
    buf[2] = 0x01;
    emit_record(COMENT, buf, 3);
}

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

int omfFixups(int seg, EMIT_LIST *rec, char *data, char *buf, int *len)
{
    int indent = 0, pos = 0;
    int fixeddat = FALSE;
    FIXUP *fixups = rec->fixups;
    while (fixups)
    {
        SYM *sp;
        int rel = FALSE, iseg;
        int fixdat = 0, tdat;
        int offset = fixups->address - rec->address;
        int locat = (offset >> 8) + (offset << 8);
        int segrel = FALSE;
        switch (fixups->fmode)
        {
            case fm_relsymbol:
                rel = TRUE;
            case fm_symbol:
                if (fixups->sym->storage_class == sc_abs)
                {
                    if (rel)
                        DIAG("Relative absolute in omfFixups");
                    else
                        *(int*)(rec->data + offset) += sp->mainsym->offset;
                    continue;
                }
                iseg = omfgetseg(fixups->sym);
                {
                    SYM *sp = fixups->sym;
                    if (sp->mainsym)
                        sp = sp->mainsym;
                    if (sp->storage_class == sc_member && sp
                        ->value.classdata.gdeclare && sp
                        ->value.classdata.gdeclare->storage_class == sc_global)
                        sp = sp->value.classdata.gdeclare;
                    if (sp->storage_class == sc_global || sp->storage_class ==
                        sc_static || (sp->storage_class == sc_external || sp
                        ->storage_class == sc_externalfunc) && !sp->mainsym
                        ->extflag)
                    {
                        if (rel)
                        {
                            if (iseg == seg)
                            {
                                *(int*)(data + offset) = sp->mainsym->offset -
                                    fixups->address - 4;
                            }
                            else
                            {
                                locat |= 0xa4;
                                fixdat = 0x54;
                                if (!(iseg &0xc0000000))
                                    tdat = segxlattab[iseg];
                                else
                                    tdat = iseg;
                                segrel = TRUE;
                                *(int*)(data + offset) = sp->mainsym->offset;
                            }
                        }
                        else
                        {
                            locat |= 0xe4;
                            fixdat = 0x04;
                            if (!(iseg &0xc0000000))
                                tdat = segxlattab[iseg];
                            else
                                tdat = iseg;
                            //							printf("%s:%x:%x:%p:%p\n",sp->name,sp->offset,sp->mainsym->offset,sp,sp->mainsym) ;
                            *(int*)(data + offset) += sp->mainsym->offset;
                            segrel = TRUE;
                        }
                        /* segment relative */
                    }
                    else
                    {
                        if (rel)
                        {
                            locat |= 0xa4;
                            fixdat = 0x56;
                            tdat = sp->value.i;
                        }
                        else
                        {
                            locat |= 0xe4;
                            fixdat = 0x06;
                            tdat = sp->value.i;
                        }
                        /* extdef relative */
                    }
                }
                break;

            case fm_rellabel:
                rel = TRUE;
            case fm_label:
                iseg = LabelSeg(fixups->label);
                if (rel)
                {
                    if (iseg == seg)
                        *(int*)(data + offset) = LabelAddress(fixups->label) -
                            fixups->address - 4;
                    else
                    {
                        locat |= 0xa4;
                        fixdat = 0x54;
                        if (!(iseg &0xc0000000))
                            tdat = segxlattab[iseg];
                        else
                            tdat = iseg;
                    }
                }
                else
                {
                    *(int*)(data + offset) += LabelAddress(fixups->label);
                    locat |= 0xe4;
                    fixdat = 0x04;
                    if (!(iseg &0xc0000000))
                        tdat = segxlattab[iseg];
                    else
                        tdat = iseg;
                    segrel = TRUE;
                }
                /* segment relative */
                break;
        }
        if (fixdat)
        {
            int len = 5+((tdat &0x3fffffff) > 127) + !!(tdat &0xc0000000);
            if (!fixeddat && pos + len >= 1024)
            {
                fixeddat = TRUE;
                indent = 1024-pos;
                pos = 1024;
            }
            buf[pos++] = locat &0xff;
            buf[pos++] = locat >> 8;
            if ((fixdat &0x70) == 0x00)
            {
                if (segrel && (tdat == 2 || tdat == 3 || tdat == segxlattab[4] 
                    || tdat == segxlattab[5]))
                {
                    buf[pos++] = fixdat | 0x10; /* grouped, 1st group */
                    buf[pos++] = 1;
                }
                else
                    buf[pos++] = fixdat | 0x50;
            }
            else
                buf[pos++] = fixdat;
            pos += put_ident(buf + pos, tdat);
            if (tdat == 0)
                DIAG("omfFixups - null index");
        }
        fixups = fixups->next;
    }
    *len = pos;
    return indent;
}

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

void omfComDefData(void)
{
    VIRTUAL_LIST *v = virtualFirst;
    char buf[1500],  *p;
    while (v)
    {
        EMIT_LIST *rec = v->seg->first;
        while (rec)
        {
            int indent;
            int len;
            char fbuf[2048];
            p = buf;
            p += put_ident(p, v->sp->value.i);
            *((int*)(p))++ = rec->address;
            memcpy(p, rec->data, rec->filled);
            indent = omfFixups(virtseg, rec, p, fbuf, &len);
            emit_record(LEDATA, buf, rec->filled + p - buf);
            if (len)
                if (len < 1024)
                    emit_record(FIXUPP, fbuf, len);
                else
            {
                emit_record(FIXUPP, fbuf, 1024-indent);
                emit_record(FIXUPP, fbuf + 1024, len - 1024);
            }
            rec = rec->next;
        }
        v = v->next;
    }
}

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

void omfData(void)
{
    char buf[1100];
    int i;
    for (i = 1; i < MAX_SEGS; i++)
    if (segxlattab[i] && segs[i].curlast)
    {
        if (i == bssxseg)
        {
            buf[0] = segxlattab[i];
            *(int*)(buf + 1) = 0; /* offset */
            *(int*)(buf + 5) = segs[i].curlast; /* repeat count */
            *(short*)(buf + 9) = 0; /* block count */
            *(buf + 11) = 1; /* num bytes */
            *(buf + 12) = 0; /* data */
            emit_record(LIDATA, buf, 13);
        }
        else
        {
            EMIT_LIST *rec = segs[i].first;
            while (rec)
            {
                int indent;
                int len;
                char fbuf[2048];
                buf[0] = segxlattab[i];
                *(int*)(buf + 1) = rec->address;
                memcpy(buf + 5, rec->data, rec->filled);
                indent = omfFixups(i, rec, buf + 5, fbuf, &len);
                emit_record(LEDATA, buf, rec->filled + 5);
                if (len)
                    if (len < 1024)
                        emit_record(FIXUPP, fbuf, len);
                    else
                {
                    emit_record(FIXUPP, fbuf, 1024-indent);
                    emit_record(FIXUPP, fbuf + 1024, len - 1024);
                }
                rec = rec->next;
            }
        }
    }
}

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

void omfSourceFile(char *file, int num)
{
    unsigned short time, date;
    char buf[256];
    int fd;
    *(short*)buf = 0xe800;
    buf[2] = num;
    strcpy(buf + 4, fullqualify(file));
    buf[3] = strlen(buf + 4);
    if (_dos_open(file, 0, &fd))
    {
        time = 0;
        date = 0;
    }
    else
    {
        _dos_getftime(fd, &date, &time);
        _dos_close(fd);
    }
    *(short*)(buf + 4+buf[3]) = time;
    *(short*)(buf + 6+buf[3]) = date;
    emit_record(COMENT, buf, 8+buf[3]);
}

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

void omfLineNumbers(int file)
{
    LINEBUF *l = linelist;
    char buf[1100],  *p;
    int lastnum =  - 1;
    while (l)
    {
        p = buf;
        *p++ = 0;
        *p++ = segxlattab[codeseg];
        while (l && p - buf < 1024-6)
        {
            if (l->file == file)
            {
                //            if (l->address != lastnum) {
                *(short*)p = l->lineno;
                *(int*)(p + 2) = l->address;
                p += 6;
                lastnum = l->address;
                //            }
            }
            l = l->next;
        }
        if (p - buf > 2)
        {
            emit_record(LINNUM, buf, p - buf);
        }
    }
}

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

void omfEmitLineInfo(void)
{
    int i, q;
    FILELIST *l;
    omfSourceFile(infile, 1);
    omfLineNumbers(0);
    for (i = 1, q = 2, l = incfiles; l; i++, l = l->link)
    if (l->hascode)
    {
        omfSourceFile(l->data, q++);
        omfLineNumbers(i);
    }
}

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

void omfModEnd(void)
{
    char buf = 0;
    emit_record(MODEND, &buf, 1);
}

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

void output_obj_file(void)
{
    LIST *l = incfiles;
    extIndex = extSize = 0;
    omfFileName();
    omfTranslatorName();
    omfFileTime(fullqualify(infile));
    while (l)
    {
        omfFileTime(l->data);
        l = l->link;
    }
    omfFileTime(0);
    omfDebugMarker();
    omfLibMod();
    omfLNames();
    omfSegs();
    omfComDefs();
    omfGroups();
    omfExtDefs();
    omfImports();
    omfPublics();
    omfExports();
    omfPassSeperator();
    if (prm_debug)
        omfEmitLineInfo();
    omfComDefData();
    omfData();
    omfModEnd();
}

⌨️ 快捷键说明

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