diff --git a/project/common.mk b/project/common.mk index 31de801..1da17d9 100644 --- a/project/common.mk +++ b/project/common.mk @@ -1,5 +1,6 @@ API_SRCS = \ src/arbits/slbt_archive_ctx.c \ + src/arbits/slbt_archive_mapstrv.c \ src/arbits/slbt_archive_merge.c \ src/arbits/slbt_archive_meta.c \ src/arbits/slbt_archive_store.c \ diff --git a/src/arbits/output/slbt_ar_output_mapfile.c b/src/arbits/output/slbt_ar_output_mapfile.c index 09774bd..3455c37 100644 --- a/src/arbits/output/slbt_ar_output_mapfile.c +++ b/src/arbits/output/slbt_ar_output_mapfile.c @@ -20,21 +20,31 @@ static int slbt_ar_output_mapfile_impl( struct slbt_archive_meta_impl * mctx, int fdout) { + bool fsort; const char * regex; const char ** symv; + const char ** symstrv; regex_t regctx; regmatch_t pmatch[2] = {0}; + fsort = true; + if (slbt_dprintf(fdout,"{\n" "\t" "global:\n") < 0) return SLBT_SYSTEM_ERROR(dctx,0); + if (fsort && !mctx->mapstrv) + if (slbt_update_mapstrv(dctx,mctx) < 0) + return SLBT_NESTED_ERROR(dctx); + if ((regex = dctx->cctx->regex)) if (regcomp(®ctx,regex,REG_NEWLINE)) return SLBT_CUSTOM_ERROR( dctx, SLBT_ERR_FLOW_ERROR); - for (symv=mctx->symstrv; *symv; symv++) + symstrv = fsort ? mctx->mapstrv : mctx->symstrv; + + for (symv=symstrv; *symv; symv++) if (!regex || !regexec(®ctx,*symv,1,pmatch,0)) if (slbt_dprintf(fdout,"\t\t%s;\n",*symv) < 0) return SLBT_SYSTEM_ERROR(dctx,0); diff --git a/src/arbits/output/slbt_ar_output_symbols.c b/src/arbits/output/slbt_ar_output_symbols.c index cfd0be8..167de50 100644 --- a/src/arbits/output/slbt_ar_output_symbols.c +++ b/src/arbits/output/slbt_ar_output_symbols.c @@ -25,12 +25,19 @@ static int slbt_ar_output_symbols_posix( const struct slbt_fd_ctx * fdctx) { int fdout; + bool fsort; const char * regex; const char ** symv; + const char ** symstrv; regex_t regctx; regmatch_t pmatch[2] = {0}; fdout = fdctx->fdout; + fsort = true; + + if (fsort && !mctx->mapstrv) + if (slbt_update_mapstrv(dctx,mctx) < 0) + return SLBT_NESTED_ERROR(dctx); if ((regex = dctx->cctx->regex)) if (regcomp(®ctx,regex,REG_NEWLINE)) @@ -38,7 +45,9 @@ static int slbt_ar_output_symbols_posix( dctx, SLBT_ERR_FLOW_ERROR); - for (symv=mctx->symstrv; *symv; symv++) + symstrv = fsort ? mctx->mapstrv : mctx->symstrv; + + for (symv=symstrv; *symv; symv++) if (!regex || !regexec(®ctx,*symv,1,pmatch,0)) if (slbt_dprintf(fdout,"%s\n",*symv) < 0) return SLBT_SYSTEM_ERROR(dctx,0); diff --git a/src/arbits/slbt_archive_mapstrv.c b/src/arbits/slbt_archive_mapstrv.c new file mode 100644 index 0000000..eadf809 --- /dev/null +++ b/src/arbits/slbt_archive_mapstrv.c @@ -0,0 +1,41 @@ +/*******************************************************************/ +/* 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 "slibtool_driver_impl.h" +#include "slibtool_errinfo_impl.h" +#include "slibtool_ar_impl.h" + +static int slbt_strcmp(const void * a, const void * b) +{ + return strcmp(*(const char **)a,*(const char **)b); +} + +int slbt_update_mapstrv( + const struct slbt_driver_ctx * dctx, + struct slbt_archive_meta_impl * mctx) +{ + size_t nsyms; + const char ** symv; + const char ** mapstrv; + + for (nsyms=0,symv=mctx->symstrv; *symv; symv++) + nsyms++; + + if (!(mapstrv = calloc(nsyms+1,sizeof(const char *)))) + return SLBT_SYSTEM_ERROR(dctx,0); + + for (nsyms=0,symv=mctx->symstrv; *symv; symv++) + mapstrv[nsyms++] = *symv; + + qsort(mapstrv,nsyms,sizeof(const char *),slbt_strcmp); + + mctx->mapstrv = mapstrv; + + return 0; +} diff --git a/src/arbits/slbt_archive_meta.c b/src/arbits/slbt_archive_meta.c index 8c8f999..f4ae050 100644 --- a/src/arbits/slbt_archive_meta.c +++ b/src/arbits/slbt_archive_meta.c @@ -51,6 +51,9 @@ static int slbt_free_archive_meta_impl(struct slbt_archive_meta_impl * meta, int if (meta->symstrv) free(meta->symstrv); + if (meta->mapstrv) + free(meta->mapstrv); + free(meta); } diff --git a/src/internal/slibtool_ar_impl.h b/src/internal/slibtool_ar_impl.h index c171d26..b034c2b 100644 --- a/src/internal/slibtool_ar_impl.h +++ b/src/internal/slibtool_ar_impl.h @@ -41,6 +41,7 @@ struct slbt_archive_meta_impl { char * namestrs; const char * symstrs; const char ** symstrv; + const char ** mapstrv; off_t * offsetv; struct ar_meta_member_info ** memberv; struct ar_meta_member_info * members; @@ -68,6 +69,10 @@ int slbt_ar_parse_primary_armap_sysv_64( const struct slbt_driver_ctx * dctx, struct slbt_archive_meta_impl * m); +int slbt_update_mapstrv( + const struct slbt_driver_ctx * dctx, + struct slbt_archive_meta_impl * m); + static inline struct slbt_archive_meta_impl * slbt_archive_meta_ictx(const struct slbt_archive_meta * meta) { uintptr_t addr;