|
|
7bab5a |
/*******************************************************************/
|
|
|
eac61a |
/* slibtool: a strong libtool implementation, written in C */
|
|
|
7bab5a |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
7bab5a |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
7bab5a |
/*******************************************************************/
|
|
|
7bab5a |
|
|
|
7bab5a |
#include <stdint.h>
|
|
|
7bab5a |
#include <stddef.h>
|
|
|
7bab5a |
#include <stdlib.h>
|
|
|
7bab5a |
#include <string.h>
|
|
|
7bab5a |
#include <sys/mman.h>
|
|
|
7bab5a |
|
|
|
7bab5a |
#include <slibtool/slibtool.h>
|
|
|
7bab5a |
#include "slibtool_driver_impl.h"
|
|
|
7bab5a |
#include "slibtool_errinfo_impl.h"
|
|
|
e486b0 |
#include "slibtool_ar_impl.h"
|
|
|
7bab5a |
|
|
|
7bab5a |
static int slbt_map_raw_archive(
|
|
|
7bab5a |
const struct slbt_driver_ctx * dctx,
|
|
|
7bab5a |
int fd,
|
|
|
7bab5a |
const char * path,
|
|
|
7bab5a |
int prot,
|
|
|
7bab5a |
struct slbt_raw_archive * map)
|
|
|
7bab5a |
{
|
|
|
7bab5a |
struct slbt_input mapinfo = {0,0};
|
|
|
7bab5a |
|
|
|
932ec0 |
if (slbt_fs_map_input(dctx,fd,path,prot,&mapinfo) < 0)
|
|
|
7bab5a |
return SLBT_NESTED_ERROR(dctx);
|
|
|
7bab5a |
|
|
|
7bab5a |
if (mapinfo.size == 0)
|
|
|
7bab5a |
return SLBT_CUSTOM_ERROR(
|
|
|
7bab5a |
dctx,
|
|
|
7bab5a |
SLBT_ERR_AR_EMPTY_FILE);
|
|
|
7bab5a |
|
|
|
7bab5a |
map->map_addr = mapinfo.addr;
|
|
|
7bab5a |
map->map_size = mapinfo.size;
|
|
|
7bab5a |
|
|
|
7bab5a |
return 0;
|
|
|
7bab5a |
}
|
|
|
7bab5a |
|
|
|
7bab5a |
static int slbt_unmap_raw_archive(struct slbt_raw_archive * map)
|
|
|
7bab5a |
{
|
|
|
7bab5a |
struct slbt_input mapinfo;
|
|
|
7bab5a |
|
|
|
7bab5a |
mapinfo.addr = map->map_addr;
|
|
|
7bab5a |
mapinfo.size = map->map_size;
|
|
|
7bab5a |
|
|
|
932ec0 |
return slbt_fs_unmap_input(&mapinfo);
|
|
|
7bab5a |
}
|
|
|
7bab5a |
|
|
|
51c276 |
static int slbt_ar_free_archive_ctx_impl(struct slbt_archive_ctx_impl * ctx, int ret)
|
|
|
7bab5a |
{
|
|
|
7bab5a |
if (ctx) {
|
|
|
51c276 |
slbt_ar_free_archive_meta(ctx->meta);
|
|
|
7bab5a |
slbt_unmap_raw_archive(&ctx->map);
|
|
|
9a3246 |
free(ctx->pathbuf);
|
|
|
7bab5a |
free(ctx);
|
|
|
7bab5a |
}
|
|
|
7bab5a |
|
|
|
7bab5a |
return ret;
|
|
|
7bab5a |
}
|
|
|
7bab5a |
|
|
|
51c276 |
int slbt_ar_get_archive_ctx(
|
|
|
7bab5a |
const struct slbt_driver_ctx * dctx,
|
|
|
7bab5a |
const char * path,
|
|
|
7bab5a |
struct slbt_archive_ctx ** pctx)
|
|
|
7bab5a |
{
|
|
|
7bab5a |
struct slbt_archive_ctx_impl * ctx;
|
|
|
e486b0 |
struct slbt_archive_meta_impl * mctx;
|
|
|
7bab5a |
int prot;
|
|
|
7bab5a |
|
|
|
7bab5a |
if (!(ctx = calloc(1,sizeof(*ctx))))
|
|
|
7bab5a |
return SLBT_BUFFER_ERROR(dctx);
|
|
|
7bab5a |
|
|
|
7bab5a |
slbt_driver_set_arctx(
|
|
|
7bab5a |
dctx,0,path);
|
|
|
7bab5a |
|
|
|
7bab5a |
prot = (dctx->cctx->actflags & SLBT_ACTION_MAP_READWRITE)
|
|
|
7bab5a |
? PROT_READ | PROT_WRITE
|
|
|
7bab5a |
: PROT_READ;
|
|
|
7bab5a |
|
|
|
7bab5a |
if (slbt_map_raw_archive(dctx,-1,path,prot,&ctx->map))
|
|
|
51c276 |
return slbt_ar_free_archive_ctx_impl(ctx,
|
|
|
7bab5a |
SLBT_NESTED_ERROR(dctx));
|
|
|
7bab5a |
|
|
|
51c276 |
if (slbt_ar_get_archive_meta(dctx,&ctx->map,&ctx->meta))
|
|
|
51c276 |
return slbt_ar_free_archive_ctx_impl(ctx,
|
|
|
7bab5a |
SLBT_NESTED_ERROR(dctx));
|
|
|
7bab5a |
|
|
|
9a3246 |
if (!(ctx->pathbuf = strdup(path)))
|
|
|
9a3246 |
return slbt_ar_free_archive_ctx_impl(ctx,
|
|
|
9a3246 |
SLBT_NESTED_ERROR(dctx));
|
|
|
9a3246 |
|
|
|
e486b0 |
mctx = slbt_archive_meta_ictx(ctx->meta);
|
|
|
e486b0 |
|
|
|
b1d1a0 |
ctx->dctx = dctx;
|
|
|
9a3246 |
ctx->path = ctx->pathbuf;
|
|
|
7bab5a |
ctx->actx.path = &ctx->path;
|
|
|
7bab5a |
ctx->actx.map = &ctx->map;
|
|
|
7bab5a |
ctx->actx.meta = ctx->meta;
|
|
|
e486b0 |
mctx->actx = &ctx->actx;
|
|
|
7bab5a |
|
|
|
7bab5a |
*pctx = &ctx->actx;
|
|
|
7bab5a |
return 0;
|
|
|
7bab5a |
}
|
|
|
7bab5a |
|
|
|
51c276 |
void slbt_ar_free_archive_ctx(struct slbt_archive_ctx * ctx)
|
|
|
7bab5a |
{
|
|
|
7bab5a |
struct slbt_archive_ctx_impl * ictx;
|
|
|
7bab5a |
uintptr_t addr;
|
|
|
7bab5a |
|
|
|
7bab5a |
if (ctx) {
|
|
|
7bab5a |
addr = (uintptr_t)ctx - offsetof(struct slbt_archive_ctx_impl,actx);
|
|
|
7bab5a |
ictx = (struct slbt_archive_ctx_impl *)addr;
|
|
|
51c276 |
slbt_ar_free_archive_ctx_impl(ictx,0);
|
|
|
7bab5a |
}
|
|
|
7bab5a |
}
|