diff options
Diffstat (limited to 'src/arbits/output')
-rw-r--r-- | src/arbits/output/slbt_au_output_arname.c | 86 | ||||
-rw-r--r-- | src/arbits/output/slbt_au_output_dlsyms.c | 12 | ||||
-rw-r--r-- | src/arbits/output/slbt_au_output_mapfile.c | 12 | ||||
-rw-r--r-- | src/arbits/output/slbt_au_output_members.c | 278 | ||||
-rw-r--r-- | src/arbits/output/slbt_au_output_symbols.c | 201 |
5 files changed, 589 insertions, 0 deletions
diff --git a/src/arbits/output/slbt_au_output_arname.c b/src/arbits/output/slbt_au_output_arname.c new file mode 100644 index 0000000..28e081d --- /dev/null +++ b/src/arbits/output/slbt_au_output_arname.c @@ -0,0 +1,86 @@ +/*******************************************************************/ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <slibtool/slibtool.h> +#include <slibtool/slibtool_output.h> +#include "slibtool_driver_impl.h" +#include "slibtool_dprintf_impl.h" +#include "slibtool_errinfo_impl.h" +#include "slibtool_ar_impl.h" + +#define SLBT_PRETTY_FLAGS (SLBT_PRETTY_YAML \ + | SLBT_PRETTY_POSIX \ + | SLBT_PRETTY_HEXDATA) + +static int slbt_au_output_arname_impl( + const struct slbt_driver_ctx * dctx, + const struct slbt_archive_ctx * actx, + const struct slbt_fd_ctx * fdctx, + const char * fmt) +{ + const char * path; + const char mema[] = "<memory_object>"; + + path = actx->path && *actx->path ? *actx->path : mema; + + if (slbt_dprintf(fdctx->fdout,fmt,path) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + + return 0; +} + +static int slbt_au_output_arname_posix( + const struct slbt_driver_ctx * dctx, + const struct slbt_archive_ctx * actx, + const struct slbt_fd_ctx * fdctx) +{ + if (slbt_au_output_arname_impl( + dctx,actx,fdctx, + "%s:\n") < 0) + return SLBT_NESTED_ERROR(dctx); + + return 0; +} + +static int slbt_au_output_arname_yaml( + const struct slbt_driver_ctx * dctx, + const struct slbt_archive_ctx * actx, + const struct slbt_fd_ctx * fdctx) +{ + if (slbt_au_output_arname_impl( + dctx,actx,fdctx, + "Archive:\n" + " - Meta:\n" + " - [ name: %s ]\n\n") < 0) + return SLBT_NESTED_ERROR(dctx); + + return 0; +} + +int slbt_au_output_arname(const struct slbt_archive_ctx * actx) +{ + const struct slbt_driver_ctx * dctx; + struct slbt_fd_ctx fdctx; + + dctx = (slbt_get_archive_ictx(actx))->dctx; + + if (slbt_lib_get_driver_fdctx(dctx,&fdctx) < 0) + return SLBT_NESTED_ERROR(dctx); + + switch (dctx->cctx->fmtflags & SLBT_PRETTY_FLAGS) { + case SLBT_PRETTY_YAML: + return slbt_au_output_arname_yaml( + dctx,actx,&fdctx); + + case SLBT_PRETTY_POSIX: + return slbt_au_output_arname_posix( + dctx,actx,&fdctx); + + default: + return slbt_au_output_arname_yaml( + dctx,actx,&fdctx); + } +} diff --git a/src/arbits/output/slbt_au_output_dlsyms.c b/src/arbits/output/slbt_au_output_dlsyms.c new file mode 100644 index 0000000..512f60f --- /dev/null +++ b/src/arbits/output/slbt_au_output_dlsyms.c @@ -0,0 +1,12 @@ +/*******************************************************************/ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <slibtool/slibtool.h> + +int slbt_au_output_dlsyms(struct slbt_archive_ctx ** arctxv, const char * dlunit) +{ + return slbt_ar_create_dlsyms(arctxv,dlunit,0,0); +} diff --git a/src/arbits/output/slbt_au_output_mapfile.c b/src/arbits/output/slbt_au_output_mapfile.c new file mode 100644 index 0000000..fb470df --- /dev/null +++ b/src/arbits/output/slbt_au_output_mapfile.c @@ -0,0 +1,12 @@ +/*******************************************************************/ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <slibtool/slibtool.h> + +int slbt_au_output_mapfile(const struct slbt_archive_meta * meta) +{ + return slbt_ar_create_mapfile(meta,0,0); +} diff --git a/src/arbits/output/slbt_au_output_members.c b/src/arbits/output/slbt_au_output_members.c new file mode 100644 index 0000000..88937b0 --- /dev/null +++ b/src/arbits/output/slbt_au_output_members.c @@ -0,0 +1,278 @@ +/*******************************************************************/ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <time.h> +#include <locale.h> +#include <inttypes.h> +#include <slibtool/slibtool.h> +#include <slibtool/slibtool_output.h> +#include "slibtool_driver_impl.h" +#include "slibtool_dprintf_impl.h" +#include "slibtool_errinfo_impl.h" +#include "slibtool_ar_impl.h" + +#define SLBT_PRETTY_FLAGS (SLBT_PRETTY_YAML \ + | SLBT_PRETTY_POSIX \ + | SLBT_PRETTY_HEXDATA) + +#define PPRIU64 "%"PRIu64 + +const char slbt_ar_perm_strs[8][4] = { + {'-','-','-','\0'}, + {'-','-','x','\0'}, + {'-','w','-','\0'}, + {'-','w','x','\0'}, + {'r','-','-','\0'}, + {'r','-','x','\0'}, + {'r','w','-','\0'}, + {'r','w','x','\0'} +}; + +static unsigned slbt_au_output_decimal_len_from_val(size_t val, unsigned min) +{ + unsigned ret; + + for (ret=0; val; ret++) + val /= 10; + + return (ret > min) ? ret : min; +} + +static int slbt_au_output_one_member_posix( + int fdout, + struct ar_meta_member_info * memberp) +{ + return slbt_dprintf( + fdout,"%s\n", + memberp->ar_file_header.ar_member_name); +} + +static int slbt_au_output_one_member_posix_verbose( + int fdout, + struct ar_meta_member_info * memberp, + const char * fmtstr, + locale_t arlocale) +{ + unsigned ownerbits; + unsigned groupbits; + unsigned worldbits; + time_t artimeval; + struct tm artimeloc; + char artimestr[64] = {0}; + + ownerbits = (memberp->ar_file_header.ar_file_mode & 0700) >> 6; + groupbits = (memberp->ar_file_header.ar_file_mode & 0070) >> 3; + worldbits = (memberp->ar_file_header.ar_file_mode & 0007); + artimeval = memberp->ar_file_header.ar_time_date_stamp; + + if (localtime_r(&artimeval,&artimeloc)) + strftime_l( + artimestr,sizeof(artimestr), + "%b %e %H:%M %Y",&artimeloc, + arlocale); + + return slbt_dprintf( + fdout,fmtstr, + slbt_ar_perm_strs[ownerbits], + slbt_ar_perm_strs[groupbits], + slbt_ar_perm_strs[worldbits], + memberp->ar_file_header.ar_uid, + memberp->ar_file_header.ar_gid, + memberp->ar_object_size, + artimestr, + memberp->ar_file_header.ar_member_name); +} + +static int slbt_au_output_members_posix( + const struct slbt_driver_ctx * dctx, + const struct slbt_archive_meta * meta, + const struct slbt_fd_ctx * fdctx) +{ + struct ar_meta_member_info ** memberp; + int fdout; + size_t testval; + size_t sizelen; + size_t uidlen; + size_t gidlen; + locale_t arloc; + char fmtstr[64]; + + fdout = fdctx->fdout; + arloc = 0; + + if (dctx->cctx->fmtflags & SLBT_PRETTY_VERBOSE) { + for (sizelen=0,memberp=meta->a_memberv; *memberp; memberp++) + if ((testval = memberp[0]->ar_object_size) > sizelen) + sizelen = testval; + + for (uidlen=0,memberp=meta->a_memberv; *memberp; memberp++) + if ((testval = memberp[0]->ar_file_header.ar_uid) > uidlen) + uidlen = testval; + + for (gidlen=0,memberp=meta->a_memberv; *memberp; memberp++) + if ((testval = memberp[0]->ar_file_header.ar_gid) > gidlen) + gidlen = testval; + + sizelen = slbt_au_output_decimal_len_from_val(sizelen,6); + uidlen = slbt_au_output_decimal_len_from_val(uidlen,1); + gidlen = slbt_au_output_decimal_len_from_val(gidlen,1); + arloc = newlocale(LC_ALL,setlocale(LC_ALL,0),0); + + sprintf( + fmtstr, + "%%s%%s%%s " + "%%" PPRIU64 "u" + "/%%-" PPRIU64 "u " + "%%" PPRIU64 "u " + "%%s " + "%%s\n", + uidlen, + gidlen, + sizelen); + } + + for (memberp=meta->a_memberv; *memberp; memberp++) { + switch ((*memberp)->ar_member_attr) { + case AR_MEMBER_ATTR_ARMAP: + case AR_MEMBER_ATTR_LINKINFO: + case AR_MEMBER_ATTR_NAMESTRS: + break; + + default: + if (arloc) { + if (slbt_au_output_one_member_posix_verbose( + fdout,*memberp,fmtstr,arloc) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + } else { + if (slbt_au_output_one_member_posix( + fdout,*memberp) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + } + } + } + + if (arloc) + freelocale(arloc); + + return 0; +} + +static int slbt_au_output_one_member_yaml( + int fdout, + struct ar_meta_member_info * memberp) +{ + return slbt_dprintf( + fdout, + " - [ member: %s ]\n", + memberp->ar_file_header.ar_member_name); +} + +static int slbt_au_output_one_member_yaml_verbose( + int fdout, + struct ar_meta_member_info * memberp, + locale_t arlocale) +{ + time_t artimeval; + struct tm artimeloc; + char artimestr[64] = {0}; + + artimeval = memberp->ar_file_header.ar_time_date_stamp; + + if (localtime_r(&artimeval,&artimeloc)) + strftime_l( + artimestr,sizeof(artimestr), + "%Y/%m/%d @ %H:%M",&artimeloc, + arlocale); + + return slbt_dprintf( + fdout, + " - Member:\n" + " - [ name: " "%s" " ]\n" + " - [ timestamp: " "%s" " ]\n" + " - [ filesize: " PPRIU64 " ]\n" + " - [ uid: " "%d" " ]\n" + " - [ gid: " "%d" " ]\n" + " - [ mode: " "%d" " ]\n\n", + memberp->ar_file_header.ar_member_name, + artimestr, + memberp->ar_object_size, + memberp->ar_file_header.ar_uid, + memberp->ar_file_header.ar_gid, + memberp->ar_file_header.ar_file_mode); +} + +static int slbt_au_output_members_yaml( + const struct slbt_driver_ctx * dctx, + const struct slbt_archive_meta * meta, + const struct slbt_fd_ctx * fdctx) +{ + struct ar_meta_member_info ** memberp; + int fdout; + locale_t arloc; + + fdout = fdctx->fdout; + arloc = 0; + + if (dctx->cctx->fmtflags & SLBT_PRETTY_VERBOSE) { + arloc = newlocale(LC_ALL,setlocale(LC_ALL,0),0); + } + + if (slbt_dprintf(fdctx->fdout," - Members:\n") < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + + for (memberp=meta->a_memberv; *memberp; memberp++) { + switch ((*memberp)->ar_member_attr) { + case AR_MEMBER_ATTR_ARMAP: + case AR_MEMBER_ATTR_LINKINFO: + case AR_MEMBER_ATTR_NAMESTRS: + break; + + default: + if (arloc) { + if (slbt_au_output_one_member_yaml_verbose( + fdout,*memberp,arloc) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + } else { + if (slbt_au_output_one_member_yaml( + fdout,*memberp) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + } + } + } + + if (arloc) + freelocale(arloc); + + return 0; +} + +int slbt_au_output_members(const struct slbt_archive_meta * meta) +{ + const struct slbt_driver_ctx * dctx; + struct slbt_fd_ctx fdctx; + + dctx = (slbt_archive_meta_ictx(meta))->dctx; + + if (slbt_lib_get_driver_fdctx(dctx,&fdctx) < 0) + return SLBT_NESTED_ERROR(dctx); + + if (!meta->a_memberv) + return 0; + + switch (dctx->cctx->fmtflags & SLBT_PRETTY_FLAGS) { + case SLBT_PRETTY_YAML: + return slbt_au_output_members_yaml( + dctx,meta,&fdctx); + + case SLBT_PRETTY_POSIX: + return slbt_au_output_members_posix( + dctx,meta,&fdctx); + + default: + return slbt_au_output_members_yaml( + dctx,meta,&fdctx); + } +} diff --git a/src/arbits/output/slbt_au_output_symbols.c b/src/arbits/output/slbt_au_output_symbols.c new file mode 100644 index 0000000..950cde8 --- /dev/null +++ b/src/arbits/output/slbt_au_output_symbols.c @@ -0,0 +1,201 @@ +/*******************************************************************/ +/* slibtool: a strong libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include <time.h> +#include <locale.h> +#include <regex.h> +#include <inttypes.h> +#include <slibtool/slibtool.h> +#include <slibtool/slibtool_output.h> +#include "slibtool_driver_impl.h" +#include "slibtool_dprintf_impl.h" +#include "slibtool_errinfo_impl.h" +#include "slibtool_pecoff_impl.h" +#include "slibtool_tmpfile_impl.h" +#include "slibtool_ar_impl.h" + +#define SLBT_PRETTY_FLAGS (SLBT_PRETTY_YAML \ + | SLBT_PRETTY_POSIX \ + | SLBT_PRETTY_HEXDATA) + +static int slbt_au_output_symbols_posix( + const struct slbt_driver_ctx * dctx, + struct slbt_archive_meta_impl * mctx, + int fdout) +{ + bool fsort; + bool fcoff; + const char * dot; + const char * mark; + const char * regex; + const char ** symv; + const char ** symstrv; + regex_t regctx; + regmatch_t pmatch[2] = {{0,0},{0,0}}; + char strbuf[4096]; + + fsort = !(dctx->cctx->fmtflags & SLBT_OUTPUT_ARCHIVE_NOSORT); + fcoff = (mctx->ofmtattr & AR_OBJECT_ATTR_COFF); + + 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_EXTENDED|REG_NEWLINE)) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_FLOW_ERROR); + + symstrv = fsort ? mctx->mapstrv : mctx->symstrv; + + for (symv=symstrv; *symv; symv++) { + if (!fcoff || slbt_is_strong_coff_symbol(*symv)) { + if (!regex || !regexec(®ctx,*symv,1,pmatch,0)) { + if (slbt_dprintf(fdout,"%s\n",*symv) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + } + + /* coff weak symbols: expsym = .weak.alias.strong */ + } else if (fcoff && !strncmp(*symv,".weak.",6)) { + mark = &(*symv)[6]; + dot = strchr(mark,'.'); + + strncpy(strbuf,mark,dot-mark); + strbuf[dot-mark] = '\0'; + + if (!regex || !regexec(®ctx,strbuf,1,pmatch,0)) + if (slbt_dprintf(fdout,"%s\n",strbuf) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + } + } + + if (regex) + regfree(®ctx); + + return 0; +} + +static int slbt_au_output_one_symbol_yaml( + int fdout, + struct slbt_archive_meta_impl * mctx, + const char * symname) +{ + struct ar_meta_symbol_info ** syminfv; + + for (syminfv=mctx->syminfv; *syminfv; syminfv++) + if (!strcmp(syminfv[0]->ar_symbol_name,symname)) + return slbt_dprintf( + fdout, + " - Symbol:\n" + " - [ object_name: " "%s" " ]\n" + " - [ symbol_name: " "%s" " ]\n" + " - [ symbol_type: " "%s" " ]\n\n", + syminfv[0]->ar_object_name, + symname, + syminfv[0]->ar_symbol_type); + + return 0; +} + +static int slbt_au_output_symbols_yaml( + const struct slbt_driver_ctx * dctx, + struct slbt_archive_meta_impl * mctx, + int fdout) +{ + int fdtmp; + bool fsort; + bool fcoff; + const char * dot; + const char * mark; + const char * regex; + const char ** symv; + const char ** symstrv; + regex_t regctx; + regmatch_t pmatch[2] = {{0,0},{0,0}}; + char strbuf[4096]; + + fsort = !(dctx->cctx->fmtflags & SLBT_OUTPUT_ARCHIVE_NOSORT); + fcoff = (mctx->ofmtattr & AR_OBJECT_ATTR_COFF); + + if ((fdtmp = slbt_tmpfile()) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + + if (fsort && !mctx->mapstrv) + if (slbt_update_mapstrv(dctx,mctx) < 0) + return SLBT_NESTED_ERROR(dctx); + + if (slbt_ar_update_syminfo_ex(mctx->actx,fdtmp) < 0) + return SLBT_NESTED_ERROR(dctx); + + if ((regex = dctx->cctx->regex)) + if (regcomp(®ctx,regex,REG_EXTENDED|REG_NEWLINE)) + return SLBT_CUSTOM_ERROR( + dctx, + SLBT_ERR_FLOW_ERROR); + + symstrv = fsort ? mctx->mapstrv : mctx->symstrv; + + if (slbt_dprintf(fdout," - Symbols:\n") < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + + for (symv=symstrv; *symv; symv++) { + if (!fcoff || slbt_is_strong_coff_symbol(*symv)) { + if (!regex || !regexec(®ctx,*symv,1,pmatch,0)) { + if (slbt_au_output_one_symbol_yaml( + fdout,mctx,*symv) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + } + + /* coff weak symbols: expsym = .weak.alias.strong */ + } else if (fcoff && !strncmp(*symv,".weak.",6)) { + mark = &(*symv)[6]; + dot = strchr(mark,'.'); + + strncpy(strbuf,mark,dot-mark); + strbuf[dot-mark] = '\0'; + + if (!regex || !regexec(®ctx,strbuf,1,pmatch,0)) + if (slbt_au_output_one_symbol_yaml( + fdout,mctx,strbuf) < 0) + return SLBT_SYSTEM_ERROR(dctx,0); + } + } + + if (regex) + regfree(®ctx); + + return 0; +} + +int slbt_au_output_symbols(const struct slbt_archive_meta * meta) +{ + struct slbt_archive_meta_impl * mctx; + const struct slbt_driver_ctx * dctx; + int fdout; + + mctx = slbt_archive_meta_ictx(meta); + dctx = (slbt_archive_meta_ictx(meta))->dctx; + + fdout = slbt_driver_fdout(dctx); + + if (!meta->a_memberv) + return 0; + + switch (dctx->cctx->fmtflags & SLBT_PRETTY_FLAGS) { + case SLBT_PRETTY_YAML: + return slbt_au_output_symbols_yaml( + dctx,mctx,fdout); + + case SLBT_PRETTY_POSIX: + return slbt_au_output_symbols_posix( + dctx,mctx,fdout); + + default: + return slbt_au_output_symbols_yaml( + dctx,mctx,fdout); + } +} |