summaryrefslogtreecommitdiff
path: root/overlay/mbinutils
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2019-08-30 17:03:25 +0000
committermidipix <writeonce@midipix.org>2019-08-30 17:03:25 +0000
commita98c846ea845b6de9b3b15bb6927daad47e0d384 (patch)
tree70305cda02c067d8eb4712dc2e98afa69b74f257 /overlay/mbinutils
parent9b88f8a526eba71fe67c6d35845f51fd9523fd02 (diff)
downloadchainport-a98c846ea845b6de9b3b15bb6927daad47e0d384.tar.bz2
chainport-a98c846ea845b6de9b3b15bb6927daad47e0d384.tar.xz
project: applied new directory layout (./overlay).
Diffstat (limited to 'overlay/mbinutils')
-rw-r--r--overlay/mbinutils/bfd/pe-mdso.h10
-rw-r--r--overlay/mbinutils/ld/pe-mdso.c241
2 files changed, 251 insertions, 0 deletions
diff --git a/overlay/mbinutils/bfd/pe-mdso.h b/overlay/mbinutils/bfd/pe-mdso.h
new file mode 100644
index 0000000..bf0a853
--- /dev/null
+++ b/overlay/mbinutils/bfd/pe-mdso.h
@@ -0,0 +1,10 @@
+#ifndef PEMDSO_H
+#define PEMDSO_H
+
+#define PE_DSO_SUFFIX ".so"
+#define PE_DSOLIB_SUFFIX ".dso.a"
+#define PE_IMPLIB_SUFFIX ".lib.a"
+
+const char * pe_mdso_input_name(const char * input_name);
+
+#endif
diff --git a/overlay/mbinutils/ld/pe-mdso.c b/overlay/mbinutils/ld/pe-mdso.c
new file mode 100644
index 0000000..b351599
--- /dev/null
+++ b/overlay/mbinutils/ld/pe-mdso.c
@@ -0,0 +1,241 @@
+#include "sysdep.h"
+#include "pe-mdso.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <perk/perk.h>
+#include <mdso/mdso.h>
+
+extern char * program_name;
+extern int xatexit(void (*)(void));
+
+static char pe_mdso_tmp_lib_name[] = "/tmp/mdso_XXXXXXXXXXXX";
+static char pe_perk_tmp_def_name[] = "/tmp/perk_XXXXXXXXXXXX";
+static struct pe_driver_ctx * pe_dctx;
+
+struct pe_mdso_lib {
+ dev_t st_dev;
+ ino_t st_ino;
+ char ar_name[24];
+};
+
+struct pe_mdso_lib * pe_mdso_lib_arr;
+struct pe_mdso_lib * pe_mdso_lib_ptr;
+struct pe_mdso_lib * pe_mdso_lib_cap;
+
+static int pe_mdso_perk_init(void)
+{
+ char * argv[2];
+
+ if (pe_dctx)
+ return 0;
+
+ argv[0] = program_name;
+ argv[1] = 0;
+
+ return pe_get_driver_ctx(argv,0,0,0,&pe_dctx);
+}
+
+static void pe_mdso_cache_unlink(void)
+{
+ struct pe_mdso_lib * pe_mdso;
+
+ for (pe_mdso=pe_mdso_lib_arr; pe_mdso<pe_mdso_lib_ptr; pe_mdso++)
+ unlink(pe_mdso->ar_name);
+}
+
+static int pe_mdso_cache_alloc(void)
+{
+ void * prev;
+ size_t size;
+ size_t nlib;
+
+ if (pe_mdso_lib_cap > pe_mdso_lib_ptr)
+ return 0;
+
+ prev = pe_mdso_lib_arr;
+ nlib = pe_mdso_lib_cap - pe_mdso_lib_arr;
+ size = nlib * sizeof(struct pe_mdso_lib);
+
+ if (!(pe_mdso_lib_arr = calloc(nlib+2,sizeof(struct pe_mdso_lib))))
+ return -1;
+
+ if (!prev)
+ xatexit(pe_mdso_cache_unlink);
+
+ memcpy(pe_mdso_lib_arr,prev,size);
+
+ pe_mdso_lib_ptr = &pe_mdso_lib_arr[nlib];
+ pe_mdso_lib_cap = &pe_mdso_lib_arr[nlib+2];
+
+ return 0;
+}
+
+const char * pe_mdso_input_name(const char * input_name)
+{
+ int fdin;
+ int fdout;
+ char * libname;
+ char * argv[8];
+
+ struct stat st;
+ struct pe_mdso_lib * pe_mdso;
+ struct pe_unit_ctx * pe_uctx;
+ struct pe_fd_ctx pe_fdctx;
+ struct mdso_driver_ctx * mdso_dctx;
+
+ /* perk driver context */
+ if (pe_mdso_perk_init() < 0)
+ return 0;
+
+ /* defer when input_name cannot be opened */
+ if ((fdin = open(input_name,O_RDONLY)) < 0)
+ return input_name;
+
+ /* stat */
+ if (fstat(fdin,&st) < 0) {
+ close(fdin);
+ pe_free_unit_ctx(pe_uctx);
+ pe_output_error_vector(pe_dctx);
+ return 0;
+ }
+
+ /* repeated input argument? */
+ for (pe_mdso=pe_mdso_lib_arr; pe_mdso<pe_mdso_lib_ptr; pe_mdso++) {
+ if ((pe_mdso->st_dev == st.st_dev) && (pe_mdso->st_ino == st.st_ino)) {
+ close(fdin);
+ return pe_mdso->ar_name;
+ }
+ }
+
+ /* defer when perk object/image context cannot be created */
+ if (pe_get_unit_ctx(pe_dctx,input_name,&pe_uctx) < 0) {
+ close(fdin);
+ return input_name;
+ }
+
+ /* defer when input file is not an image */
+ switch (pe_uctx->meta->m_subtype) {
+ case PE_SUBTYPE_DLL:
+ case PE_SUBTYPE_EXE:
+ break;
+
+ default:
+ close(fdin);
+ pe_free_unit_ctx(pe_uctx);
+ return input_name;
+ }
+
+ /* image bits */
+ switch (pe_uctx->meta->m_abi) {
+ case PE_ABI_PE32:
+ argv[1] = "-m32";
+ break;
+
+ case PE_ABI_PE64:
+ argv[1] = "-m64";
+ break;
+
+ default:
+ close(fdin);
+ pe_free_unit_ctx(pe_uctx);
+ return 0;
+ }
+
+ /* perk driver fd context (get) */
+ if ((pe_get_driver_fdctx(pe_dctx,&pe_fdctx)) < 0) {
+ close(fdin);
+ pe_free_unit_ctx(pe_uctx);
+ pe_output_error_vector(pe_dctx);
+ return 0;
+ }
+
+ /* template init */
+ memset (&pe_perk_tmp_def_name[10],'X',12);
+ memset (&pe_mdso_tmp_lib_name[10],'X',12);
+
+ /* perk .def file (create) */
+ if ((pe_fdctx.fdout = mkstemp(pe_perk_tmp_def_name)) < 0) {
+ close(fdin);
+ pe_free_unit_ctx(pe_uctx);
+ pe_output_error_vector(pe_dctx);
+ return 0;
+ }
+
+ /* perk driver fd context (set) */
+ if ((pe_set_driver_fdctx(pe_dctx,&pe_fdctx)) < 0) {
+ close(fdin);
+ pe_free_unit_ctx(pe_uctx);
+ pe_output_error_vector(pe_dctx);
+ return 0;
+ }
+
+ /* perk .def file (populate) */
+ if (pe_output_export_symbols(pe_dctx,pe_uctx->meta) < 0) {
+ close(fdin);
+ pe_free_unit_ctx(pe_uctx);
+ pe_output_error_vector(pe_dctx);
+ return 0;
+ };
+
+ /* done with perk */
+ close(fdin);
+ pe_free_unit_ctx(pe_uctx);
+
+ /* libname */
+ if ((libname = strrchr(input_name,'/')))
+ libname++;
+ else if ((libname = strrchr(input_name,'\\')))
+ libname++;
+ else
+ libname = (char *)input_name;
+
+ /* cache alloc (as needed) */
+ if (pe_mdso_cache_alloc() < 0)
+ return 0;
+
+ /* mdso lib file (create) */
+ if ((fdout = mkstemp(pe_mdso_tmp_lib_name)) < 0)
+ return 0;
+
+ /* mdso driver context (argv[1] already set, see above) */
+ argv[0] = program_name;
+ argv[2] = "--libname";
+ argv[3] = libname;
+ argv[4] = "--implib";
+ argv[5] = pe_mdso_tmp_lib_name;
+ argv[6] = pe_perk_tmp_def_name;
+ argv[7] = 0;
+
+ if (mdso_get_driver_ctx(argv,0,0,0,&mdso_dctx) < 0) {
+ close(fdout);
+ return 0;
+ }
+
+ /* mdso lib file (generate) */
+ if (mdso_create_implib_archive(mdso_dctx) < 0) {
+ close(fdout);
+ mdso_output_error_vector(mdso_dctx);
+ mdso_free_driver_ctx(mdso_dctx);
+ return 0;
+ }
+
+ /* cache */
+ strcpy(pe_mdso_lib_ptr->ar_name,pe_mdso_tmp_lib_name);
+
+ pe_mdso_lib_ptr->st_dev = st.st_dev;
+ pe_mdso_lib_ptr->st_ino = st.st_ino;
+ pe_mdso_lib_ptr++;
+
+ /* all done */
+ unlink(pe_perk_tmp_def_name);
+ mdso_free_driver_ctx(mdso_dctx);
+ close(fdout);
+
+ return pe_mdso_tmp_lib_name;
+}