summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/perk/perk.h10
-rw-r--r--src/driver/pe_unit_ctx.c25
-rw-r--r--src/internal/perk_impl.h8
-rw-r--r--src/perk.c18
4 files changed, 44 insertions, 17 deletions
diff --git a/include/perk/perk.h b/include/perk/perk.h
index f19e596..0b84349 100644
--- a/include/perk/perk.h
+++ b/include/perk/perk.h
@@ -135,10 +135,12 @@ struct pe_driver_ctx {
};
struct pe_unit_ctx {
- const char * path;
- struct pe_raw_image map;
- struct pe_image_meta * meta;
- struct pe_common_ctx cctx;
+ const char * const * path;
+ const struct pe_raw_image * map;
+ const struct pe_image_meta * meta;
+ const struct pe_common_ctx * cctx;
+ int status;
+ int nerrors;
};
/* driver api */
diff --git a/src/driver/pe_unit_ctx.c b/src/driver/pe_unit_ctx.c
index b86719c..df5409b 100644
--- a/src/driver/pe_unit_ctx.c
+++ b/src/driver/pe_unit_ctx.c
@@ -1,10 +1,13 @@
#include <stdint.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
+
#include <perk/perk.h>
+#include "perk_impl.h"
-static int pe_free_unit_ctx_impl(struct pe_unit_ctx * ctx, int status)
+static int pe_free_unit_ctx_impl(struct pe_unit_ctx_impl * ctx, int status)
{
if (ctx) {
pe_free_image_meta(ctx->meta);
@@ -20,7 +23,7 @@ int pe_get_unit_ctx(
const char * path,
struct pe_unit_ctx ** pctx)
{
- struct pe_unit_ctx * ctx;
+ struct pe_unit_ctx_impl * ctx;
int prot;
if (!dctx || !(ctx = calloc(sizeof(*ctx),1)))
@@ -39,14 +42,26 @@ int pe_get_unit_ctx(
memcpy(&ctx->cctx,dctx->cctx,
sizeof(ctx->cctx));
- ctx->path = path;
+ ctx->path = ctx->path;
ctx->cctx.prot = prot;
- *pctx = ctx;
+ ctx->uctx.path = &ctx->path;
+ ctx->uctx.map = &ctx->map;
+ ctx->uctx.meta = ctx->meta;
+ ctx->uctx.cctx = &ctx->cctx;
+
+ *pctx = &ctx->uctx;
return 0;
}
void pe_free_unit_ctx(struct pe_unit_ctx * ctx)
{
- pe_free_unit_ctx_impl(ctx,0);
+ struct pe_unit_ctx_impl * ictx;
+ uintptr_t addr;
+
+ if (ctx) {
+ addr = (uintptr_t)ctx - offsetof(struct pe_unit_ctx_impl,uctx);
+ ictx = (struct pe_unit_ctx_impl *)addr;
+ pe_free_unit_ctx_impl(ictx,0);
+ }
}
diff --git a/src/internal/perk_impl.h b/src/internal/perk_impl.h
index dd8ff4d..77a64ae 100644
--- a/src/internal/perk_impl.h
+++ b/src/internal/perk_impl.h
@@ -13,4 +13,12 @@ struct pe_driver_ctx_impl {
struct pe_driver_ctx ctx;
};
+struct pe_unit_ctx_impl {
+ const char * path;
+ struct pe_raw_image map;
+ struct pe_image_meta * meta;
+ struct pe_common_ctx cctx;
+ struct pe_unit_ctx uctx;
+};
+
#endif
diff --git a/src/perk.c b/src/perk.c
index c057fc2..85a601f 100644
--- a/src/perk.c
+++ b/src/perk.c
@@ -27,8 +27,8 @@ static ssize_t perk_paragraph_break(struct pe_unit_ctx * uctx, int * fpara)
if (*fpara) {
*fpara = 0;
- if (uctx->cctx.fdout >= 0)
- return write(uctx->cctx.fdout,"\n",1);
+ if (uctx->cctx->fdout >= 0)
+ return write(uctx->cctx->fdout,"\n",1);
else
return fputc('\n',stdout);
} else
@@ -38,24 +38,26 @@ static ssize_t perk_paragraph_break(struct pe_unit_ctx * uctx, int * fpara)
static void perk_perform_unit_actions(struct pe_unit_ctx * uctx)
{
int fpara = 0;
- uint64_t flags = uctx->cctx.fmtflags;
+ uint64_t flags = uctx->cctx->fmtflags;
if (flags & PERK_OUTPUT_EXPORT_SYMS) {
- uctx->cctx.status = pe_output_export_symbols(uctx->meta,&uctx->cctx,0);
+ uctx->status = pe_output_export_symbols(uctx->meta,uctx->cctx,0);
+ uctx->nerrors += !!uctx->status;
fpara += uctx->meta->summary.num_of_export_syms;
}
if ((flags & PERK_OUTPUT_IMPORT_LIBS) || (flags & PERK_OUTPUT_IMPORT_SYMS)) {
perk_paragraph_break(uctx,&fpara);
- uctx->cctx.status = pe_output_import_libraries(uctx->meta,&uctx->cctx,0);
+ uctx->status = pe_output_import_libraries(uctx->meta,uctx->cctx,0);
+ uctx->nerrors += !!uctx->status;
fpara += (uctx->meta->summary.num_of_implibs > 0);
}
}
-static int perk_exit(struct pe_driver_ctx * dctx, int status)
+static int perk_exit(struct pe_driver_ctx * dctx, int nerrors)
{
pe_free_driver_ctx(dctx);
- return (status < 0) ? 2 : status;
+ return nerrors ? 2 : 0;
}
static int perk_main(int argc, const char ** argv, const char ** envp)
@@ -75,7 +77,7 @@ static int perk_main(int argc, const char ** argv, const char ** envp)
for (unit=dctx->units; *unit; unit++) {
if (!(pe_get_unit_ctx(dctx,*unit,&uctx))) {
perk_perform_unit_actions(uctx);
- ret = uctx->cctx.status ? uctx->cctx.status : ret;
+ ret += uctx->nerrors;
pe_free_unit_ctx(uctx);
}
}