diff --git a/include/mdso/mdso.h b/include/mdso/mdso.h index 6ef0c0a..5822880 100644 --- a/include/mdso/mdso.h +++ b/include/mdso/mdso.h @@ -34,6 +34,7 @@ extern "C" { #define MDSO_DRIVER_DRY_RUN 0x0020 #define MDSO_DRIVER_QUAD_PTR 0x0040 #define MDSO_DRIVER_GENERATE_ASM 0x0100 +#define MDSO_DRIVER_GENERATE_OBJECTS 0x0200 #define MDSO_DRIVER_ANNOTATE_ALWAYS 0x1000 #define MDSO_DRIVER_ANNOTATE_NEVER 0x2000 @@ -51,6 +52,7 @@ enum mdso_custom_error { MDSO_ERR_NULL_CONTEXT, MDSO_ERR_NULL_SOURCE, MDSO_ERR_INVALID_DATA, + MDSO_ERR_INVALID_DSTDIR, MDSO_ERR_INVALID_CONTEXT, MDSO_ERR_INVALID_SOURCE, MDSO_ERR_SOURCE_SIZE_ZERO, @@ -134,10 +136,12 @@ mdso_api int mdso_unmap_input (struct mdso_input *); /* helper api */ mdso_api FILE*mdso_create_asm_source (const struct mdso_driver_ctx *, const char * asmname); +mdso_api FILE*mdso_create_object (const struct mdso_driver_ctx *, const char * objname); /* utility api */ mdso_api int mdso_main (int, char **, char **); mdso_api int mdso_create_implib_sources(const struct mdso_driver_ctx *); +mdso_api int mdso_create_implib_objects(const struct mdso_driver_ctx *); mdso_api int mdso_output_export_symbols(const struct mdso_driver_ctx *, const struct mdso_unit_ctx *, FILE *); mdso_api int mdso_output_error_record (const struct mdso_driver_ctx *, const struct mdso_error_info *); mdso_api int mdso_output_error_vector (const struct mdso_driver_ctx *); diff --git a/project/common.mk b/project/common.mk index fc3d5c1..65bcd2e 100644 --- a/project/common.mk +++ b/project/common.mk @@ -10,6 +10,7 @@ API_SRCS = \ src/logic/mdso_asmgen_symentry.c \ src/logic/mdso_asmgen_symfn.c \ src/logic/mdso_map_input.c \ + src/object/mdso_create_implib_objects.c \ src/object/mdso_objgen_dsometa.c \ src/object/mdso_objgen_symentry.c \ src/object/mdso_objgen_symfn.c \ diff --git a/src/driver/mdso_amain.c b/src/driver/mdso_amain.c index b85a568..629b606 100644 --- a/src/driver/mdso_amain.c +++ b/src/driver/mdso_amain.c @@ -81,6 +81,9 @@ int mdso_main(int argc, char ** argv, char ** envp) if (dctx->cctx->drvflags & MDSO_DRIVER_GENERATE_ASM) mdso_create_implib_sources(dctx); + if (dctx->cctx->drvflags & MDSO_DRIVER_GENERATE_OBJECTS) + mdso_create_implib_objects(dctx); + for (unit=dctx->units; *unit && !dctx->errv[0]; unit++) { if (!(mdso_get_unit_ctx(dctx,*unit,&uctx))) { mdso_perform_unit_actions(dctx,uctx); diff --git a/src/driver/mdso_driver_ctx.c b/src/driver/mdso_driver_ctx.c index 1c96911..3decf70 100644 --- a/src/driver/mdso_driver_ctx.c +++ b/src/driver/mdso_driver_ctx.c @@ -196,6 +196,10 @@ int mdso_get_driver_ctx( cctx.drvflags |= MDSO_DRIVER_GENERATE_ASM; break; + case TAG_OBJ: + cctx.drvflags |= MDSO_DRIVER_GENERATE_OBJECTS; + break; + case TAG_QUAD_PTR: if (!(strcmp(entry->arg,"64"))) cctx.drvflags |= MDSO_DRIVER_QUAD_PTR; diff --git a/src/helper/mdso_create_asm_source.c b/src/helper/mdso_create_asm_source.c index 85aaaba..b152697 100644 --- a/src/helper/mdso_create_asm_source.c +++ b/src/helper/mdso_create_asm_source.c @@ -15,22 +15,19 @@ #include "mdso_driver_impl.h" #include "mdso_errinfo_impl.h" -FILE * mdso_create_asm_source( +static FILE * mdso_create_output( const struct mdso_driver_ctx * dctx, - const char * asmname) + const char * name) { struct mdso_driver_ctx_impl * ictx; uintptr_t addr; int fdout; FILE * fout; - if (!dctx->cctx->dstdir) - return stdout; - addr = (uintptr_t)dctx - offsetof(struct mdso_driver_ctx_impl,ctx); ictx = (struct mdso_driver_ctx_impl *)addr; - if ((fdout = openat(ictx->fddst,asmname, + if ((fdout = openat(ictx->fddst,name, O_CREAT|O_TRUNC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { MDSO_SYSTEM_ERROR(dctx); @@ -45,3 +42,25 @@ FILE * mdso_create_asm_source( return fout; } + +FILE * mdso_create_asm_source( + const struct mdso_driver_ctx * dctx, + const char * asmname) +{ + if (!dctx->cctx->dstdir) + return stdout; + + return mdso_create_output(dctx,asmname); +} + +FILE * mdso_create_object( + const struct mdso_driver_ctx * dctx, + const char * objname) +{ + if (!dctx->cctx->dstdir) { + MDSO_CUSTOM_ERROR(dctx,MDSO_ERR_INVALID_DSTDIR); + return 0; + } + + return mdso_create_output(dctx,objname); +} diff --git a/src/internal/mdso_driver_impl.h b/src/internal/mdso_driver_impl.h index 5e260f8..ffeae9d 100644 --- a/src/internal/mdso_driver_impl.h +++ b/src/internal/mdso_driver_impl.h @@ -16,6 +16,7 @@ enum app_tags { TAG_HELP, TAG_VERSION, TAG_ASM, + TAG_OBJ, TAG_QUAD_PTR, TAG_LIBPATH, TAG_LIBNAME, diff --git a/src/object/mdso_create_implib_objects.c b/src/object/mdso_create_implib_objects.c new file mode 100644 index 0000000..dd681e0 --- /dev/null +++ b/src/object/mdso_create_implib_objects.c @@ -0,0 +1,79 @@ +/****************************************************************/ +/* mdso: midipix dso scavenger */ +/* Copyright (C) 2015--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.MDSO. */ +/****************************************************************/ + +#include +#include +#include + +#include +#include "mdso_errinfo_impl.h" + +static void mdso_init_objname(char * buf, const char * fmt, const char * str) +{ + char hexstr[24]; + long long unsigned int crc64; + + if (strlen(str) + strlen(fmt) > (PATH_MAX - 1)) { + crc64 = mdso_crc64_mbstr((const unsigned char *)str,0); + sprintf(hexstr,"%llx",crc64); + sprintf(buf,fmt,hexstr); + } else + sprintf(buf,fmt,str); +} + +mdso_api 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]; + const char * const * sym; + int ret; + + mdso_init_objname(objname,".dsometa_%s.o",dctx->cctx->libname); + + if (!(fout = mdso_create_object(dctx,objname))) + return MDSO_NESTED_ERROR(dctx); + + ret = mdso_objgen_dsometa(dctx,fout,0); + fclose(fout); + + if (ret < 0) + return MDSO_NESTED_ERROR(dctx); + + for (unit=dctx->units; *unit; unit++) { + if (mdso_get_unit_ctx(dctx,*unit,&uctx)) + return MDSO_NESTED_ERROR(dctx); + + for (sym=uctx->syms; *sym; sym++) { + mdso_init_objname(objname,".%s_symentry.o",*sym); + + 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) + return MDSO_NESTED_ERROR(dctx); + + mdso_init_objname(objname,".%s_symfn.o",*sym); + + 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) + return MDSO_NESTED_ERROR(dctx); + } + + mdso_free_unit_ctx(uctx); + } + + return 0; +} diff --git a/src/output/mdso_output_error.c b/src/output/mdso_output_error.c index 53974fc..08d66dc 100644 --- a/src/output/mdso_output_error.c +++ b/src/output/mdso_output_error.c @@ -23,6 +23,8 @@ static const char const * const mdso_error_strings[MDSO_ERR_CAP] = { [MDSO_ERR_FLEE_ERROR] = "flees and bugs and cats and mice", [MDSO_ERR_NULL_CONTEXT] = "null driver or unit context", [MDSO_ERR_NULL_SOURCE] = "source file does not define any symbols", + [MDSO_ERR_INVALID_DATA] = "invalid data (symbol name too long)", + [MDSO_ERR_INVALID_DSTDIR] = "invalid destination directory", [MDSO_ERR_INVALID_CONTEXT] = "invalid driver or unit context", [MDSO_ERR_INVALID_SOURCE] = "invalid symbol definition source file", [MDSO_ERR_SOURCE_SIZE_ZERO] = "cannot map an empty symbol definition source file", diff --git a/src/skin/mdso_skin_default.c b/src/skin/mdso_skin_default.c index e7ad452..1c0151e 100644 --- a/src/skin/mdso_skin_default.c +++ b/src/skin/mdso_skin_default.c @@ -11,6 +11,9 @@ const struct argv_option mdso_default_options[] = { {"asm", 'a',TAG_ASM,ARGV_OPTARG_NONE,0,0,0, "generate assembly sources"}, + {"obj", 'b',TAG_OBJ,ARGV_OPTARG_NONE,0,0,0, + "generate objects"}, + {"machine", 'm',TAG_QUAD_PTR,ARGV_OPTARG_REQUIRED,0,"32|64",0, "set machine bits to %s"},