summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mdso/mdso.h4
-rw-r--r--project/common.mk1
-rw-r--r--src/driver/mdso_amain.c3
-rw-r--r--src/driver/mdso_driver_ctx.c27
-rw-r--r--src/helper/mdso_create_output.c17
-rw-r--r--src/internal/mdso_driver_impl.h2
-rw-r--r--src/output/mdso_output_error.c1
-rw-r--r--src/skin/mdso_skin_default.c3
-rw-r--r--src/util/mdso_create_implib_archive.c83
9 files changed, 132 insertions, 9 deletions
diff --git a/include/mdso/mdso.h b/include/mdso/mdso.h
index 105a9c5..62ec354 100644
--- a/include/mdso/mdso.h
+++ b/include/mdso/mdso.h
@@ -51,6 +51,7 @@ enum mdso_custom_error {
MDSO_ERR_FLEE_ERROR,
MDSO_ERR_NULL_CONTEXT,
MDSO_ERR_NULL_SOURCE,
+ MDSO_ERR_INVALID_NAME,
MDSO_ERR_INVALID_DATA,
MDSO_ERR_INVALID_DSTDIR,
MDSO_ERR_INVALID_CONTEXT,
@@ -99,6 +100,7 @@ struct mdso_common_ctx {
uint64_t actflags;
uint64_t fmtflags;
uint32_t dsoflags;
+ const char * implib;
const char * libname;
const char * asmbase;
const char * dstdir;
@@ -136,11 +138,13 @@ mdso_api int mdso_map_input (const struct mdso_driver_ctx *, int fd, const cha
mdso_api int mdso_unmap_input (struct mdso_input *);
/* helper api */
+mdso_api FILE*mdso_create_archive (const struct mdso_driver_ctx *, const char * arname);
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_archive(const struct mdso_driver_ctx *);
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 *);
diff --git a/project/common.mk b/project/common.mk
index 5b1c676..8f693ff 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -16,6 +16,7 @@ API_SRCS = \
src/output/mdso_output_error.c \
src/output/mdso_output_export_symbols.c \
src/skin/mdso_skin_default.c \
+ src/util/mdso_create_implib_archive.c \
src/util/mdso_create_implib_objects.c \
src/util/mdso_create_implib_sources.c \
diff --git a/src/driver/mdso_amain.c b/src/driver/mdso_amain.c
index 629b606..70fb44a 100644
--- a/src/driver/mdso_amain.c
+++ b/src/driver/mdso_amain.c
@@ -78,6 +78,9 @@ int mdso_main(int argc, char ** argv, char ** envp)
if ((mdso_version(dctx)) < 0)
return mdso_exit(dctx,MDSO_ERROR);
+ if (dctx->cctx->implib)
+ mdso_create_implib_archive(dctx);
+
if (dctx->cctx->drvflags & MDSO_DRIVER_GENERATE_ASM)
mdso_create_implib_sources(dctx);
diff --git a/src/driver/mdso_driver_ctx.c b/src/driver/mdso_driver_ctx.c
index 3decf70..5dd9449 100644
--- a/src/driver/mdso_driver_ctx.c
+++ b/src/driver/mdso_driver_ctx.c
@@ -131,12 +131,16 @@ static int mdso_dstdir_open(const struct mdso_common_ctx * cctx, const char * as
static int mdso_get_driver_ctx_fail(
struct argv_meta * meta,
+ char * implib,
char * asmbase,
int fddst)
{
if (fddst >= 0)
close(fddst);
+ if (implib)
+ free(implib);
+
if (asmbase)
free(asmbase);
@@ -158,6 +162,7 @@ int mdso_get_driver_ctx(
size_t nunits;
const char * program;
const char * pretty;
+ char * implib;
char * asmbase;
char * dot;
int fddst;
@@ -171,6 +176,7 @@ int mdso_get_driver_ctx(
nunits = 0;
pretty = 0;
+ implib = 0;
asmbase = 0;
fddst = -1;
program = argv_program_name(argv[0]);
@@ -207,6 +213,10 @@ int mdso_get_driver_ctx(
cctx.drvflags &= ~(uint64_t)MDSO_DRIVER_QUAD_PTR;
break;
+ case TAG_IMPLIB:
+ cctx.implib = entry->arg;
+ break;
+
case TAG_LIBPATH:
if (!(strcmp(entry->arg,"loader")))
cctx.dsoflags |= MDSO_FLAG_LOADER_PATH;
@@ -245,18 +255,22 @@ int mdso_get_driver_ctx(
if (!cctx.libname)
cctx.libname = "win32any";
+ if (cctx.implib && !(implib = strdup(cctx.implib)))
+ return mdso_get_driver_ctx_fail(meta,0,0,fddst);
+
if (!(asmbase = strdup(cctx.libname)))
- return mdso_get_driver_ctx_fail(meta,asmbase,fddst);
+ return mdso_get_driver_ctx_fail(meta,implib,0,fddst);
if ((dot = strchr(asmbase,'.')))
*dot = '\0';
if (cctx.dstdir && (fddst = mdso_dstdir_open(&cctx,asmbase)) < 0)
- return mdso_get_driver_ctx_fail(meta,asmbase,fddst);
+ return mdso_get_driver_ctx_fail(meta,implib,asmbase,fddst);
if (!(ctx = mdso_driver_ctx_alloc(meta,&cctx,nunits)))
- return mdso_get_driver_ctx_fail(meta,asmbase,fddst);
+ return mdso_get_driver_ctx_fail(meta,implib,asmbase,fddst);
+ ctx->implib = implib;
ctx->asmbase = asmbase;
ctx->cctx.asmbase = asmbase;
@@ -284,10 +298,10 @@ int mdso_create_driver_ctx(
return -1;
if (cctx->dstdir && (fddst = mdso_dstdir_open(cctx,cctx->asmbase)) < 0)
- return mdso_get_driver_ctx_fail(meta,0,fddst);
+ return mdso_get_driver_ctx_fail(meta,0,0,fddst);
if (!(ctx = mdso_driver_ctx_alloc(meta,cctx,0)))
- return mdso_get_driver_ctx_fail(meta,0,fddst);
+ return mdso_get_driver_ctx_fail(meta,0,0,fddst);
ctx->ctx.cctx = &ctx->cctx;
*pctx = &ctx->ctx;
@@ -305,6 +319,9 @@ static void mdso_free_driver_ctx_impl(struct mdso_driver_ctx_alloc * ictx)
if (ictx->ctx.asmbase)
free(ictx->ctx.asmbase);
+ if (ictx->ctx.implib)
+ free(ictx->ctx.implib);
+
argv_free(ictx->meta);
free(ictx);
}
diff --git a/src/helper/mdso_create_output.c b/src/helper/mdso_create_output.c
index b152697..5f4a761 100644
--- a/src/helper/mdso_create_output.c
+++ b/src/helper/mdso_create_output.c
@@ -17,7 +17,8 @@
static FILE * mdso_create_output(
const struct mdso_driver_ctx * dctx,
- const char * name)
+ const char * name,
+ int fdat)
{
struct mdso_driver_ctx_impl * ictx;
uintptr_t addr;
@@ -26,8 +27,9 @@ static FILE * mdso_create_output(
addr = (uintptr_t)dctx - offsetof(struct mdso_driver_ctx_impl,ctx);
ictx = (struct mdso_driver_ctx_impl *)addr;
+ fdat = (fdat == AT_FDCWD) ? AT_FDCWD : ictx->fddst;
- if ((fdout = openat(ictx->fddst,name,
+ if ((fdout = openat(fdat,name,
O_CREAT|O_TRUNC|O_WRONLY|O_NOCTTY|O_NOFOLLOW,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
MDSO_SYSTEM_ERROR(dctx);
@@ -43,6 +45,13 @@ static FILE * mdso_create_output(
return fout;
}
+FILE * mdso_create_archive(
+ const struct mdso_driver_ctx * dctx,
+ const char * arname)
+{
+ return mdso_create_output(dctx,arname,AT_FDCWD);
+}
+
FILE * mdso_create_asm_source(
const struct mdso_driver_ctx * dctx,
const char * asmname)
@@ -50,7 +59,7 @@ FILE * mdso_create_asm_source(
if (!dctx->cctx->dstdir)
return stdout;
- return mdso_create_output(dctx,asmname);
+ return mdso_create_output(dctx,asmname,-1);
}
FILE * mdso_create_object(
@@ -62,5 +71,5 @@ FILE * mdso_create_object(
return 0;
}
- return mdso_create_output(dctx,objname);
+ return mdso_create_output(dctx,objname,-1);
}
diff --git a/src/internal/mdso_driver_impl.h b/src/internal/mdso_driver_impl.h
index ffeae9d..6b092dc 100644
--- a/src/internal/mdso_driver_impl.h
+++ b/src/internal/mdso_driver_impl.h
@@ -18,6 +18,7 @@ enum app_tags {
TAG_ASM,
TAG_OBJ,
TAG_QUAD_PTR,
+ TAG_IMPLIB,
TAG_LIBPATH,
TAG_LIBNAME,
TAG_DSTDIR,
@@ -34,6 +35,7 @@ struct mdso_driver_ctx_impl {
struct mdso_common_ctx cctx;
struct mdso_driver_ctx ctx;
char * asmbase;
+ char * implib;
int fddst;
int fdtmpin;
const struct mdso_unit_ctx * euctx;
diff --git a/src/output/mdso_output_error.c b/src/output/mdso_output_error.c
index 4793a35..d06d01e 100644
--- a/src/output/mdso_output_error.c
+++ b/src/output/mdso_output_error.c
@@ -23,6 +23,7 @@ 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_NAME] = "invalid or missing import library archive name",
[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",
diff --git a/src/skin/mdso_skin_default.c b/src/skin/mdso_skin_default.c
index 1c0151e..fdff8ad 100644
--- a/src/skin/mdso_skin_default.c
+++ b/src/skin/mdso_skin_default.c
@@ -8,6 +8,9 @@ const struct argv_option mdso_default_options[] = {
{"help", 'h',TAG_HELP,ARGV_OPTARG_OPTIONAL,0,"short|long",0,
"show usage information [listing %s options only]"},
+ {"implib", 'i',TAG_IMPLIB,ARGV_OPTARG_REQUIRED,0,0,"<path>",
+ "create an import library archive"},
+
{"asm", 'a',TAG_ASM,ARGV_OPTARG_NONE,0,0,0,
"generate assembly sources"},
diff --git a/src/util/mdso_create_implib_archive.c b/src/util/mdso_create_implib_archive.c
new file mode 100644
index 0000000..323b318
--- /dev/null
+++ b/src/util/mdso_create_implib_archive.c
@@ -0,0 +1,83 @@
+/****************************************************************/
+/* mdso: midipix dso scavenger */
+/* Copyright (C) 2015--2017 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.MDSO. */
+/****************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <mdso/mdso.h>
+#include "mdso_errinfo_impl.h"
+
+static void mdso_free_uctx_vector(struct mdso_unit_ctx ** uctxv)
+{
+ struct mdso_unit_ctx ** puctx;
+
+ for (puctx=uctxv; *puctx; puctx++)
+ mdso_free_unit_ctx(*puctx);
+
+ free(uctxv);
+}
+
+int mdso_create_implib_archive(const struct mdso_driver_ctx * dctx)
+{
+ int ret;
+ FILE * fout;
+ size_t nsym;
+ struct mdso_unit_ctx ** uctxv;
+ struct mdso_unit_ctx ** puctx;
+ const char * const * dsym;
+ const char ** unit;
+ const char ** psym;
+ const char ** symv;
+ const char * asym[512];
+
+ if (!dctx->cctx->implib)
+ return MDSO_CUSTOM_ERROR(dctx,MDSO_ERR_INVALID_NAME);
+
+ if (!(fout = mdso_create_archive(dctx,dctx->cctx->implib)))
+ return MDSO_NESTED_ERROR(dctx);
+
+ for (unit=dctx->units; *unit; unit++)
+ (void)0;
+
+ if (!(uctxv = calloc(++unit - dctx->units,sizeof(*uctxv))))
+ return MDSO_SYSTEM_ERROR(dctx);
+
+ for (puctx=uctxv,unit=dctx->units; *unit; unit++) {
+ if (mdso_get_unit_ctx(dctx,*unit,puctx)) {
+ mdso_free_uctx_vector(uctxv);
+ return MDSO_NESTED_ERROR(dctx);
+ }
+ }
+
+ for (nsym=0,puctx=uctxv; *puctx; puctx++)
+ for (dsym=puctx[0]->syms; *dsym; dsym++)
+ nsym++;
+
+ if (nsym < 512) {
+ memset(asym,0,sizeof(asym));
+ symv = asym;
+
+ } else if (!(symv = calloc(nsym+1,sizeof(const char *)))) {
+ mdso_free_uctx_vector(uctxv);
+ return MDSO_SYSTEM_ERROR(dctx);
+ }
+
+ for (psym=symv,puctx=uctxv; *puctx; puctx++)
+ for (dsym=puctx[0]->syms; *dsym; dsym++)
+ *psym++ = *dsym;
+
+ ret = mdso_argen_common(dctx,symv,fout,0);
+ fclose(fout);
+
+ if (symv != asym)
+ free(symv);
+
+ mdso_free_uctx_vector(uctxv);
+
+ return ret ? MDSO_NESTED_ERROR(dctx) : 0;
+}