Esempio n. 1
0
int VarDeclaration::cvMember(unsigned char *p)
{
    char *id;
    idx_t typidx;
    unsigned attribute;
    int nwritten = 0;

    //printf("VarDeclaration::cvMember(p = %p) '%s'\n", p, toChars());

    if (type->toBasetype()->ty == Ttuple)
	return 0;

    id = toChars();

    if (!p)
    {
	if (storage_class & STCfield)
	{
	    nwritten += 6 +
		    cv4_numericbytes(offset) + cv_stringbytes(id);
	}
	else if (isStatic())
	{
	    nwritten += 6 + cv_stringbytes(id);
	}
    }
    else if (storage_class & STCfield)
    {
	TOWORD(p,LF_MEMBER);
	typidx = cv_typidx(type->toCtype());
	attribute = PROTtoATTR(prot());
	assert((attribute & ~3) == 0);
	TOWORD(p + 2,typidx);
	TOWORD(p + 4,attribute);
	cv4_storenumeric(p + 6, offset);
	nwritten = 6 + cv4_numericbytes( offset);
	nwritten += cv_namestring(p + nwritten, id);
    }
    else if (isStatic())
    {
	TOWORD(p,LF_STMEMBER);
	typidx = cv_typidx(type->toCtype());
	attribute = PROTtoATTR(prot());
	assert((attribute & ~3) == 0);
	TOWORD(p + 2,typidx);
	TOWORD(p + 4,attribute);
	nwritten = 6 + cv_namestring(p + 6, id);
    }
    return nwritten;
}
Esempio n. 2
0
File: cv8.c Progetto: 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;
    }
}
Esempio n. 3
0
File: cv8.c Progetto: 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;
}
Esempio n. 4
0
int VarDeclaration::cvMember(unsigned char *p)
{
    int nwritten = 0;

    //printf("VarDeclaration::cvMember(p = %p) '%s'\n", p, toChars());

    if (type->toBasetype()->ty == Ttuple)
        return 0;

    char *id = toChars();

    if (!p)
    {
        if (isField())
        {
            if (config.fulltypes == CV8)
                nwritten += 2;
            nwritten += 6 + cv_stringbytes(id);
            nwritten += cv4_numericbytes(offset);
        }
        else if (isStatic())
        {
            if (config.fulltypes == CV8)
                nwritten += 2;
            nwritten += 6 + cv_stringbytes(id);
        }
        nwritten = cv_align(NULL, nwritten);
    }
    else
    {
        idx_t typidx = cv_typidx(type->toCtype());
        unsigned attribute = PROTtoATTR(prot());
        assert((attribute & ~3) == 0);
        switch (config.fulltypes)
        {
            case CV8:
                if (isField())
                {
                    TOWORD(p,LF_MEMBER_V3);
                    TOWORD(p + 2,attribute);
                    TOLONG(p + 4,typidx);
                    cv4_storenumeric(p + 8, offset);
                    nwritten = 8 + cv4_numericbytes( offset);
                    nwritten += cv_namestring(p + nwritten, id);
                }
                else if (isStatic())
                {
                    TOWORD(p,LF_STMEMBER_V3);
                    TOWORD(p + 2,attribute);
                    TOLONG(p + 4,typidx);
                    nwritten = 8;
                    nwritten += cv_namestring(p + nwritten, id);
                }
                break;

            case CV4:
                if (isField())
                {
                    TOWORD(p,LF_MEMBER);
                    TOWORD(p + 2,typidx);
                    TOWORD(p + 4,attribute);
                    cv4_storenumeric(p + 6, offset);
                    nwritten = 6 + cv4_numericbytes( offset);
                    nwritten += cv_namestring(p + nwritten, id);
                }
                else if (isStatic())
                {
                    TOWORD(p,LF_STMEMBER);
                    TOWORD(p + 2,typidx);
                    TOWORD(p + 4,attribute);
                    nwritten = 6;
                    nwritten += cv_namestring(p + nwritten, id);
                }
                break;

             default:
                assert(0);
        }

        nwritten = cv_align(p + nwritten, nwritten);
#ifdef DEBUG
        assert(nwritten == cvMember(NULL));
#endif
    }
    return nwritten;
}
Esempio n. 5
0
        void visit(VarDeclaration *vd)
        {
            //printf("VarDeclaration::cvMember(p = %p) '%s'\n", p, vd->toChars());

            if (vd->type->toBasetype()->ty == Ttuple)
                return;

            char *id = vd->toChars();

            if (!p)
            {
                if (vd->isField())
                {
                    if (config.fulltypes == CV8)
                        result += 2;
                    result += 6 + cv_stringbytes(id);
                    result += cv4_numericbytes(vd->offset);
                }
                else if (vd->isStatic())
                {
                    if (config.fulltypes == CV8)
                        result += 2;
                    result += 6 + cv_stringbytes(id);
                }
                result = cv_align(NULL, result);
            }
            else
            {
                idx_t typidx = cv_typidx(Type_toCtype(vd->type));
                unsigned attribute = PROTtoATTR(vd->prot());
                assert((attribute & ~3) == 0);
                switch (config.fulltypes)
                {
                    case CV8:
                        if (vd->isField())
                        {
                            TOWORD(p,LF_MEMBER_V3);
                            TOWORD(p + 2,attribute);
                            TOLONG(p + 4,typidx);
                            cv4_storenumeric(p + 8, vd->offset);
                            result = 8 + cv4_numericbytes(vd->offset);
                            result += cv_namestring(p + result, id);
                        }
                        else if (vd->isStatic())
                        {
                            TOWORD(p,LF_STMEMBER_V3);
                            TOWORD(p + 2,attribute);
                            TOLONG(p + 4,typidx);
                            result = 8;
                            result += cv_namestring(p + result, id);
                        }
                        break;

                    case CV4:
                        if (vd->isField())
                        {
                            TOWORD(p,LF_MEMBER);
                            TOWORD(p + 2,typidx);
                            TOWORD(p + 4,attribute);
                            cv4_storenumeric(p + 6, vd->offset);
                            result = 6 + cv4_numericbytes(vd->offset);
                            result += cv_namestring(p + result, id);
                        }
                        else if (vd->isStatic())
                        {
                            TOWORD(p,LF_STMEMBER);
                            TOWORD(p + 2,typidx);
                            TOWORD(p + 4,attribute);
                            result = 6;
                            result += cv_namestring(p + result, id);
                        }
                        break;

                     default:
                        assert(0);
                }

                result = cv_align(p + result, result);
        #ifdef DEBUG
                int save = result;
                result = 0;
                p = NULL;
                visit(vd);
                assert(result == save);
        #endif
            }
        }