summaryrefslogtreecommitdiffhomepage
path: root/src/internal
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/perk_ar_impl.h116
-rw-r--r--src/internal/perk_dprintf_impl.c4
-rw-r--r--src/internal/perk_driver_impl.h30
-rw-r--r--src/internal/perk_errinfo_impl.c3
-rw-r--r--src/internal/perk_hexdump_impl.c (renamed from src/internal/perk_hdrdump_impl.c)9
-rw-r--r--src/internal/perk_hexdump_impl.h (renamed from src/internal/perk_hdrdump_impl.h)0
-rw-r--r--src/internal/perk_synopsis_impl.h46
-rw-r--r--src/internal/perk_visibility_impl.h26
8 files changed, 218 insertions, 16 deletions
diff --git a/src/internal/perk_ar_impl.h b/src/internal/perk_ar_impl.h
new file mode 100644
index 0000000..0da7559
--- /dev/null
+++ b/src/internal/perk_ar_impl.h
@@ -0,0 +1,116 @@
+/***************************************************************/
+/* perk: PE Resource Kit */
+/* Copyright (C) 2015--2025 SysDeer Technologies, LLC */
+/* Released under GPLv2 and GPLv3; see COPYING.PERK. */
+/***************************************************************/
+
+#ifndef SLIBTOOL_AR_IMPL_H
+#define SLIBTOOL_AR_IMPL_H
+
+#include "argv/argv.h"
+#include <perk/perk.h>
+#include <perk/perk_arbits.h>
+
+/* decimal values in archive header are right padded with ascii spaces */
+#define AR_DEC_PADDING (0x20)
+
+/* archive file members are right padded as needed with ascii newline */
+#define AR_OBJ_PADDING (0x0A)
+
+/* initial number of elements in the transient, on-stack vector */
+# define AR_STACK_VECTOR_ELEMENTS (0x200)
+
+/* bit mask to indicate that the first non-option argument is <posname> */
+#define AR_POSNAME_MASK (PERK_DRIVER_AR_POSITION_AFTER \
+ |PERK_DRIVER_AR_POSITION_BEFORE)
+
+#define AR_UPDATE_MASK (PERK_DRIVER_AR_UPDATE_MEMBERS \
+ |PERK_DRIVER_AR_REPLACE_MEMBERS)
+
+#define AR_ACTION_MASK (PERK_DRIVER_AR_LIST_MEMBERS \
+ |PERK_DRIVER_AR_MOVE_MEMBERS \
+ |PERK_DRIVER_AR_UPDATE_MEMBERS \
+ |PERK_DRIVER_AR_DELETE_MEMBERS \
+ |PERK_DRIVER_AR_APPEND_MEMBERS \
+ |PERK_DRIVER_AR_REPLACE_MEMBERS \
+ |PERK_DRIVER_AR_EXTRACT_MEMBERS \
+ |PERK_DRIVER_AR_PRINT_MEMBERS)
+
+extern const struct argv_option pe_ar_options[];
+
+struct ar_armaps_impl {
+ struct ar_meta_armap_ref_32 * armap_symrefs_32;
+ struct ar_meta_armap_ref_64 * armap_symrefs_64;
+ struct ar_raw_armap_bsd_32 armap_bsd_32;
+ struct ar_raw_armap_bsd_64 armap_bsd_64;
+ struct ar_raw_armap_sysv_32 armap_sysv_32;
+ struct ar_raw_armap_sysv_64 armap_sysv_64;
+ struct ar_meta_armap_common_32 armap_common_32;
+ struct ar_meta_armap_common_64 armap_common_64;
+ uint64_t armap_nsyms;
+};
+
+struct pe_archive_meta_impl {
+ const struct pe_driver_ctx * dctx;
+ struct pe_archive_ctx * actx;
+ size_t ofmtattr;
+ size_t nentries;
+ void * hdrinfov;
+ char * namestrs;
+ const char * symstrs;
+ const char ** symstrv;
+ const char ** mapstrv;
+ off_t * offsetv;
+ struct ar_meta_symbol_info * syminfo;
+ struct ar_meta_symbol_info ** syminfv;
+ struct ar_meta_member_info ** memberv;
+ struct ar_meta_member_info * members;
+ struct ar_armaps_impl armaps;
+ struct pe_txtfile_ctx * nminfo;
+ struct pe_archive_meta armeta;
+};
+
+struct ar_meta_member_info * pe_archive_member_from_offset(
+ struct pe_archive_meta_impl * meta,
+ off_t offset);
+
+int pe_ar_parse_primary_armap_bsd_32(
+ const struct pe_driver_ctx * dctx,
+ struct pe_archive_meta_impl * m);
+
+int pe_ar_parse_primary_armap_bsd_64(
+ const struct pe_driver_ctx * dctx,
+ struct pe_archive_meta_impl * m);
+
+int pe_ar_parse_primary_armap_sysv_32(
+ const struct pe_driver_ctx * dctx,
+ struct pe_archive_meta_impl * m);
+
+int pe_ar_parse_primary_armap_sysv_64(
+ const struct pe_driver_ctx * dctx,
+ struct pe_archive_meta_impl * m);
+
+int pe_update_mapstrv(
+ const struct pe_driver_ctx * dctx,
+ struct pe_archive_meta_impl * m);
+
+int pe_ar_update_syminfo(
+ struct pe_archive_ctx * actx);
+
+int pe_ar_update_syminfo_ex(
+ struct pe_archive_ctx * actx,
+ int fdout);
+
+static inline struct pe_archive_meta_impl * pe_archive_meta_ictx(const struct pe_archive_meta * meta)
+{
+ uintptr_t addr;
+
+ if (meta) {
+ addr = (uintptr_t)meta - offsetof(struct pe_archive_meta_impl,armeta);
+ return (struct pe_archive_meta_impl *)addr;
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/src/internal/perk_dprintf_impl.c b/src/internal/perk_dprintf_impl.c
index 30d3d11..8e834e4 100644
--- a/src/internal/perk_dprintf_impl.c
+++ b/src/internal/perk_dprintf_impl.c
@@ -4,7 +4,9 @@
#include <unistd.h>
#include <errno.h>
-int pe_dprintf(int fd, const char * fmt, ...)
+#include "perk_visibility_impl.h"
+
+perk_hidden int pe_dprintf(int fd, const char * fmt, ...)
{
int ret;
int cnt;
diff --git a/src/internal/perk_driver_impl.h b/src/internal/perk_driver_impl.h
index dafad86..22e7894 100644
--- a/src/internal/perk_driver_impl.h
+++ b/src/internal/perk_driver_impl.h
@@ -13,11 +13,15 @@
#define PERK_OPTV_ELEMENTS 64
extern const struct argv_option pe_default_options[];
+extern const struct argv_option pe_perk_options[];
+extern const struct argv_option pe_ar_options[];
enum app_tags {
TAG_HELP,
TAG_VERSION,
+ TAG_CMD,
TAG_PRETTY,
+ TAG_VERBOSE,
TAG_CATEGORY,
TAG_SECTIONS,
TAG_SYMBOLS,
@@ -28,6 +32,8 @@ enum app_tags {
TAG_DSOLIBS,
TAG_DSOSYMS,
TAG_HDRDUMP,
+ TAG_AR_LIST_MEMBERS,
+ TAG_AR_PRINT_MEMBERS,
};
struct pe_driver_ctx_impl {
@@ -43,10 +49,14 @@ struct pe_driver_ctx_impl {
};
struct pe_unit_ctx_impl {
- const char * path;
- struct pe_raw_image map;
- struct pe_image_meta * meta;
- struct pe_unit_ctx uctx;
+ const char * path;
+ struct pe_raw_image map;
+ struct pe_image_meta * meta;
+ struct pe_raw_archive armap;
+ struct pe_archive_meta * armeta;
+ struct pe_image_meta ** objmeta;
+ const struct pe_image_meta**usrobjmeta;
+ struct pe_unit_ctx uctx;
};
@@ -78,42 +88,42 @@ static inline void pe_driver_set_ectx(
static inline int pe_driver_fdin(const struct pe_driver_ctx * dctx)
{
struct pe_fd_ctx fdctx;
- pe_get_driver_fdctx(dctx,&fdctx);
+ pe_lib_get_driver_fdctx(dctx,&fdctx);
return fdctx.fdin;
}
static inline int pe_driver_fdout(const struct pe_driver_ctx * dctx)
{
struct pe_fd_ctx fdctx;
- pe_get_driver_fdctx(dctx,&fdctx);
+ pe_lib_get_driver_fdctx(dctx,&fdctx);
return fdctx.fdout;
}
static inline int pe_driver_fderr(const struct pe_driver_ctx * dctx)
{
struct pe_fd_ctx fdctx;
- pe_get_driver_fdctx(dctx,&fdctx);
+ pe_lib_get_driver_fdctx(dctx,&fdctx);
return fdctx.fderr;
}
static inline int pe_driver_fdlog(const struct pe_driver_ctx * dctx)
{
struct pe_fd_ctx fdctx;
- pe_get_driver_fdctx(dctx,&fdctx);
+ pe_lib_get_driver_fdctx(dctx,&fdctx);
return fdctx.fdlog;
}
static inline int pe_driver_fdcwd(const struct pe_driver_ctx * dctx)
{
struct pe_fd_ctx fdctx;
- pe_get_driver_fdctx(dctx,&fdctx);
+ pe_lib_get_driver_fdctx(dctx,&fdctx);
return fdctx.fdcwd;
}
static inline int pe_driver_fddst(const struct pe_driver_ctx * dctx)
{
struct pe_fd_ctx fdctx;
- pe_get_driver_fdctx(dctx,&fdctx);
+ pe_lib_get_driver_fdctx(dctx,&fdctx);
return fdctx.fddst;
}
diff --git a/src/internal/perk_errinfo_impl.c b/src/internal/perk_errinfo_impl.c
index 22b084e..d930c1a 100644
--- a/src/internal/perk_errinfo_impl.c
+++ b/src/internal/perk_errinfo_impl.c
@@ -7,8 +7,9 @@
#include <perk/perk.h>
#include "perk_driver_impl.h"
#include "perk_errinfo_impl.h"
+#include "perk_visibility_impl.h"
-int pe_record_error(
+perk_hidden int pe_record_error(
const struct pe_driver_ctx * dctx,
int esyscode,
int elibcode,
diff --git a/src/internal/perk_hdrdump_impl.c b/src/internal/perk_hexdump_impl.c
index 6bf1867..01effe0 100644
--- a/src/internal/perk_hdrdump_impl.c
+++ b/src/internal/perk_hexdump_impl.c
@@ -10,7 +10,8 @@
#include <perk/perk.h>
#include <perk/perk_consts.h>
#include <perk/perk_structs.h>
-#include "perk_hdrdump_impl.h"
+#include "perk_hexdump_impl.h"
+#include "perk_visibility_impl.h"
#define PE_TABWIDTH 8
#define PE_HDRSPACE 40
@@ -24,7 +25,7 @@ static const char pe_hex_header_dot[] =
static const char pe_hex_footer[] =
"|---------------------------------------------------| |-----------------|\n\n";
-size_t pe_output_hex_header(
+perk_hidden size_t pe_output_hex_header(
char * buf,
const char * sname,
uint64_t faddr,
@@ -94,7 +95,7 @@ size_t pe_output_hex_header(
return ch - buf;
}
-size_t pe_output_hex_footer(char * buf)
+perk_hidden size_t pe_output_hex_footer(char * buf)
{
size_t nlen;
@@ -107,7 +108,7 @@ size_t pe_output_hex_footer(char * buf)
return PE_HDRSPACE + nlen;
}
-size_t pe_output_raw_element(
+perk_hidden size_t pe_output_raw_element(
char * ch,
const void * rdata,
const char * mname,
diff --git a/src/internal/perk_hdrdump_impl.h b/src/internal/perk_hexdump_impl.h
index 379d427..379d427 100644
--- a/src/internal/perk_hdrdump_impl.h
+++ b/src/internal/perk_hexdump_impl.h
diff --git a/src/internal/perk_synopsis_impl.h b/src/internal/perk_synopsis_impl.h
new file mode 100644
index 0000000..f3d0a3a
--- /dev/null
+++ b/src/internal/perk_synopsis_impl.h
@@ -0,0 +1,46 @@
+/***************************************************************/
+/* perk: PE Resource Kit */
+/* Copyright (C) 2015--2025 SysDeer Technologies, LLC */
+/* Released under GPLv2 and GPLv3; see COPYING.PERK. */
+/***************************************************************/
+
+#ifndef SLIBTOOL_SYNOPSIS_IMPL_H
+#define SLIBTOOL_SYNOPSIS_IMPL_H
+
+#define PERK_DEFAULT_CMD_SYNOPSIS \
+ "%s — PE/COFF Resource Kit\n\n" \
+ "Synopsis:\n" \
+ " %s [option] ...\n" \
+ " %s --cmd=<command> [option] ...\n" \
+ " %s --cmd=<command> [option] ... <file> ...\n\n" \
+ "Options:\n"
+
+#define PERK_PERK_CMD_SYNOPSIS \
+ "%s — PE/COFF Resource Kit\n\n" \
+ "Synopsis:\n" \
+ " %s [option] ...\n" \
+ " %s [option] ... <file> ...\n\n" \
+ "Options:\n"
+
+#define PERK_AR_CMD_SYNOPSIS \
+ "%s — the PE/COFF Resource Kit Archiver\n\n" \
+ "Synopsis:\n" \
+ " %s -d [-v] <archive> <file> ...\n" \
+ " %s -p [-v] [-s] <archive> <file> ...\n" \
+ " %s -q [-v] [-c] <archive> <file> ...\n" \
+ " %s -r [-v] [-c] [-u] <archive> <file> ...\n" \
+ " %s -t [-v] [-s] <archive> [<file> ...]\n" \
+ " %s -x [-v] [-s] [-C] [-T] <archive> [<file> ...]\n\n" \
+ \
+ " %s -m [-v] <archive> <file> ...\n" \
+ " %s -m -a [-v] <posname> <archive> <file> ...\n" \
+ " %s -m -b [-v] <posname> <archive> <file> ...\n" \
+ " %s -m -i [-v] <posname> <archive> <file> ...\n\n" \
+ \
+ " %s -r [-v] [-c] [-u] <archive> <file> ...\n" \
+ " %s -r -a [-v] [-c] [-u] <posname> <archive> <file> ...\n" \
+ " %s -r -b [-v] [-c] [-u] <posname> <archive> <file> ...\n" \
+ " %s -r -i [-v] [-c] [-u] <posname> <archive> <file> ...\n\n" \
+ "Options:\n"
+
+#endif
diff --git a/src/internal/perk_visibility_impl.h b/src/internal/perk_visibility_impl.h
new file mode 100644
index 0000000..0057b8b
--- /dev/null
+++ b/src/internal/perk_visibility_impl.h
@@ -0,0 +1,26 @@
+#ifndef PERK_VISIBILITY_IMPL_H
+#define PERK_VISIBILITY_IMPL_H
+
+/**********************************************************************/
+/* PE targets: __dllexport suffices for the purpose of exporting only */
+/* the desired subset of global symbols; this makes the visibility */
+/* attribute not only redundant, but also tricky if not properly */
+/* supported by the toolchain. */
+/* */
+/* When targeting Midipix hosts, where elf-like visibility is fully */
+/* supported and may be detected via the __PE_VISIBILITY__ macro, */
+/* we utilize the attribute to render private symbols invisibile */
+/* to dlsym(), as well as reduce the size of the .gotstrs section. */
+/**********************************************************************/
+
+#if defined(__PE_VISIBILITY__)
+#define perk_hidden _ATTR_VISIBILITY_HIDDEN
+#elif defined(__PE__)
+#define perk_hidden
+#elif defined(_ATTR_VISIBILITY_HIDDEN)
+#define perk_hidden _ATTR_VISIBILITY_HIDDEN
+#else
+#define perk_hidden
+#endif
+
+#endif