/***********************9 * Append data represented by ptr[0..size] */ void DtBuilder::nbytes(unsigned size, const char *ptr) { if (!size) return; dt_t *dt; if (size < DTibytesMax) { dt = dt_calloc(DT_ibytes); dt->DTn = size; memcpy(dt->DTdata,ptr,size); } else { dt = dt_calloc(DT_nbytes); dt->DTnbytes = size; dt->DTpbytes = (char *) MEM_PH_MALLOC(size); memcpy(dt->DTpbytes,ptr,size); } assert(!*pTail); *pTail = dt; pTail = &dt->DTnext; assert(!*pTail); }
/************************* * Write a reference to s+offset */ void DtBuilder::xoff(Symbol *s, unsigned offset, tym_t ty) { dt_t *dt = dt_calloc(DT_xoff); dt->DTsym = s; dt->DToffset = offset; dt->Dty = ty; assert(!*pTail); *pTail = dt; pTail = &dt->DTnext; assert(!*pTail); }
void init_common(symbol *s) { //printf("init_common('%s')\n", s->Sident); unsigned size = type_size(s->Stype); if (size) { dt_t *dt = dt_calloc(DT_common); dt->DTazeros = size; s->Sdt = dt; } }
/*********************** * Write a bunch of zeros */ void DtBuilder::nzeros(unsigned size) { if (!size) return; assert((long) size > 0); dt_t *dt = dt_calloc(DT_azeros); dt->DTazeros = size; assert(!*pTail); *pTail = dt; pTail = &dt->DTnext; assert(!*pTail); }
/******************************** * Write reference to offset in code segment. */ void DtBuilder::coff(unsigned offset) { dt_t *dt = dt_calloc(DT_coff); #if TARGET_SEGMENTED dt->Dty = TYcptr; #else dt->Dty = TYnptr; #endif dt->DToffset = offset; assert(!*pTail); *pTail = dt; pTail = &dt->DTnext; assert(!*pTail); }
/******************************* * Like xoff(), but returns handle with which to patch 'offset' value. */ dt_t *DtBuilder::xoffpatch(Symbol *s, unsigned offset, tym_t ty) { dt_t *dt = dt_calloc(DT_xoff); dt->DTsym = s; dt->DToffset = offset; dt->Dty = ty; dt_t **pxoff = pTail; assert(!*pTail); *pTail = dt; pTail = &dt->DTnext; assert(!*pTail); return *pxoff; }
/***************************************** * Write a reference to the data ptr[0..size+nzeros] */ void DtBuilder::abytes(tym_t ty, unsigned offset, unsigned size, const char *ptr, unsigned nzeros) { dt_t *dt = dt_calloc(DT_abytes); dt->DTnbytes = size + nzeros; dt->DTpbytes = (char *) MEM_PH_MALLOC(size + nzeros); dt->Dty = ty; dt->DTabytes = offset; memcpy(dt->DTpbytes,ptr,size); if (nzeros) memset(dt->DTpbytes + size, 0, nzeros); assert(!*pTail); *pTail = dt; pTail = &dt->DTnext; assert(!*pTail); }
/************************************** * Write 4 bytes of value. */ void DtBuilder::dword(int value) { if (value == 0) { nzeros(4); return; } dt_t *dt = dt_calloc(DT_ibytes); dt->DTn = 4; union { char* cp; int* lp; } u; u.cp = dt->DTdata; *u.lp = value; assert(!*pTail); *pTail = dt; pTail = &dt->DTnext; assert(!*pTail); }
/*********************** * Write a size_t value. */ void DtBuilder::size(d_ulong value) { if (value == 0) { nzeros(NPTRSIZE); return; } dt_t *dt = dt_calloc(DT_ibytes); dt->DTn = NPTRSIZE; union { char* cp; int* lp; } u; u.cp = dt->DTdata; *u.lp = value; if (NPTRSIZE == 8) u.lp[1] = value >> 32; assert(!*pTail); *pTail = dt; pTail = &dt->DTnext; assert(!*pTail); }
/************************************** * Repeat a list of dt_t's count times. */ void DtBuilder::repeat(dt_t *dt, size_t count) { if (!count) return; unsigned size = dt_size(dt); if (!size) return; if (dtallzeros(dt)) { if (head && dtallzeros(head)) head->DTazeros += size * count; else nzeros(size * count); return; } if (dtpointers(dt)) { dt_t *dtp = NULL; dt_t **pdt = &dtp; for (size_t i = 0; i < count; ++i) { for (dt_t *dtn = dt; dtn; dtn = dtn->DTnext) { dt_t *dtx = dt_calloc(dtn->dt); *dtx = *dtn; dtx->DTnext = NULL; switch (dtx->dt) { case DT_abytes: case DT_nbytes: dtx->DTpbytes = (char *) MEM_PH_MALLOC(dtx->DTnbytes); memcpy(dtx->DTpbytes, dtn->DTpbytes, dtx->DTnbytes); break; } *pdt = dtx; pdt = &dtx->DTnext; } } assert(!*pTail); *pTail = dtp; assert(*pdt == NULL); pTail = pdt; return; } char *p = (char *)MEM_PH_MALLOC(size * count); size_t offset = 0; for (dt_t *dtn = dt; dtn; dtn = dtn->DTnext) { switch (dtn->dt) { case DT_nbytes: memcpy(p + offset, dtn->DTpbytes, dtn->DTnbytes); offset += dtn->DTnbytes; break; case DT_ibytes: memcpy(p + offset, dtn->DTdata, dtn->DTn); offset += dtn->DTn; break; case DT_azeros: memset(p + offset, 0, dtn->DTazeros); offset += dtn->DTazeros; break; default: #ifdef DEBUG printf("dt = %p, dt = %d\n",dt,dt->dt); #endif assert(0); } } assert(offset == size); for (size_t i = 1; i < count; ++i) { memcpy(p + offset, p, size); offset += size; } dt_t *dtx = dt_calloc(DT_nbytes); dtx->DTnbytes = size * count; dtx->DTpbytes = p; assert(!*pTail); *pTail = dtx; pTail = &dtx->DTnext; assert(!*pTail); }
void dtsymsize(symbol *s) { symbol_debug(s); s->Sdt = dt_calloc(DT_symsize); }