diff --git a/include/mdso/mdso.h b/include/mdso/mdso.h index 8c76720..387e771 100644 --- a/include/mdso/mdso.h +++ b/include/mdso/mdso.h @@ -165,7 +165,7 @@ mdso_api int mdso_asmgen_symfn (const struct mdso_driver_ctx *, const char mdso_api int mdso_objgen_dsometa (const struct mdso_driver_ctx *, FILE * fout, struct mdso_object *); mdso_api int mdso_objgen_symentry (const struct mdso_driver_ctx *, const char * sym, FILE * fout, struct mdso_object *); mdso_api int mdso_objgen_symfn (const struct mdso_driver_ctx *, const char * sym, FILE * fout, struct mdso_object *); -mdso_api int mdso_argen_common (const struct mdso_driver_ctx *, const char ** symv, FILE * fout, struct mdso_object *); +mdso_api int mdso_argen_common (const struct mdso_driver_ctx *, const char ** symv, const int * stype, FILE * fout, struct mdso_object *); #ifdef __cplusplus } diff --git a/src/archive/mdso_argen_common.c b/src/archive/mdso_argen_common.c index fdd138c..3cae712 100644 --- a/src/archive/mdso_argen_common.c +++ b/src/archive/mdso_argen_common.c @@ -49,6 +49,7 @@ static void mdso_write_big_endian_long(unsigned char * ch, uint32_t val) int mdso_argen_common( const struct mdso_driver_ctx * dctx, const char ** symv, + const int * stype, FILE * fout, struct mdso_object * vobj) { @@ -56,6 +57,7 @@ int mdso_argen_common( const char ** psym; int nsym; int nobj; + int ndata; uint32_t objlen; uint32_t hdrlen; uint32_t mapstrsnum; @@ -74,10 +76,10 @@ int mdso_argen_common( /* init */ memset (sobj,0,sizeof(sobj)); - for (nsym=0,psym=symv; *psym; psym++) - nsym++; + for (nsym=0,ndata=0,psym=symv; *psym; psym++,nsym++) + ndata += (stype[psym-symv] == MDSO_SYMBOL_TYPE_DATA); - if ((nobj = 2*nsym + 1) < 256) + if ((nobj = 1 + (2*nsym) - ndata) < 256) aobj = sobj; else if (nobj > 1024*1024) @@ -104,18 +106,20 @@ int mdso_argen_common( mapstrsnum = aobj->mapstrsnum; for (psym=symv,pobj=&aobj[1]; *psym && !ret; psym++) { - ret = mdso_objgen_symfn(dctx,*psym,0,pobj); + if (stype[psym-symv] == MDSO_SYMBOL_TYPE_CODE) { + ret = mdso_objgen_symfn(dctx,*psym,0,pobj); - pobj->size += 1; - pobj->size |= 1; - pobj->size ^= 1; + pobj->size += 1; + pobj->size |= 1; + pobj->size ^= 1; - objlen += pobj->size; - objlen += sizeof(struct pe_raw_archive_common_hdr); + objlen += pobj->size; + objlen += sizeof(struct pe_raw_archive_common_hdr); - mapstrslen += pobj->mapstrslen; - mapstrsnum += pobj->mapstrsnum; - pobj++; + mapstrslen += pobj->mapstrslen; + mapstrsnum += pobj->mapstrsnum; + pobj++; + } ret |= mdso_objgen_symentry(dctx,*psym,0,pobj); @@ -213,30 +217,32 @@ int mdso_argen_common( /* archive symfn and symentry objects */ for (psym=symv,pobj=&aobj[1]; *psym && !ret; psym++) { /* symfn object */ - pobj->mapstrs = mapstrs; - pobj->arhdrpos = (uint32_t)(mark - ar); - pobj->arhdrlen = sizeof(struct pe_raw_archive_common_hdr); - pobj->addr = &mark[pobj->arhdrlen]; - - for (symidx=0; symidxmapstrsnum; symidx++) { - mdso_write_big_endian_long(idx,pobj->arhdrpos); - idx += sizeof(uint32_t); + if (stype[psym-symv] == MDSO_SYMBOL_TYPE_CODE) { + pobj->mapstrs = mapstrs; + pobj->arhdrpos = (uint32_t)(mark - ar); + pobj->arhdrlen = sizeof(struct pe_raw_archive_common_hdr); + pobj->addr = &mark[pobj->arhdrlen]; + + for (symidx=0; symidxmapstrsnum; symidx++) { + mdso_write_big_endian_long(idx,pobj->arhdrpos); + idx += sizeof(uint32_t); + } + + ret = mdso_objgen_symfn(dctx,*psym,0,pobj); + + sprintf( + objname,"f%06zu.o", + psym - symv); + + mdso_argen_common_hdr( + (struct pe_raw_archive_common_hdr *)mark, + objname,pobj->size); + + mark += pobj->arhdrlen + pobj->size; + mapstrs += pobj->mapstrslen; + pobj++; } - ret = mdso_objgen_symfn(dctx,*psym,0,pobj); - - sprintf( - objname,"f%06zu.o", - psym - symv); - - mdso_argen_common_hdr( - (struct pe_raw_archive_common_hdr *)mark, - objname,pobj->size); - - mark += pobj->arhdrlen + pobj->size; - mapstrs += pobj->mapstrslen; - pobj++; - /* symentry object */ pobj->mapstrs = mapstrs; diff --git a/src/util/mdso_create_implib_archive.c b/src/util/mdso_create_implib_archive.c index c48c220..27f82e7 100644 --- a/src/util/mdso_create_implib_archive.c +++ b/src/util/mdso_create_implib_archive.c @@ -12,10 +12,20 @@ #include #include "mdso_errinfo_impl.h" -static void mdso_free_uctx_vector(struct mdso_unit_ctx ** uctxv, FILE * fout) +static void mdso_free_uctx_vector( + struct mdso_unit_ctx ** uctxv, + const char ** symv, + int * stype, + FILE * fout) { struct mdso_unit_ctx ** puctx; + if (symv) + free(symv); + + if (stype) + free(stype); + for (puctx=uctxv; *puctx; puctx++) mdso_free_unit_ctx(*puctx); @@ -23,11 +33,6 @@ static void mdso_free_uctx_vector(struct mdso_unit_ctx ** uctxv, FILE * fout) fclose(fout); } -static int mdso_symcmp(const void * src, const void * dst) -{ - return strcmp(*(const char **)src,*(const char **)dst); -} - int mdso_create_implib_archive(const struct mdso_driver_ctx * dctx) { int ret; @@ -39,7 +44,7 @@ int mdso_create_implib_archive(const struct mdso_driver_ctx * dctx) const char ** unit; const char ** psym; const char ** symv; - const char * asym[512]; + int * stype; if (!dctx->cctx->implib) return MDSO_CUSTOM_ERROR(dctx,MDSO_ERR_INVALID_NAME); @@ -55,7 +60,7 @@ int mdso_create_implib_archive(const struct mdso_driver_ctx * dctx) for (puctx=uctxv,unit=dctx->units; *unit; unit++) { if (mdso_get_unit_ctx(dctx,*unit,puctx)) { - mdso_free_uctx_vector(uctxv,fout); + mdso_free_uctx_vector(uctxv,0,0,fout); return MDSO_NESTED_ERROR(dctx); } } @@ -64,26 +69,25 @@ int mdso_create_implib_archive(const struct mdso_driver_ctx * dctx) for (dsym=puctx[0]->syms; *dsym; dsym++) nsym++; - if (nsym < 512) { - memset(asym,0,sizeof(asym)); - symv = asym; + if (!(symv = calloc(nsym+1,sizeof(const char *)))) { + mdso_free_uctx_vector(uctxv,0,0,fout); + return MDSO_SYSTEM_ERROR(dctx); + } - } else if (!(symv = calloc(nsym+1,sizeof(const char *)))) { - mdso_free_uctx_vector(uctxv,fout); + if (!(stype = calloc(nsym+1,sizeof(int)))) { + mdso_free_uctx_vector(uctxv,symv,0,fout); return MDSO_SYSTEM_ERROR(dctx); } - for (psym=symv,puctx=uctxv; *puctx; puctx++) - for (dsym=puctx[0]->syms; *dsym; dsym++) + for (psym=symv,puctx=uctxv; *puctx; puctx++) { + for (dsym=puctx[0]->syms; *dsym; dsym++) { + stype[psym-symv] = puctx[0]->stype[dsym-puctx[0]->syms]; *psym++ = *dsym; + } + } - qsort(symv,nsym,sizeof(*symv),mdso_symcmp); - ret = mdso_argen_common(dctx,symv,fout,0); - - if (symv != asym) - free(symv); - - mdso_free_uctx_vector(uctxv,fout); + ret = mdso_argen_common(dctx,symv,stype,fout,0); + mdso_free_uctx_vector(uctxv,symv,stype,fout); return ret ? MDSO_NESTED_ERROR(dctx) : 0; }