From d42469095d909e70814099a22b40ae2f9831fe6b Mon Sep 17 00:00:00 2001 From: midipix Date: Mon, 19 Feb 2024 06:38:37 +0000 Subject: driver: added slbt_lib_get_symlist_ctx(): symbol string vector from symlist. --- include/slibtool/slibtool.h | 9 +++ project/common.mk | 1 + src/driver/slbt_symlist_ctx.c | 149 ++++++++++++++++++++++++++++++++++++ src/internal/slibtool_driver_impl.h | 9 +++ 4 files changed, 168 insertions(+) create mode 100644 src/driver/slbt_symlist_ctx.c diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h index c1e96c2..d80a00e 100644 --- a/include/slibtool/slibtool.h +++ b/include/slibtool/slibtool.h @@ -338,6 +338,11 @@ struct slbt_archive_ctx { void * any; }; +struct slbt_symlist_ctx { + const char * const * path; + const char ** symstrv; +}; + /* raw input api */ slbt_api int slbt_fs_map_input (const struct slbt_driver_ctx *, int, const char *, int, @@ -356,6 +361,10 @@ slbt_api int slbt_lib_get_driver_fdctx (const struct slbt_driver_ctx *, struct slbt_api int slbt_lib_set_driver_fdctx (struct slbt_driver_ctx *, const struct slbt_fd_ctx *); +slbt_api int slbt_lib_get_symlist_ctx (const struct slbt_driver_ctx *, const char *, struct slbt_symlist_ctx **); + +slbt_api void slbt_lib_free_symlist_ctx (struct slbt_symlist_ctx *); + /* command execution context api */ slbt_api int slbt_ectx_get_exec_ctx (const struct slbt_driver_ctx *, struct slbt_exec_ctx **); slbt_api void slbt_ectx_free_exec_ctx (struct slbt_exec_ctx *); diff --git a/project/common.mk b/project/common.mk index 13a3e2d..e82ddc1 100644 --- a/project/common.mk +++ b/project/common.mk @@ -16,6 +16,7 @@ API_SRCS = \ src/driver/slbt_driver_ctx.c \ src/driver/slbt_link_params.c \ src/driver/slbt_split_argv.c \ + src/driver/slbt_symlist_ctx.c \ src/driver/slbt_version_info.c \ src/host/slbt_host_params.c \ src/util/slbt_archive_import.c \ diff --git a/src/driver/slbt_symlist_ctx.c b/src/driver/slbt_symlist_ctx.c new file mode 100644 index 0000000..2a4997d --- /dev/null +++ b/src/driver/slbt_symlist_ctx.c @@ -0,0 +1,149 @@ +/*******************************************************************/ +/* slibtool: a skinny libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include "slibtool_driver_impl.h" +#include "slibtool_errinfo_impl.h" + +static int slbt_lib_free_symlist_ctx_impl( + struct slbt_symlist_ctx_impl * ctx, + struct slbt_input * mapinfo, + int ret) +{ + if (mapinfo) + slbt_fs_unmap_input(mapinfo); + + if (ctx) { + if (ctx->pathbuf) + free(ctx->pathbuf); + + if (ctx->symstrs) + free(ctx->symstrs); + + if (ctx->symstrv) + free(ctx->symstrv); + + free(ctx); + } + + return ret; +} + +int slbt_lib_get_symlist_ctx( + const struct slbt_driver_ctx * dctx, + const char * path, + struct slbt_symlist_ctx ** pctx) +{ + struct slbt_symlist_ctx_impl * ctx; + struct slbt_input mapinfo; + size_t nsyms; + char * ch; + char * cap; + char * src; + const char ** psym; + char dummy; + bool fvalid; + + /* map symlist file temporarily */ + if (slbt_fs_map_input(dctx,-1,path,PROT_READ,&mapinfo) < 0) + return SLBT_NESTED_ERROR(dctx); + + /* alloc context */ + if (!(ctx = calloc(1,sizeof(*ctx)))) + return slbt_lib_free_symlist_ctx_impl( + ctx,&mapinfo, + SLBT_BUFFER_ERROR(dctx)); + + /* count symbols */ + src = mapinfo.size ? mapinfo.addr : &dummy; + cap = &src[mapinfo.size]; + + for (; (srcpathbuf = strdup(path))) + return slbt_lib_free_symlist_ctx_impl( + ctx,&mapinfo, + SLBT_SYSTEM_ERROR(dctx,0)); + + if (!(ctx->symstrs = calloc(mapinfo.size+1,1))) + return slbt_lib_free_symlist_ctx_impl( + ctx,&mapinfo, + SLBT_SYSTEM_ERROR(dctx,0)); + + if (!(ctx->symstrv = calloc(nsyms+1,sizeof(char *)))) + return slbt_lib_free_symlist_ctx_impl( + ctx,&mapinfo, + SLBT_SYSTEM_ERROR(dctx,0)); + + /* copy the source to the allocated string buffer */ + memcpy(ctx->symstrs,mapinfo.addr,mapinfo.size); + slbt_fs_unmap_input(&mapinfo); + + /* populate the symbol vector, handle whitespace */ + src = ctx->symstrs; + cap = &src[mapinfo.size]; + + for (; (srcsymstrv; chdctx = dctx; + ctx->path = ctx->pathbuf; + ctx->sctx.path = &ctx->path; + ctx->sctx.symstrv = ctx->symstrv; + + *pctx = &ctx->sctx; + + return 0; +} + +void slbt_lib_free_symlist_ctx(struct slbt_symlist_ctx * ctx) +{ + struct slbt_symlist_ctx_impl * ictx; + uintptr_t addr; + + if (ctx) { + addr = (uintptr_t)ctx - offsetof(struct slbt_symlist_ctx_impl,sctx); + ictx = (struct slbt_symlist_ctx_impl *)addr; + slbt_lib_free_symlist_ctx_impl(ictx,0,0); + } +} diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h index e30514d..8420532 100644 --- a/src/internal/slibtool_driver_impl.h +++ b/src/internal/slibtool_driver_impl.h @@ -185,6 +185,15 @@ struct slbt_archive_ctx_impl { struct slbt_archive_ctx actx; }; +struct slbt_symlist_ctx_impl { + const struct slbt_driver_ctx * dctx; + const char * path; + char * pathbuf; + char * symstrs; + const char ** symstrv; + struct slbt_symlist_ctx sctx; +}; + const char * slbt_program_name(const char *); -- cgit v1.2.3