diff --git a/src/backend/aa.c b/src/backend/aa.c index dd57b677abdc..86f54373f7f3 100644 --- a/src/backend/aa.c +++ b/src/backend/aa.c @@ -42,6 +42,15 @@ size_t aligntsize(size_t tsize) return (tsize + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1); } +static int hashCmp(hash_t lhs, hash_t rhs) +{ + if (lhs == rhs) + return 0; + else if (lhs < rhs) + return -1; + return 1; +} + /********************************** * Constructor. */ @@ -122,7 +131,7 @@ void* AArray::get(void *pkey) while ((e = *pe) != NULL) { int c; - c = key_hash - e->hash; + c = hashCmp(key_hash, e->hash); if (c == 0) { c = keyti->compare(pkey, e + 1); @@ -180,7 +189,7 @@ void* AArray::in(void *pkey) while (e != NULL) { int c; - c = key_hash - e->hash; + c = hashCmp(key_hash, e->hash); if (c == 0) { c = keyti->compare(pkey, e + 1); @@ -218,7 +227,7 @@ void AArray::del(void *pkey) while ((e = *pe) != NULL) // NULL means not found { int c; - c = key_hash - e->hash; + c = hashCmp(key_hash, e->hash); if (c == 0) { c = keyti->compare(pkey, e + 1); @@ -412,7 +421,7 @@ void AArray::rehash_x(aaA* olde, aaA** newbuckets, size_t newbuckets_length) //printf("\te = %p, e->left = %p, e->right = %p\n", e, e->left, e->right); assert(e->left != e); assert(e->right != e); - c = key_hash - e->hash; + c = hashCmp(key_hash, e->hash); if (c == 0) c = keyti->compare(olde + 1, e + 1); if (c < 0) diff --git a/src/backend/backconfig.c b/src/backend/backconfig.c index 9c55916985da..a3b3c19bc5f2 100644 --- a/src/backend/backconfig.c +++ b/src/backend/backconfig.c @@ -38,6 +38,7 @@ extern void ph_init(); void out_config_init( int model, // 32: 32 bit code // 64: 64 bit code + // Windows: set bit 0 to generate MS-COFF instead of OMF bool exe, // true: exe file // false: dll or shared library (generate PIC code) bool trace, // add profiling code @@ -64,6 +65,8 @@ void out_config_init( config.memmodel = 0; config.flags |= CFGuchar; // make sure TYchar is unsigned tytab[TYchar] |= TYFLuns; + bool mscoff = model & 1; + model &= 32 | 64; #if TARGET_WINDOS if (model == 64) { config.exe = EX_WIN64; @@ -73,10 +76,12 @@ void out_config_init( config.flags |= CFGnoebp; config.flags |= CFGalwaysframe; config.flags |= CFGromable; // put switch tables in code segment + config.objfmt = OBJ_MSCOFF; } else { config.exe = EX_NT; config.flags2 |= CFG2seh; // Win32 eh + config.objfmt = mscoff ? OBJ_MSCOFF : OBJ_OMF; } if (exe) @@ -98,6 +103,7 @@ void out_config_init( config.flags |= CFGalwaysframe; if (!exe) config.flags3 |= CFG3pic; + config.objfmt = OBJ_ELF; #endif #if TARGET_OSX config.fpxmmregs = TRUE; @@ -112,6 +118,7 @@ void out_config_init( if (!exe) config.flags3 |= CFG3pic; config.flags |= CFGromable; // put switch tables in code segment + config.objfmt = OBJ_MACH; #endif #if TARGET_FREEBSD if (model == 64) @@ -128,6 +135,7 @@ void out_config_init( config.flags |= CFGalwaysframe; if (!exe) config.flags3 |= CFG3pic; + config.objfmt = OBJ_ELF; #endif #if TARGET_OPENBSD if (model == 64) @@ -144,6 +152,7 @@ void out_config_init( config.flags |= CFGalwaysframe; if (!exe) config.flags3 |= CFG3pic; + config.objfmt = OBJ_ELF; #endif #if TARGET_SOLARIS if (model == 64) @@ -160,6 +169,7 @@ void out_config_init( config.flags |= CFGalwaysframe; if (!exe) config.flags3 |= CFG3pic; + config.objfmt = OBJ_ELF; #endif config.flags2 |= CFG2nodeflib; // no default library config.flags3 |= CFG3eseqds; @@ -189,7 +199,7 @@ void out_config_init( config.fulltypes = (symdebug == 1) ? CVDWARF_D : CVDWARF_C; #endif #if SYMDEB_CODEVIEW - if (model == 64) + if (config.objfmt == OBJ_MSCOFF) { configv.addlinenumbers = 1; config.fulltypes = CV8; diff --git a/src/backend/cdef.h b/src/backend/cdef.h index 53cfc62584d0..2dc46573a62d 100644 --- a/src/backend/cdef.h +++ b/src/backend/cdef.h @@ -703,6 +703,11 @@ struct Config 2: fast inline 8087 code */ short memmodel; // 0:S,X,N,F, 1:M, 2:C, 3:L, 4:V + unsigned objfmt; // target object format +#define OBJ_OMF 1 +#define OBJ_MSCOFF 2 +#define OBJ_ELF 3 +#define OBJ_MACH 4 unsigned exe; // target operating system #define EX_DOSX 1 // DOSX 386 program #define EX_ZPM 2 // ZPM 286 program diff --git a/src/backend/cgen.c b/src/backend/cgen.c index 754653e0bee5..ac2e13926f4d 100644 --- a/src/backend/cgen.c +++ b/src/backend/cgen.c @@ -525,7 +525,7 @@ size_t addtofixlist(symbol *s,targ_size_t soffset,int seg,targ_size_t val,int fl static char zeros[8]; //printf("addtofixlist(%p '%s')\n",s,s->Sident); - assert(flags); + assert(I32 || flags); fixlist *ln = (fixlist *) mem_calloc(sizeof(fixlist)); //ln->Lsymbol = s; ln->Loffset = soffset; diff --git a/src/backend/cod1.c b/src/backend/cod1.c index 978158f34e2e..0bdb6d10f8d6 100644 --- a/src/backend/cod1.c +++ b/src/backend/cod1.c @@ -2213,6 +2213,13 @@ code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask) info[CLIBullngdbl].retregs32 = mAX; info[CLIBdblullng].retregs32 = mAX; } + else if (config.objfmt == OBJ_MSCOFF) + { + strcpy(lib[CLIBldiv].Sident, "_ms_alldiv"); + strcpy(lib[CLIBlmod].Sident, "_ms_allrem"); info[CLIBlmod].retregs32 = mAX|mDX; + strcpy(lib[CLIBuldiv].Sident, "_ms_aulldiv"); + strcpy(lib[CLIBulmod].Sident, "_ms_aullrem"); info[CLIBulmod].retregs32 = mAX|mDX; + } } clib_inited++; } diff --git a/src/backend/cod3.c b/src/backend/cod3.c index 0a9b3cbd8a2c..426d5c5b5df6 100644 --- a/src/backend/cod3.c +++ b/src/backend/cod3.c @@ -4152,7 +4152,7 @@ void cod3_thunk(symbol *sthunk,symbol *sfunc,unsigned p,tym_t thisty, objmod->pubdef(cseg,sthunk,sthunk->Soffset); #endif #if TARGET_WINDOS - if (config.exe == EX_WIN64) + if (config.objfmt == OBJ_MSCOFF) objmod->pubdef(cseg,sthunk,sthunk->Soffset); #endif searchfixlist(sthunk); /* resolve forward refs */ diff --git a/src/backend/cv8.c b/src/backend/cv8.c index 980a0764d20f..5c5949861d22 100644 --- a/src/backend/cv8.c +++ b/src/backend/cv8.c @@ -277,7 +277,7 @@ void cv8_initmodule(const char *filename, const char *modulename) void cv8_termmodule() { //printf("cv8_termmodule()\n"); - assert(config.exe == EX_WIN64); + assert(config.objfmt == OBJ_MSCOFF); } /****************************************** @@ -614,14 +614,14 @@ void cv8_outsym(Symbol *s) buf->writeWordn(0x1111); buf->write32(s->Soffset + base + BPoff); buf->write32(typidx); - buf->writeWordn(334); // relative to RBP + 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(0x1006); + buf->writeWordn(S_BPREL_V3); buf->write32(s->Soffset + base + BPoff); buf->write32(typidx); cv8_writename(buf, id, len); @@ -864,7 +864,9 @@ idx_t cv8_darray(type *t, idx_t etypidx) debtyp_t *f = debtyp_alloc(sizeof(fl)); memcpy(f->data,fl,sizeof(fl)); + TOLONG(f->data + 6, I64 ? 0x23 : 0x22); // size_t TOLONG(f->data + 26, ptridx); + TOWORD(f->data + 30, NPTRSIZE); idx_t fieldlist = cv_debtyp(f); const char *id; @@ -899,7 +901,7 @@ idx_t cv8_darray(type *t, idx_t etypidx) TOLONG(d->data + 6, fieldlist); TOLONG(d->data + 10, 0); // dList TOLONG(d->data + 14, 0); // vtshape - TOWORD(d->data + 18, 16); // size + TOWORD(d->data + 18, 2 * NPTRSIZE); // size cv_namestring(d->data + 20, id, idlen); d->data[20 + idlen] = 0; @@ -966,6 +968,7 @@ idx_t cv8_ddelegate(type *t, idx_t functypidx) memcpy(f->data,fl,sizeof(fl)); TOLONG(f->data + 6, pvidx); TOLONG(f->data + 22, ptridx); + TOWORD(f->data + 26, NPTRSIZE); idx_t fieldlist = cv_debtyp(f); const char *id = "dDelegate"; @@ -980,7 +983,7 @@ idx_t cv8_ddelegate(type *t, idx_t functypidx) TOLONG(d->data + 6, fieldlist); TOLONG(d->data + 10, 0); // dList TOLONG(d->data + 14, 0); // vtshape - TOWORD(d->data + 18, 16); // size + TOWORD(d->data + 18, 2 * NPTRSIZE); // size memcpy(d->data + 20, id, idlen); d->data[20 + idlen] = 0; #endif diff --git a/src/backend/el.c b/src/backend/el.c index d36084f321a4..965ab936f3c0 100644 --- a/src/backend/el.c +++ b/src/backend/el.c @@ -588,10 +588,18 @@ elem *exp2_copytotemp(elem *e) { //printf("exp2_copytotemp()\n"); elem_debug(e); - Symbol *stmp = symbol_genauto(e); + tym_t ty = tybasic(e->Ety); + type *t; +#if MARS + if ((ty == TYstruct || ty == TYarray) && e->ET) + t = e->ET; + else +#endif + t = type_fake(ty); + Symbol *stmp = symbol_genauto(t); elem *eeq = el_bin(OPeq,e->Ety,el_var(stmp),e); elem *er = el_bin(OPcomma,e->Ety,eeq,el_var(stmp)); - if (tybasic(e->Ety) == TYstruct || tybasic(e->Ety) == TYarray) + if (ty == TYstruct || ty == TYarray) { eeq->Eoper = OPstreq; eeq->ET = e->ET; diff --git a/src/backend/mscoffobj.c b/src/backend/mscoffobj.c index badaf20162cc..f588a03ae66e 100644 --- a/src/backend/mscoffobj.c +++ b/src/backend/mscoffobj.c @@ -326,7 +326,7 @@ symbol * MsCoffObj::sym_cdata(tym_t ty,char *p,int len) int MsCoffObj::data_readonly(char *p, int len, segidx_t *pseg) { int oldoff; - if (I64) + if (I64 || I32) { oldoff = Doffset; SegData[DATA]->SDbuf->reserve(len); @@ -930,19 +930,61 @@ void MsCoffObj::term(const char *objfilename) } #endif } + else if (I32) + { + rel.r_type = (r->rtype == RELrel) + ? IMAGE_REL_I386_REL32 + : IMAGE_REL_I386_DIR32; + + if (s->Stype->Tty & mTYthread) + rel.r_type = IMAGE_REL_I386_SECREL; + + if (s->Sclass == SCextern || + s->Sclass == SCcomdef || + s->Sclass == SCcomdat || + s->Sclass == SCglobal) + { + rel.r_vaddr = r->offset; + rel.r_symndx = s->Sxtrnnum; + } + else + { + rel.r_vaddr = r->offset; + rel.r_symndx = s->Sxtrnnum; + } + } + else + assert(false); // not implemented for I16 } else { //printf("test2\n"); - if (pdata) - rel.r_type = IMAGE_REL_AMD64_ADDR32NB; - else - rel.r_type = IMAGE_REL_AMD64_ADDR64; + if (I64) + { + if (pdata) + rel.r_type = IMAGE_REL_AMD64_ADDR32NB; + else + rel.r_type = IMAGE_REL_AMD64_ADDR64; + + if (r->rtype == RELseg) + rel.r_type = IMAGE_REL_AMD64_SECTION; + else if (r->rtype == RELaddr32) + rel.r_type = IMAGE_REL_AMD64_SECREL; + } + else if (I32) + { + if (pdata) + rel.r_type = IMAGE_REL_I386_DIR32NB; + else + rel.r_type = IMAGE_REL_I386_DIR32; - if (r->rtype == RELseg) - rel.r_type = IMAGE_REL_AMD64_SECTION; - else if (r->rtype == RELaddr32) - rel.r_type = IMAGE_REL_AMD64_SECREL; + if (r->rtype == RELseg) + rel.r_type = IMAGE_REL_I386_SECTION; + else if (r->rtype == RELaddr32) + rel.r_type = IMAGE_REL_I386_SECREL; + } + else + assert(false); // not implemented for I16 rel.r_vaddr = r->offset; rel.r_symndx = s->Sxtrnnum; @@ -1075,7 +1117,7 @@ printf("test4\n"); */ //assert(rel.r_symndx <= 20000); - assert(rel.r_type <= 0x10); + assert(rel.r_type <= 0x14); fobjbuf->write(&rel, sizeof(rel)); foffset += sizeof(rel); } @@ -1780,34 +1822,36 @@ char *obj_mangle2(Symbol *s,char *dest) { char *pstr = unsstr(type_paramsize(s->Stype)); size_t pstrlen = strlen(pstr); - size_t destlen = len + 1 + pstrlen + 1; + size_t prelen = I32 ? 1 : 0; + size_t destlen = prelen + len + 1 + pstrlen + 1; if (destlen > DEST_LEN) dest = (char *)mem_malloc(destlen); - memcpy(dest,name,len); - dest[len] = '@'; - memcpy(dest + 1 + len, pstr, pstrlen + 1); + dest[0] = '_'; + memcpy(dest + prelen,name,len); + dest[prelen + len] = '@'; + memcpy(dest + prelen + 1 + len, pstr, pstrlen + 1); break; } case mTYman_cpp: case mTYman_d: case mTYman_sys: - case mTYman_c: + case_mTYman_c64: case 0: if (len >= DEST_LEN) dest = (char *)mem_malloc(len + 1); memcpy(dest,name,len+1);// copy in name and trailing 0 break; -#if 0 case mTYman_c: + if(I64) + goto case_mTYman_c64; // Prepend _ to identifier if (len >= DEST_LEN - 1) dest = (char *)mem_malloc(1 + len + 1); dest[0] = '_'; memcpy(dest + 1,name,len+1);// copy in name and trailing 0 break; -#endif default: #ifdef DEBUG @@ -1827,9 +1871,12 @@ char *obj_mangle2(Symbol *s,char *dest) void MsCoffObj::export_symbol(Symbol *s,unsigned argsize) { + char dest[DEST_LEN+1]; + char *destr = obj_mangle2(s, dest); + //printf("MsCoffObj::export_symbol(%s,%d)\n",s->Sident,argsize); SegData[segidx_drectve]->SDbuf->write(" /EXPORT:", 9); - SegData[segidx_drectve]->SDbuf->write(s->Sident, strlen(s->Sident)); + SegData[segidx_drectve]->SDbuf->write(dest, strlen(dest)); } /******************************* @@ -2285,6 +2332,8 @@ void MsCoffObj::reftocodeseg(segidx_t seg,targ_size_t offset,targ_size_t val) int save = buf->size(); buf->setsize(offset); val -= funcsym_p->Soffset; + if (I32) + MsCoffObj::addrel(seg, offset, funcsym_p, 0, RELaddr, 0); // MsCoffObj::addrel(seg, offset, funcsym_p, 0, RELaddr); // if (I64) // buf->write64(val); @@ -2331,7 +2380,7 @@ int MsCoffObj::reftoident(segidx_t seg, targ_size_t offset, Symbol *s, targ_size } else { - if (I64) + if (I64 || I32) { //if (s->Sclass != SCcomdat) //val += s->Soffset; diff --git a/src/backend/out.c b/src/backend/out.c index d23362b1a5c1..fc730904b5c1 100644 --- a/src/backend/out.c +++ b/src/backend/out.c @@ -192,7 +192,7 @@ void outdata(symbol *s) objmod->lidata(pseg->SDseg, pseg->SDoffset, datasize); #endif #if OMFOBJ - if (config.exe == EX_WIN64) + if (config.objfmt == OBJ_MSCOFF) objmod->lidata(pseg->SDseg, pseg->SDoffset, datasize); else pseg->SDoffset += datasize; @@ -212,7 +212,7 @@ void outdata(symbol *s) if (s->Sclass == SCglobal || s->Sclass == SCstatic) // if a pubdef to be done #endif #if OMFOBJ - if (s->Sclass == SCglobal || (s->Sclass == SCstatic && I64)) // if a pubdef to be done + if (s->Sclass == SCglobal || (s->Sclass == SCstatic && config.objfmt == OBJ_MSCOFF)) // if a pubdef to be done #endif objmod->pubdefsize(s->Sseg,s,s->Soffset,datasize); // do the definition searchfixlist(s); @@ -334,7 +334,7 @@ void outdata(symbol *s) || s->Sclass == SCstatic #endif #if OMFOBJ - || (s->Sclass == SCstatic && I64) + || (s->Sclass == SCstatic && config.objfmt == OBJ_MSCOFF) #endif ) { @@ -480,7 +480,7 @@ void outcommon(symbol *s,targ_size_t n) objmod->common_block(s, 0, n, 1); #endif #if OMFOBJ - if (I64) + if (config.objfmt == OBJ_MSCOFF) objmod->common_block(s, 0, n, 1); else { diff --git a/src/backend/rtlsym.h b/src/backend/rtlsym.h index 6d16fe31d121..adf65ba4a3d0 100644 --- a/src/backend/rtlsym.h +++ b/src/backend/rtlsym.h @@ -95,6 +95,7 @@ SYMBOL_MARS(CALLFINALIZER, FLfunc,FREGSAVED,"_d_callfinalizer", 0, t) \ SYMBOL_MARS(CALLINTERFACEFINALIZER, FLfunc,FREGSAVED,"_d_callinterfacefinalizer", 0, t) \ SYMBOL_MARS(DELCLASS, FLfunc,FREGSAVED,"_d_delclass", 0, t) \ SYMBOL_MARS(DELINTERFACE, FLfunc,FREGSAVED,"_d_delinterface", 0, t) \ +SYMBOL_MARS(DELSTRUCT, FLfunc,FREGSAVED,"_d_delstruct", 0, t) \ SYMBOL_MARS(ALLOCMEMORY, FLfunc,FREGSAVED,"_d_allocmemory", 0, t) \ SYMBOL_MARS(DELARRAY, FLfunc,FREGSAVED,"_d_delarray", 0, t) \ SYMBOL_MARS(DELARRAYT, FLfunc,FREGSAVED,"_d_delarray_t", 0, t) \