summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/slibtool/slibtool.h3
-rw-r--r--src/arbits/slbt_archive_merge.c37
2 files changed, 40 insertions, 0 deletions
diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index e0e92d3..d89e184 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -450,6 +450,9 @@ slbt_api int slbt_ar_get_archive_ctx (const struct slbt_driver_ctx *, const c
slbt_api void slbt_ar_free_archive_ctx (struct slbt_archive_ctx *);
+slbt_api int slbt_ar_get_varchive_ctx (const struct slbt_driver_ctx *,
+ struct slbt_archive_ctx **);
+
slbt_api int slbt_ar_get_archive_meta (const struct slbt_driver_ctx *,
const struct slbt_raw_archive *,
struct slbt_archive_meta **);
diff --git a/src/arbits/slbt_archive_merge.c b/src/arbits/slbt_archive_merge.c
index 82eaed5..dfa8f52 100644
--- a/src/arbits/slbt_archive_merge.c
+++ b/src/arbits/slbt_archive_merge.c
@@ -31,6 +31,9 @@
/* file size format specifier */
#define PPRIU64 "%"PRIu64
+/* dlopen self/force */
+static const char slbt_ar_self_dlunit[] = "@PROGRAM@";
+
struct armap_buffer_32 {
uint32_t moffset;
const char * symname;
@@ -695,3 +698,37 @@ int slbt_ar_merge_archives(
return 0;
}
+
+
+int slbt_ar_get_varchive_ctx(
+ const struct slbt_driver_ctx * dctx,
+ struct slbt_archive_ctx ** pctx)
+{
+ struct slbt_archive_ctx * ctx;
+ struct slbt_archive_ctx_impl * ictx;
+ void * base;
+ size_t size;
+
+ size = sizeof(struct ar_raw_signature);
+
+ if (slbt_create_anonymous_archive_ctx(dctx,size,&ctx) < 0)
+ return SLBT_NESTED_ERROR(dctx);
+
+ ictx = slbt_get_archive_ictx(ctx);
+
+ base = ctx->map->map_addr;
+ memcpy(base,ar_signature,size);
+
+ if (slbt_ar_get_archive_meta(dctx,ctx->map,&ictx->meta) < 0) {
+ slbt_ar_free_archive_ctx(ctx);
+ return SLBT_NESTED_ERROR(dctx);
+ }
+
+ ictx->path = slbt_ar_self_dlunit;
+ ictx->actx.meta = ictx->meta;
+ ictx->actx.path = &ictx->path;
+
+ *pctx = ctx;
+
+ return 0;
+}