void outdata(symbol *s) { #if HTOD return; #endif int seg; targ_size_t offset; int flags; const int codeseg = cseg; symbol_debug(s); #ifdef DEBUG debugy && dbg_printf("outdata('%s')\n",s->Sident); #endif //printf("outdata('%s', ty=x%x)\n",s->Sident,s->Stype->Tty); //symbol_print(s); // Data segment variables are always live on exit from a function s->Sflags |= SFLlivexit; dt_t *dtstart = s->Sdt; s->Sdt = NULL; // it will be free'd targ_size_t datasize = 0; tym_t ty = s->ty(); #if SCPP && TARGET_WINDOS if (eecontext.EEcompile) { s->Sfl = (s->ty() & mTYfar) ? FLfardata : FLextern; s->Sseg = UNKNOWN; goto Lret; // don't output any data } #endif if (ty & mTYexport && config.wflags & WFexpdef && s->Sclass != SCstatic) objmod->export_symbol(s,0); // export data definition for (dt_t *dt = dtstart; dt; dt = dt->DTnext) { //printf("\tdt = %p, dt = %d\n",dt,dt->dt); switch (dt->dt) { case DT_abytes: { // Put out the data for the string, and // reserve a spot for a pointer to that string datasize += size(dt->Dty); // reserve spot for pointer to string #if TARGET_SEGMENTED if (tybasic(dt->Dty) == TYcptr) { dt->DTseg = codeseg; dt->DTabytes += Offset(codeseg); goto L1; } else if (tybasic(dt->Dty) == TYfptr && dt->DTnbytes > config.threshold) { targ_size_t foffset; dt->DTseg = objmod->fardata(s->Sident,dt->DTnbytes,&foffset); dt->DTabytes += foffset; L1: objmod->write_bytes(SegData[dt->DTseg],dt->DTnbytes,dt->DTpbytes); break; } else #endif { dt->DTabytes += objmod->data_readonly(dt->DTpbytes,dt->DTnbytes,&dt->DTseg); } break; } case DT_ibytes: datasize += dt->DTn; break; case DT_nbytes: //printf("DT_nbytes %d\n", dt->DTnbytes); datasize += dt->DTnbytes; break; case DT_azeros: /* A block of zeros */ //printf("DT_azeros %d\n", dt->DTazeros); case_azeros: datasize += dt->DTazeros; if (dt == dtstart && !dt->DTnext && s->Sclass != SCcomdat && (s->Sseg == UNKNOWN || s->Sseg <= UDATA)) { /* first and only, so put in BSS segment */ switch (ty & mTYLINK) { #if TARGET_SEGMENTED case mTYfar: // if far data s->Sseg = objmod->fardata(s->Sident,datasize,&s->Soffset); s->Sfl = FLfardata; break; case mTYcs: s->Sseg = codeseg; Offset(codeseg) = _align(datasize,Offset(codeseg)); s->Soffset = Offset(codeseg); Offset(codeseg) += datasize; s->Sfl = FLcsdata; break; #endif case mTYthreadData: assert(config.objfmt == OBJ_MACH && I64); case mTYthread: { seg_data *pseg = objmod->tlsseg_bss(); s->Sseg = pseg->SDseg; objmod->data_start(s, datasize, pseg->SDseg); if (config.objfmt == OBJ_OMF) pseg->SDoffset += datasize; else objmod->lidata(pseg->SDseg, pseg->SDoffset, datasize); s->Sfl = FLtlsdata; break; } default: s->Sseg = UDATA; objmod->data_start(s,datasize,UDATA); objmod->lidata(s->Sseg,s->Soffset,datasize); s->Sfl = FLudata; // uninitialized data break; } assert(s->Sseg && s->Sseg != UNKNOWN); if (s->Sclass == SCglobal || (s->Sclass == SCstatic && config.objfmt != OBJ_OMF)) // if a pubdef to be done objmod->pubdefsize(s->Sseg,s,s->Soffset,datasize); // do the definition searchfixlist(s); if (config.fulltypes && !(s->Sclass == SCstatic && funcsym_p)) // not local static cv_outsym(s); #if SCPP out_extdef(s); #endif goto Lret; } break; case DT_common: assert(!dt->DTnext); outcommon(s,dt->DTazeros); goto Lret; case DT_xoff: { symbol *sb = dt->DTsym; if (tyfunc(sb->ty())) #if SCPP nwc_mustwrite(sb); #else ; #endif else if (sb->Sdt) // if initializer for symbol { if (!s->Sseg) s->Sseg = DATA; outdata(sb); // write out data for symbol } } case DT_coff: datasize += size(dt->Dty); break; default: #ifdef DEBUG dbg_printf("dt = %p, dt = %d\n",dt,dt->dt); #endif assert(0); } }
void outdata(symbol *s) { #if HTOD return; #endif dt_t *dtstart,*dt; targ_size_t datasize,a; int seg; targ_size_t offset; int flags; char *p; tym_t ty; int tls; symbol_debug(s); #ifdef DEBUG debugy && dbg_printf("outdata('%s')\n",s->Sident); #endif //printf("outdata('%s', ty=x%x)\n",s->Sident,s->Stype->Tty); //symbol_print(s); // Data segment variables are always live on exit from a function s->Sflags |= SFLlivexit; dtstart = s->Sdt; s->Sdt = NULL; // it will be free'd #if SCPP && TARGET_WINDOS if (eecontext.EEcompile) { s->Sfl = (s->ty() & mTYfar) ? FLfardata : FLextern; s->Sseg = UNKNOWN; goto Lret; // don't output any data } #endif datasize = 0; tls = 0; ty = s->ty(); if (ty & mTYexport && config.wflags & WFexpdef && s->Sclass != SCstatic) obj_export(s,0); // export data definition for (dt = dtstart; dt; dt = dt->DTnext) { //printf("dt = %p, dt = %d\n",dt,dt->dt); switch (dt->dt) { case DT_abytes: { // Put out the data for the string, and // reserve a spot for a pointer to that string #if ELFOBJ || MACHOBJ datasize += size(dt->Dty); dt->DTabytes += elf_data_cdata(dt->DTpbytes,dt->DTnbytes,&dt->DTseg); #else targ_size_t *poffset; datasize += size(dt->Dty); if (tybasic(dt->Dty) == TYcptr) { seg = cseg; poffset = &Coffset; } #if SCPP else if (tybasic(dt->Dty) == TYfptr && dt->DTnbytes > config.threshold) { seg = obj_fardata(s->Sident,dt->DTnbytes,&offset); poffset = &offset; } #endif else { seg = DATA; poffset = &Doffset; } dt->DTseg = seg; dt->DTabytes += *poffset; obj_bytes(seg,*poffset,dt->DTnbytes,dt->DTpbytes); *poffset += dt->DTnbytes; #endif break; } case DT_ibytes: datasize += dt->DTn; break; case DT_nbytes: //printf("DT_nbytes %d\n", dt->DTnbytes); datasize += dt->DTnbytes; break; case DT_symsize: #if MARS assert(0); #else dt->DTazeros = type_size(s->Stype); #endif goto case_azeros; case DT_azeros: /* A block of zeros */ //printf("DT_azeros %d\n", dt->DTazeros); case_azeros: datasize += dt->DTazeros; if (dt == dtstart && !dt->DTnext && s->Sclass != SCcomdat) { /* first and only, so put in BSS segment */ switch (ty & mTYLINK) { #if OMFOBJ case mTYfar: // if far data seg = obj_fardata(s->Sident,datasize,&s->Soffset); s->Sfl = FLfardata; break; #endif case mTYcs: seg = cseg; Coffset = align(datasize,Coffset); s->Soffset = Coffset; Coffset += datasize; s->Sfl = FLcsdata; break; case mTYthread: { seg_data *pseg = obj_tlsseg_bss(); #if ELFOBJ || MACHOBJ s->Sseg = pseg->SDseg; elf_data_start(s, datasize, pseg->SDseg); obj_lidata(pseg->SDseg, pseg->SDoffset, datasize); #else targ_size_t TDoffset = pseg->SDoffset; TDoffset = align(datasize,TDoffset); s->Soffset = TDoffset; TDoffset += datasize; pseg->SDoffset = TDoffset; #endif seg = pseg->SDseg; s->Sfl = FLtlsdata; tls = 1; break; } default: #if ELFOBJ || MACHOBJ seg = elf_data_start(s,datasize,UDATA); obj_lidata(s->Sseg,s->Soffset,datasize); #else seg = UDATA; UDoffset = align(datasize,UDoffset); s->Soffset = UDoffset; UDoffset += datasize; #endif s->Sfl = FLudata; // uninitialized data break; } #if ELFOBJ || MACHOBJ assert(s->Sseg != UNKNOWN); if (s->Sclass == SCglobal || s->Sclass == SCstatic) objpubdef(s->Sseg,s,s->Soffset); /* do the definition */ /* if a pubdef to be done */ #else s->Sseg = seg; if (s->Sclass == SCglobal) /* if a pubdef to be done */ objpubdef(seg,s,s->Soffset); /* do the definition */ #endif searchfixlist(s); if (config.fulltypes && !(s->Sclass == SCstatic && funcsym_p)) // not local static cv_outsym(s); #if SCPP out_extdef(s); #endif goto Lret; } break; case DT_common: assert(!dt->DTnext); outcommon(s,dt->DTazeros); goto Lret; case DT_xoff: { symbol *sb = dt->DTsym; if (tyfunc(sb->ty())) #if SCPP nwc_mustwrite(sb); #else ; #endif else if (sb->Sdt) // if initializer for symbol outdata(sb); // write out data for symbol } case DT_coff: datasize += size(dt->Dty); break; case DT_1byte: datasize++; break; default: #ifdef DEBUG dbg_printf("dt = %p, dt = %d\n",dt,dt->dt); #endif assert(0); } }