/********************************** * We put out an external definition. */ void out_extdef(symbol *s) { pstate.STflags |= PFLextdef; if (//config.flags2 & CFG2phgen || (config.flags2 & (CFG2phauto | CFG2phautoy) && !(pstate.STflags & (PFLhxwrote | PFLhxdone))) ) synerr(EM_data_in_pch,prettyident(s)); // data or code in precompiled header }
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; }
targ_size_t type_size(type *t) { targ_size_t s; unsigned long u; tym_t tyb; type_debug(t); tyb = tybasic(t->Tty); #ifdef DEBUG if (tyb >= TYMAX) /*type_print(t),*/ dbg_printf("tyb = x%lx\n",tyb); #endif assert(tyb < TYMAX); s = tysize[tyb]; if (s == (targ_size_t) -1) { switch (tyb) { // in case program plays games with function pointers case TYffunc: case TYfpfunc: #if TX86 case TYnfunc: /* in case program plays games with function pointers */ case TYhfunc: case TYnpfunc: case TYnsfunc: case TYfsfunc: case TYf16func: case TYifunc: case TYjfunc: #endif #if SCPP if (ANSI) synerr(EM_unknown_size,"function"); /* size of function is not known */ #endif s = 1; break; case TYarray: if (t->Tflags & TFsizeunknown) { #if SCPP synerr(EM_unknown_size,"array"); /* size of array is unknown */ #endif t->Tflags &= ~TFsizeunknown; } if (t->Tflags & TFvla) { s = tysize[pointertype]; break; } s = type_size(t->Tnext); u = t->Tdim * (unsigned long) s; #if TX86 && SCPP type_chksize(u); #endif s = u; break; case TYstruct: t = t->Ttag->Stype; /* find main instance */ /* (for const struct X) */ if (t->Tflags & TFsizeunknown) { #if SCPP template_instantiate_forward(t->Ttag); if (t->Tflags & TFsizeunknown) synerr(EM_unknown_size,t->Tty & TYstruct ? prettyident(t->Ttag) : "struct"); t->Tflags &= ~TFsizeunknown; #endif } assert(t->Ttag); s = t->Ttag->Sstruct->Sstructsize; break; #if SCPP case TYenum: if (t->Ttag->Senum->SEflags & SENforward) synerr(EM_unknown_size, prettyident(t->Ttag)); s = type_size(t->Tnext); break; #endif case TYvoid: #if SCPP && TARGET_WINDOS // GNUC allows it, so we will, too synerr(EM_void_novalue); // voids have no value #endif s = 1; break; #if SCPP case TYref: case TYmemptr: case TYvtshape: s = tysize(tym_conv(t)); break; case TYident: synerr(EM_unknown_size, t->Tident); s = 1; break; #endif #if MARS case TYref: s = tysize(TYnptr); break; #endif default: #ifdef DEBUG WRTYxx(t->Tty); #endif assert(0); } } return s; }