예제 #1
0
파일: cv8.c 프로젝트: jasonwhite/dmd
/*******************************************
 * Put out a name for a user defined type.
 * Input:
 *      id      the name
 *      typidx  and its type
 */
void cv8_udt(const char *id, idx_t typidx)
{
    //printf("cv8_udt('%s', %x)\n", id, typidx);
    Outbuffer *buf = currentfuncdata.f1buf;
    size_t len = strlen(id);

    if (len > CV8_MAX_SYMBOL_LENGTH)
        len = CV8_MAX_SYMBOL_LENGTH;
    buf->reserve(2 + 2 + 4 + len + 1);
    buf->writeWordn( 2 + 4 + len + 1);
    buf->writeWordn(S_UDT_V3);
    buf->write32(typidx);
    cv8_writename(buf, id, len);
    buf->writeByte(0);
}
예제 #2
0
파일: cv8.c 프로젝트: jasonwhite/dmd
void cv8_outsym(Symbol *s)
{
    //printf("cv8_outsym(s = '%s')\n", s->Sident);
    //type_print(s->Stype);
    //symbol_print(s);
    if (s->Sflags & SFLnodebug)
        return;

    idx_t typidx = cv_typidx(s->Stype);
    //printf("typidx = %x\n", typidx);
    const char *id = s->prettyIdent ? s->prettyIdent : prettyident(s);
    size_t len = strlen(id);

    if(len > CV8_MAX_SYMBOL_LENGTH)
        len = CV8_MAX_SYMBOL_LENGTH;

    F1_Fixups f1f;
    Outbuffer *buf = currentfuncdata.f1buf;

    unsigned sr;
    unsigned base;
    switch (s->Sclass)
    {
        case SCparameter:
        case SCregpar:
        case SCshadowreg:
            if (s->Sfl == FLreg)
            {
                s->Sfl = FLpara;
                cv8_outsym(s);
                s->Sfl = FLreg;
                goto case_register;
            }
            base = Para.size - BPoff;    // cancel out add of BPoff
            goto L1;
        case SCauto:
            if (s->Sfl == FLreg)
                goto case_register;
        case_auto:
            base = Auto.size;
        L1:
#if 1
            // Register relative addressing
            buf->reserve(2 + 2 + 4 + 4 + 2 + len + 1);
            buf->writeWordn( 2 + 4 + 4 + 2 + len + 1);
            buf->writeWordn(0x1111);
            buf->write32(s->Soffset + base + BPoff);
            buf->write32(typidx);
            buf->writeWordn(I64 ? 334 : 22);       // relative to RBP/EBP
            cv8_writename(buf, id, len);
            buf->writeByte(0);
#else
            // This is supposed to work, implicit BP relative addressing, but it does not
            buf->reserve(2 + 2 + 4 + 4 + len + 1);
            buf->writeWordn( 2 + 4 + 4 + len + 1);
            buf->writeWordn(S_BPREL_V3);
            buf->write32(s->Soffset + base + BPoff);
            buf->write32(typidx);
            cv8_writename(buf, id, len);
            buf->writeByte(0);
#endif
            break;

        case SCbprel:
            base = -BPoff;
            goto L1;

        case SCfastpar:
            if (s->Sfl != FLreg)
            {   base = Fast.size;
                goto L1;
            }
            goto L2;

        case SCregister:
            if (s->Sfl != FLreg)
                goto case_auto;
        case SCpseudo:
        case_register:
        L2:
            buf->reserve(2 + 2 + 4 + 2 + len + 1);
            buf->writeWordn( 2 + 4 + 2 + len + 1);
            buf->writeWordn(S_REGISTER_V3);
            buf->write32(typidx);
            buf->writeWordn(cv8_regnum(s));
            cv8_writename(buf, id, len);
            buf->writeByte(0);
            break;

        case SCextern:
            break;

        case SCstatic:
        case SClocstat:
            sr = S_LDATA_V3;
            goto Ldata;
        case SCglobal:
        case SCcomdat:
        case SCcomdef:
            sr = S_GDATA_V3;
        Ldata:
//return;
            /*
             *  2       length (not including these 2 bytes)
             *  2       S_GDATA_V2
             *  4       typidx
             *  6       ref to symbol
             *  n       0 terminated name string
             */
            if (s->ty() & mTYthread)            // thread local storage
                sr = (sr == S_GDATA_V3) ? 0x1113 : 0x1112;

            buf->reserve(2 + 2 + 4 + 6 + len + 1);
            buf->writeWordn(2 + 4 + 6 + len + 1);
            buf->writeWordn(sr);
            buf->write32(typidx);

            f1f.s = s;
            f1f.offset = buf->size();
            F1fixup->write(&f1f, sizeof(f1f));
            buf->write32(0);
            buf->writeWordn(0);

            cv8_writename(buf, id, len);
            buf->writeByte(0);
            break;

        default:
            break;
    }
}
예제 #3
0
파일: cv8.c 프로젝트: jasonwhite/dmd
void cv8_func_term(Symbol *sfunc)
{
    //printf("cv8_func_term(%s)\n", sfunc->Sident);

    assert(currentfuncdata.sfunc == sfunc);
    currentfuncdata.section_length = retoffset + retsize;

    funcdata->write(&currentfuncdata, sizeof(currentfuncdata));

    // Write function symbol
    assert(tyfunc(sfunc->ty()));
    idx_t typidx;
    func_t* fn = sfunc->Sfunc;
    if(fn->Fclass)
    {
        // generate member function type info
        // it would be nicer if this could be in cv4_typidx, but the function info is not available there
        unsigned nparam;
        unsigned char call = cv4_callconv(sfunc->Stype);
        idx_t paramidx = cv4_arglist(sfunc->Stype,&nparam);
        unsigned next = cv4_typidx(sfunc->Stype->Tnext);

        type* classtype = (type*)fn->Fclass;
        unsigned classidx = cv4_typidx(classtype);
        type *tp = type_allocn(TYnptr, classtype);
        unsigned thisidx = cv4_typidx(tp);  // TODO
        debtyp_t *d = debtyp_alloc(2 + 4 + 4 + 4 + 1 + 1 + 2 + 4 + 4);
        TOWORD(d->data,LF_MFUNCTION_V2);
        TOLONG(d->data + 2,next);       // return type
        TOLONG(d->data + 6,classidx);   // class type
        TOLONG(d->data + 10,thisidx);   // this type
        d->data[14] = call;
        d->data[15] = 0;                // reserved
        TOWORD(d->data + 16,nparam);
        TOLONG(d->data + 18,paramidx);
        TOLONG(d->data + 22,0);  // this adjust
        typidx = cv_debtyp(d);
    }
    else
        typidx = cv_typidx(sfunc->Stype);

    const char *id = sfunc->prettyIdent ? sfunc->prettyIdent : prettyident(sfunc);
    size_t len = strlen(id);
    if(len > CV8_MAX_SYMBOL_LENGTH)
        len = CV8_MAX_SYMBOL_LENGTH;
    /*
     *  2       length (not including these 2 bytes)
     *  2       S_GPROC_V3
     *  4       parent
     *  4       pend
     *  4       pnext
     *  4       size of function
     *  4       size of function prolog
     *  4       offset to function epilog
     *  4       type index
     *  6       seg:offset of function start
     *  1       flags
     *  n       0 terminated name string
     */
    Outbuffer *buf = currentfuncdata.f1buf;
    buf->reserve(2 + 2 + 4 * 7 + 6 + 1 + len + 1);
    buf->writeWordn( 2 + 4 * 7 + 6 + 1 + len + 1);
    buf->writeWordn(sfunc->Sclass == SCstatic ? S_LPROC_V3 : S_GPROC_V3);
    buf->write32(0);            // parent
    buf->write32(0);            // pend
    buf->write32(0);            // pnext
    buf->write32(currentfuncdata.section_length);       // size of function
    buf->write32(startoffset);          // size of prolog
    buf->write32(retoffset);                    // offset to epilog
    buf->write32(typidx);

    F1_Fixups f1f;
    f1f.s = sfunc;
    f1f.offset = buf->size();
    currentfuncdata.f1fixup->write(&f1f, sizeof(f1f));
    buf->write32(0);
    buf->writeWordn(0);

    buf->writeByte(0);
    buf->writen(id, len);
    buf->writeByte(0);

    // Write local symbol table
    bool endarg = false;
    for (SYMIDX si = 0; si < globsym.top; si++)
    {   //printf("globsym.tab[%d] = %p\n",si,globsym.tab[si]);
        symbol *sa = globsym.tab[si];
        if (endarg == false &&
            sa->Sclass != SCparameter &&
            sa->Sclass != SCfastpar &&
            sa->Sclass != SCshadowreg)
        {
            buf->writeWord(2);
            buf->writeWord(S_ENDARG);
            endarg = true;
        }
        cv8_outsym(sa);
    }

    /* Put out function return record S_RETURN
     * (VC doesn't, so we won't bother, either.)
     */

    // Write function end symbol
    buf->writeWord(2);
    buf->writeWord(S_END);

    currentfuncdata.f1buf = F1_buf;
    currentfuncdata.f1fixup = F1fixup;
}