diff options
author | midipix <writeonce@midipix.org> | 2018-08-03 20:56:45 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2018-08-03 21:13:30 -0400 |
commit | a3e2cfa926e49bb4f63557bd990f83b8f4685734 (patch) | |
tree | 3edaf363a11a1fe1050780de272309ca0ac40db8 | |
parent | 18a091990a2de49fb0c9d85b0ae8e86825f2104f (diff) | |
download | mdso-a3e2cfa926e49bb4f63557bd990f83b8f4685734.tar.bz2 mdso-a3e2cfa926e49bb4f63557bd990f83b8f4685734.tar.xz |
library interfaces: object file generation: simplify, re-implement with mmap.
-rw-r--r-- | include/mdso/mdso.h | 9 | ||||
-rw-r--r-- | src/archive/mdso_argen_common.c | 12 | ||||
-rw-r--r-- | src/helper/mdso_create_output.c | 53 | ||||
-rw-r--r-- | src/object/mdso_objgen_dsometa.c | 38 | ||||
-rw-r--r-- | src/object/mdso_objgen_symentry.c | 38 | ||||
-rw-r--r-- | src/object/mdso_objgen_symfn.c | 38 | ||||
-rw-r--r-- | src/util/mdso_create_implib_objects.c | 42 |
7 files changed, 136 insertions, 94 deletions
diff --git a/include/mdso/mdso.h b/include/mdso/mdso.h index a0ecb0e..7927896 100644 --- a/include/mdso/mdso.h +++ b/include/mdso/mdso.h @@ -87,6 +87,7 @@ struct mdso_fd_ctx { }; struct mdso_object { + const char * name; void * addr; size_t size; char * mapstrs; @@ -159,7 +160,7 @@ mdso_api int mdso_set_driver_fdctx (struct mdso_driver_ctx *, const struct /* helper api */ mdso_api FILE*mdso_create_archive (const struct mdso_driver_ctx *, const char * arname); mdso_api int mdso_create_asmsrc (const struct mdso_driver_ctx *, const char * asmname); -mdso_api FILE*mdso_create_object (const struct mdso_driver_ctx *, const char * objname); +mdso_api int mdso_create_object (const struct mdso_driver_ctx *, struct mdso_object *); /* utility api */ mdso_api int mdso_main (int, char **, char **, const struct mdso_fd_ctx *); @@ -185,9 +186,9 @@ mdso_api int mdso_asmgen_dsometa (const struct mdso_driver_ctx *, int); mdso_api int mdso_asmgen_symentry (const struct mdso_driver_ctx *, const char *, int); mdso_api int mdso_asmgen_symfn (const struct mdso_driver_ctx *, const char *, int); -mdso_api int mdso_objgen_dsometa (const struct mdso_driver_ctx *, FILE *, struct mdso_object *); -mdso_api int mdso_objgen_symentry (const struct mdso_driver_ctx *, const char *, FILE *, struct mdso_object *); -mdso_api int mdso_objgen_symfn (const struct mdso_driver_ctx *, const char *, FILE *, struct mdso_object *); +mdso_api int mdso_objgen_dsometa (const struct mdso_driver_ctx *, struct mdso_object *); +mdso_api int mdso_objgen_symentry (const struct mdso_driver_ctx *, const char *, struct mdso_object *); +mdso_api int mdso_objgen_symfn (const struct mdso_driver_ctx *, const char *, struct mdso_object *); mdso_api int mdso_argen_common (const struct mdso_driver_ctx *, const char **, const int *, diff --git a/src/archive/mdso_argen_common.c b/src/archive/mdso_argen_common.c index 3cae712..62cca47 100644 --- a/src/archive/mdso_argen_common.c +++ b/src/archive/mdso_argen_common.c @@ -93,7 +93,7 @@ int mdso_argen_common( objlen += sizeof(struct pe_raw_archive_common_hdr); /* objlen: member headers */ - ret = mdso_objgen_dsometa(dctx,0,aobj); + ret = mdso_objgen_dsometa(dctx,aobj); aobj->size += 1; aobj->size |= 1; @@ -107,7 +107,7 @@ int mdso_argen_common( for (psym=symv,pobj=&aobj[1]; *psym && !ret; psym++) { if (stype[psym-symv] == MDSO_SYMBOL_TYPE_CODE) { - ret = mdso_objgen_symfn(dctx,*psym,0,pobj); + ret = mdso_objgen_symfn(dctx,*psym,pobj); pobj->size += 1; pobj->size |= 1; @@ -121,7 +121,7 @@ int mdso_argen_common( pobj++; } - ret |= mdso_objgen_symentry(dctx,*psym,0,pobj); + ret |= mdso_objgen_symentry(dctx,*psym,pobj); pobj->size += 1; pobj->size |= 1; @@ -205,7 +205,7 @@ int mdso_argen_common( idx += sizeof(uint32_t); } - ret = mdso_objgen_dsometa(dctx,0,aobj); + ret = mdso_objgen_dsometa(dctx,aobj); mdso_argen_common_hdr( (struct pe_raw_archive_common_hdr *)mark, @@ -228,7 +228,7 @@ int mdso_argen_common( idx += sizeof(uint32_t); } - ret = mdso_objgen_symfn(dctx,*psym,0,pobj); + ret = mdso_objgen_symfn(dctx,*psym,pobj); sprintf( objname,"f%06zu.o", @@ -259,7 +259,7 @@ int mdso_argen_common( objname,"s%06zu.o", psym - symv); - ret = mdso_objgen_symentry(dctx,*psym,0,pobj); + ret = mdso_objgen_symentry(dctx,*psym,pobj); mdso_argen_common_hdr( (struct pe_raw_archive_common_hdr *)mark, diff --git a/src/helper/mdso_create_output.c b/src/helper/mdso_create_output.c index 24ed757..39dd4d7 100644 --- a/src/helper/mdso_create_output.c +++ b/src/helper/mdso_create_output.c @@ -10,6 +10,7 @@ #include <stddef.h> #include <unistd.h> #include <fcntl.h> +#include <sys/mman.h> #include <mdso/mdso.h> #include "mdso_driver_impl.h" @@ -25,13 +26,40 @@ static int mdso_create_output( fddst = mdso_driver_fddst(dctx); if ((fdout = openat(fddst,name, - O_CREAT|O_TRUNC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) + O_CREAT|O_TRUNC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) return MDSO_SYSTEM_ERROR(dctx); return fdout; } +static int mdso_map_output( + const struct mdso_driver_ctx * dctx, + struct mdso_object * obj, + int fd) +{ + void * addr; + + if (ftruncate(fd,obj->size)) { + close(fd); + return MDSO_SYSTEM_ERROR(dctx); + } + + addr = mmap( + 0,obj->size, + PROT_WRITE,MAP_SHARED, + fd,0); + + close(fd); + + if (addr == MAP_FAILED) + return MDSO_SYSTEM_ERROR(dctx); + + obj->addr = addr; + + return 0; +} + static FILE * mdso_create_output_stream( const struct mdso_driver_ctx * dctx, const char * name) @@ -51,6 +79,21 @@ static FILE * mdso_create_output_stream( return fout; } +static int mdso_create_mapped_output( + const struct mdso_driver_ctx * dctx, + struct mdso_object * obj) +{ + int fd; + + if ((fd = mdso_create_output(dctx,obj->name)) < 0) + return MDSO_NESTED_ERROR(dctx); + + if (mdso_map_output(dctx,obj,fd) < 0) + return MDSO_NESTED_ERROR(dctx); + + return 0; +} + FILE * mdso_create_archive( const struct mdso_driver_ctx * dctx, const char * arname) @@ -67,9 +110,9 @@ int mdso_create_asmsrc( : mdso_driver_fdout(dctx); } -FILE * mdso_create_object( +int mdso_create_object( const struct mdso_driver_ctx * dctx, - const char * objname) + struct mdso_object * obj) { - return mdso_create_output_stream(dctx,objname); + return mdso_create_mapped_output(dctx,obj); } diff --git a/src/object/mdso_objgen_dsometa.c b/src/object/mdso_objgen_dsometa.c index dfe8a33..388e296 100644 --- a/src/object/mdso_objgen_dsometa.c +++ b/src/object/mdso_objgen_dsometa.c @@ -9,6 +9,7 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <sys/mman.h> #include <mdso/mdso.h> #include <mdso/mdso_specs.h> @@ -32,11 +33,11 @@ struct mdso_dsometa_object { int mdso_objgen_dsometa( const struct mdso_driver_ctx * dctx, - FILE * fout, struct mdso_object * vobj) { struct mdso_dsometa_object * dsometa; struct pe_raw_coff_symbol * symrec; + void * addr; unsigned char * mark; struct pe_raw_aux_rec_section * aux; size_t buflen; @@ -65,21 +66,25 @@ int mdso_objgen_dsometa( cstlen = (3 * liblen) + 48; objlen = sizeof(*dsometa) + cstlen; - if (vobj && vobj->addr && (vobj->size < objlen)) + if (vobj->addr && (vobj->size < objlen)) return MDSO_BUFFER_ERROR(dctx); - if (vobj && !vobj->addr) { - vobj->size = objlen; + if ((addr = vobj->addr)) { + (void)0; + + } else { + vobj->size = objlen; vobj->mapstrsnum = 1; vobj->mapstrslen = 10 + liblen; - return 0; - } - if (vobj) - dsometa = (struct mdso_dsometa_object *)vobj->addr; + if (!vobj->name) + return 0; + + else if (mdso_create_object(dctx,vobj) < 0) + return MDSO_NESTED_ERROR(dctx); + } - else if (!(dsometa = calloc(1,objlen))) - return MDSO_SYSTEM_ERROR(dctx); + dsometa = (struct mdso_dsometa_object *)vobj->addr; if (dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR) { reclen = sizeof(struct mdso_meta_record_m64); @@ -220,20 +225,17 @@ int mdso_objgen_dsometa( memcpy(&mark[9],dctx->cctx->libname,liblen); /* archive symbol map */ - if (vobj && vobj->mapstrs) + if (vobj->mapstrs) memcpy(vobj->mapstrs,mark,9+liblen); /* .libname */ mark = dsometa->hdr.cfh_machine; memcpy(&mark[stroff],dctx->cctx->libname,liblen); - /* tada */ - if (fout) - if (fwrite(dsometa,objlen,1,fout) == 0) - return MDSO_FILE_ERROR(dctx); - - if (!vobj) - free(dsometa); + /* fs object unmap */ + if (!addr) + munmap(vobj->addr,vobj->size); + /* tada */ return 0; } diff --git a/src/object/mdso_objgen_symentry.c b/src/object/mdso_objgen_symentry.c index 47167c7..7ddc14c 100644 --- a/src/object/mdso_objgen_symentry.c +++ b/src/object/mdso_objgen_symentry.c @@ -9,6 +9,7 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <sys/mman.h> #include <mdso/mdso.h> #include "mdso_object_impl.h" @@ -32,11 +33,11 @@ struct mdso_symentry_object { int mdso_objgen_symentry( const struct mdso_driver_ctx * dctx, const char * sym, - FILE * fout, struct mdso_object * vobj) { struct mdso_symentry_object * syment; struct pe_raw_coff_symbol * symrec; + void * addr; unsigned char * mark; unsigned char * mapsym; struct pe_raw_aux_rec_section * aux; @@ -71,21 +72,25 @@ int mdso_objgen_symentry( objlen = sizeof(*syment) + cstlen; uscore = !(dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR); - if (vobj && vobj->addr && (vobj->size < objlen)) + if (vobj->addr && (vobj->size < objlen)) return MDSO_BUFFER_ERROR(dctx); - if (vobj && !vobj->addr) { - vobj->size = objlen; + if ((addr = vobj->addr)) { + (void)0; + + } else { + vobj->size = objlen; vobj->mapstrsnum = 1; vobj->mapstrslen = 7 + uscore + symlen; - return 0; - } - if (vobj) - syment = (struct mdso_symentry_object *)vobj->addr; + if (!vobj->name) + return 0; + + else if (mdso_create_object(dctx,vobj) < 0) + return MDSO_NESTED_ERROR(dctx); + } - else if (!(syment = calloc(1,objlen))) - return MDSO_SYSTEM_ERROR(dctx); + syment = (struct mdso_symentry_object *)vobj->addr; if (dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR) { aattr = PE_IMAGE_SCN_ALIGN_16BYTES; @@ -238,7 +243,7 @@ int mdso_objgen_symentry( symrec += 1; /* archive symbol map */ - if (vobj && vobj->mapstrs) + if (vobj->mapstrs) memcpy(vobj->mapstrs,mapsym,mark-mapsym); /* coff symbol: .dsometa_libname */ @@ -255,13 +260,10 @@ int mdso_objgen_symentry( mark = syment->hdr.cfh_machine; memcpy(&mark[stroff],sym,symlen); - /* tada */ - if (fout) - if (fwrite(syment,objlen,1,fout) == 0) - return MDSO_FILE_ERROR(dctx); - - if (!vobj) - free(syment); + /* fs object unmap */ + if (!addr) + munmap(vobj->addr,vobj->size); + /* tada */ return 0; } diff --git a/src/object/mdso_objgen_symfn.c b/src/object/mdso_objgen_symfn.c index 47f9280..6f4ac68 100644 --- a/src/object/mdso_objgen_symfn.c +++ b/src/object/mdso_objgen_symfn.c @@ -9,6 +9,7 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <sys/mman.h> #include <mdso/mdso.h> #include "mdso_object_impl.h" @@ -46,12 +47,12 @@ struct mdso_symfn_object { int mdso_objgen_symfn( const struct mdso_driver_ctx * dctx, const char * sym, - FILE * fout, struct mdso_object * vobj) { struct mdso_symfn_object * symfn; struct pe_raw_coff_symbol * symrec; const unsigned char * code; + void * addr; unsigned char * mark; unsigned char * mapsym; struct pe_raw_aux_rec_section * aux; @@ -80,21 +81,25 @@ int mdso_objgen_symfn( objlen = sizeof(*symfn) + cstlen; uscore = !(dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR); - if (vobj && vobj->addr && (vobj->size < objlen)) + if (vobj->addr && (vobj->size < objlen)) return MDSO_BUFFER_ERROR(dctx); - if (vobj && !vobj->addr) { - vobj->size = objlen; + if ((addr = vobj->addr)) { + (void)0; + + } else { + vobj->size = objlen; vobj->mapstrsnum = 1; vobj->mapstrslen = 1 + uscore + symlen; - return 0; - } - if (vobj) - symfn = (struct mdso_symfn_object *)vobj->addr; + if (!vobj->name) + return 0; + + else if (mdso_create_object(dctx,vobj) < 0) + return MDSO_NESTED_ERROR(dctx); + } - else if (!(symfn = calloc(1,objlen))) - return MDSO_SYSTEM_ERROR(dctx); + symfn = (struct mdso_symfn_object *)vobj->addr; if (dctx->cctx->drvflags & MDSO_DRIVER_QUAD_PTR) { code = jmp_code_amd64; @@ -206,7 +211,7 @@ int mdso_objgen_symfn( symrec += 2; /* archive symbol map */ - if (vobj && vobj->mapstrs) + if (vobj->mapstrs) memcpy(vobj->mapstrs,mapsym,mark-mapsym); /* coff symbol: __imp_sym */ @@ -227,13 +232,10 @@ int mdso_objgen_symfn( mark++; } - /* tada */ - if (fout) - if (fwrite(symfn,objlen,1,fout) == 0) - return MDSO_FILE_ERROR(dctx); - - if (!vobj) - free(symfn); + /* fs object unmap */ + if (!addr) + munmap(vobj->addr,vobj->size); + /* tada */ return 0; } diff --git a/src/util/mdso_create_implib_objects.c b/src/util/mdso_create_implib_objects.c index 5740109..43f79ee 100644 --- a/src/util/mdso_create_implib_objects.c +++ b/src/util/mdso_create_implib_objects.c @@ -24,14 +24,19 @@ static void mdso_init_objname(char * buf, const char * fmt, const char * str) sprintf(buf,fmt,str); } -mdso_api int mdso_create_implib_objects(const struct mdso_driver_ctx * dctx) +static void mdso_init_object(struct mdso_object * obj, const char * objname) +{ + memset(obj,0,sizeof(*obj)); + obj->name = objname; +} + +int mdso_create_implib_objects(const struct mdso_driver_ctx * dctx) { - struct mdso_unit_ctx * uctx; const char ** unit; - FILE * fout; - char objname[PATH_MAX]; + struct mdso_unit_ctx * uctx; + struct mdso_object obj; const char * const * sym; - int ret; + char objname[PATH_MAX]; /* symentry, symfn */ for (unit=dctx->units; *unit; unit++) { @@ -40,26 +45,16 @@ mdso_api int mdso_create_implib_objects(const struct mdso_driver_ctx * dctx) for (sym=uctx->syms; *sym; sym++) { mdso_init_objname(objname,".%s_symentry.o",*sym); + mdso_init_object(&obj,objname); - if (!(fout = mdso_create_object(dctx,objname))) - return MDSO_NESTED_ERROR(dctx); - - ret = mdso_objgen_symentry(dctx,*sym,fout,0); - fclose(fout); - - if (ret < 0) + if (mdso_objgen_symentry(dctx,*sym,&obj) < 0) return MDSO_NESTED_ERROR(dctx); if (uctx->stype[sym-uctx->syms] == MDSO_SYMBOL_TYPE_CODE) { mdso_init_objname(objname,".%s_symfn.o",*sym); + mdso_init_object(&obj,objname); - if (!(fout = mdso_create_object(dctx,objname))) - return MDSO_NESTED_ERROR(dctx); - - ret = mdso_objgen_symfn(dctx,*sym,fout,0); - fclose(fout); - - if (ret < 0) + if (mdso_objgen_symfn(dctx,*sym,&obj) < 0) return MDSO_NESTED_ERROR(dctx); } } @@ -69,13 +64,10 @@ mdso_api int mdso_create_implib_objects(const struct mdso_driver_ctx * dctx) /* dsometa */ mdso_init_objname(objname,".dsometa_%s.o",dctx->cctx->libname); + mdso_init_object(&obj,objname); - if (!(fout = mdso_create_object(dctx,objname))) + if (mdso_objgen_dsometa(dctx,&obj) < 0) return MDSO_NESTED_ERROR(dctx); - ret = mdso_objgen_dsometa(dctx,fout,0); - fclose(fout); - - return (ret < 0) ? MDSO_NESTED_ERROR(dctx) : 0; - + return 0; } |