/******************************************* * 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); }
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; }