void win64_pdata(Symbol *sf) { // return; // doesn't work yet //printf("win64_pdata()\n"); assert(config.exe == EX_WIN64); // Generate the pdata name, which is $pdata$funcname size_t sflen = strlen(sf->Sident); char *pdata_name = (char *)alloca(7 + sflen + 1); assert(pdata_name); memcpy(pdata_name, "$pdata$", 7); memcpy(pdata_name + 7, sf->Sident, sflen + 1); // include terminating 0 symbol *spdata = symbol_name(pdata_name,SCstatic,tsint); symbol_keep(spdata); symbol_debug(spdata); symbol *sunwind = win64_unwind(sf); /* 3 pointers are emitted: * 1. pointer to start of function sf * 2. pointer past end of function sf * 3. pointer to unwind data */ dt_t **pdt = &spdata->Sdt; pdt = dtxoff(pdt,sf,0,TYint); // Note the TYint, these are 32 bit fixups pdt = dtxoff(pdt,sf,retoffset + retsize,TYint); pdt = dtxoff(pdt,sunwind,0,TYint); spdata->Sseg = symbol_iscomdat(sf) ? MsCoffObj::seg_pdata_comdat(sf) : MsCoffObj::seg_pdata(); spdata->Salignment = 4; outdata(spdata); }
/****************************************** * Called at the start of a function. */ void cv8_func_start(Symbol *sfunc) { //printf("cv8_func_start(%s)\n", sfunc->Sident); currentfuncdata.sfunc = sfunc; currentfuncdata.section_length = 0; currentfuncdata.srcfilename = NULL; currentfuncdata.srcfileoff = 0; currentfuncdata.linepairstart += currentfuncdata.linepairnum; currentfuncdata.linepairnum = 0; currentfuncdata.f1buf = F1_buf; currentfuncdata.f1fixup = F1fixup; if (symbol_iscomdat(sfunc)) { currentfuncdata.f1buf = new Outbuffer(128); currentfuncdata.f1fixup = new Outbuffer(128); } }
void cv8_termfile() { //printf("cv8_termfile()\n"); /* Write out the debug info sections. */ int seg = MsCoffObj::seg_debugS(); unsigned v = 4; objmod->bytes(seg,0,4,&v); // Write out "F2" sections unsigned length = funcdata->size(); unsigned char *p = funcdata->buf; for (unsigned u = 0; u < length; u += sizeof(FuncData)) { FuncData *fd = (FuncData *)(p + u); F2_buf->setsize(0); F2_buf->write32(fd->sfunc->Soffset); F2_buf->write32(0); F2_buf->write32(fd->section_length); F2_buf->write32(fd->srcfileoff); F2_buf->write32(fd->linepairnum); F2_buf->write32(fd->linepairnum * 8 + 12); F2_buf->write(linepair->buf + fd->linepairstart * 8, fd->linepairnum * 8); int f2seg = seg; if (symbol_iscomdat(fd->sfunc)) { f2seg = MsCoffObj::seg_debugS_comdat(fd->sfunc); objmod->bytes(f2seg,0,4,&v); } unsigned offset = SegData[f2seg]->SDoffset + 8; cv8_writesection(f2seg, 0xF2, F2_buf); objmod->reftoident(f2seg, offset, fd->sfunc, 0, CFseg | CFoff); } // Write out "F3" section cv8_writesection(seg, 0xF3, F3_buf); // Write out "F4" section cv8_writesection(seg, 0xF4, F4_buf); }
Symbol *win64_unwind(Symbol *sf) { // Generate the unwind name, which is $unwind$funcname size_t sflen = strlen(sf->Sident); char *unwind_name = (char *)alloca(8 + sflen + 1); assert(unwind_name); memcpy(unwind_name, "$unwind$", 8); memcpy(unwind_name + 8, sf->Sident, sflen + 1); // include terminating 0 symbol *sunwind = symbol_name(unwind_name,SCstatic,tsint); symbol_keep(sunwind); symbol_debug(sunwind); sunwind->Sdt = unwind_data(); sunwind->Sseg = symbol_iscomdat(sf) ? MsCoffObj::seg_xdata_comdat(sf) : MsCoffObj::seg_xdata(); sunwind->Salignment = 1; outdata(sunwind); return sunwind; }
void cv8_termfile(const char *objfilename) { //printf("cv8_termfile()\n"); /* Write out the debug info sections. */ int seg = MsCoffObj::seg_debugS(); unsigned v = 4; objmod->bytes(seg,0,4,&v); /* Start with starting symbol in separate "F1" section */ Outbuffer buf(1024); size_t len = strlen(objfilename); buf.writeWord(2 + 4 + len + 1); buf.writeWord(S_COMPILAND_V3); buf.write32(0); buf.write(objfilename, len + 1); // write S_COMPILE record buf.writeWord(2 + 1 + 1 + 2 + 1 + sizeof(VERSION)); buf.writeWord(S_COMPILE); buf.writeByte(I64 ? 0xD0 : 6); // target machine AMD64 or x86 (Pentium II) buf.writeByte(config.flags2 & CFG2gms ? (CPP != 0) : 'D'); // language index (C/C++/D) buf.writeWord(0x800 | (config.inline8087 ? 0 : (1<<3))); // 32-bit, float package buf.writeByte(sizeof(VERSION)); buf.writeByte('Z'); buf.write(VERSION, sizeof(VERSION) - 1); cv8_writesection(seg, 0xF1, &buf); // Write out "F2" sections unsigned length = funcdata->size(); unsigned char *p = funcdata->buf; for (unsigned u = 0; u < length; u += sizeof(FuncData)) { FuncData *fd = (FuncData *)(p + u); F2_buf->setsize(0); F2_buf->write32(fd->sfunc->Soffset); F2_buf->write32(0); F2_buf->write32(fd->section_length); F2_buf->write32(fd->srcfileoff); F2_buf->write32(fd->linepairnum); F2_buf->write32(fd->linepairnum * 8 + 12); F2_buf->write(linepair->buf + fd->linepairstart * 8, fd->linepairnum * 8); int f2seg = seg; if (symbol_iscomdat(fd->sfunc)) { f2seg = MsCoffObj::seg_debugS_comdat(fd->sfunc); objmod->bytes(f2seg,0,4,&v); } unsigned offset = SegData[f2seg]->SDoffset + 8; cv8_writesection(f2seg, 0xF2, F2_buf); objmod->reftoident(f2seg, offset, fd->sfunc, 0, CFseg | CFoff); if (f2seg != seg && fd->f1buf->size()) { // Write out "F1" section unsigned f1offset = SegData[f2seg]->SDoffset; cv8_writesection(f2seg, 0xF1, fd->f1buf); // Fixups for "F1" section unsigned length = fd->f1fixup->size(); unsigned char *p = fd->f1fixup->buf; for (unsigned u = 0; u < length; u += sizeof(F1_Fixups)) { F1_Fixups *f = (F1_Fixups *)(p + u); objmod->reftoident(f2seg, f1offset + 8 + f->offset, f->s, 0, CFseg | CFoff); } } } // Write out "F3" section cv8_writesection(seg, 0xF3, F3_buf); // Write out "F4" section cv8_writesection(seg, 0xF4, F4_buf); if (F1_buf->size()) { // Write out "F1" section unsigned f1offset = SegData[seg]->SDoffset; cv8_writesection(seg, 0xF1, F1_buf); // Fixups for "F1" section length = F1fixup->size(); p = F1fixup->buf; for (unsigned u = 0; u < length; u += sizeof(F1_Fixups)) { F1_Fixups *f = (F1_Fixups *)(p + u); objmod->reftoident(seg, f1offset + 8 + f->offset, f->s, 0, CFseg | CFoff); } } // Write out .debug$T section cv_term(); }