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; }
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; } }
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(¤tfuncdata, 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; }
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; }
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 } }