summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2019-08-16 11:49:46 -0400
committermidipix <writeonce@midipix.org>2019-08-17 07:30:11 -0400
commit4cda3b0874802972d4f07e7a58fb036a8f683051 (patch)
tree98867b411638fefeb69fdfbb5045ad04af377031
parentd1bc82399303a60d00525ea6ebb71d7944ae9df9 (diff)
downloadchainport-4cda3b0874802972d4f07e7a58fb036a8f683051.tar.bz2
chainport-4cda3b0874802972d4f07e7a58fb036a8f683051.tar.xz
binutils-2.24.51: mdso targets: added and integrated pe_mdso_input_name().
Following this commit, image arguments (e.g. libfoo.so) are replaced with temporary mdso import libraries that are generated on the fly using the perk and mdso library interfaces. As should be noted, the above logic is only in effect when PE_TARGET_MDSO is defined. For non-mdso targets (e.g. mingw), ld continues to generate in-memory legacy .idata import libraries as it did before.
-rw-r--r--binutils-2.24.51.midipix.patch268
1 files changed, 265 insertions, 3 deletions
diff --git a/binutils-2.24.51.midipix.patch b/binutils-2.24.51.midipix.patch
index 04117f6..bde9234 100644
--- a/binutils-2.24.51.midipix.patch
+++ b/binutils-2.24.51.midipix.patch
@@ -1,13 +1,252 @@
diff -ru --new-file a/ld/pe-mdso.c b/ld/pe-mdso.c
--- a/ld/pe-mdso.c 2019-08-14 06:12:57.193333307 -0400
-+++ a/ld/pe-mdso.c 2019-08-16 07:18:41.776390674 -0400
-@@ -0,0 +1,2 @@
++++ a/ld/pe-mdso.c 2019-08-17 00:59:46.886167655 -0400
+@@ -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;
++}
diff -ru --new-file a/bfd/pe-mdso.h b/bfd/pe-mdso.h
--- a/bfd/pe-mdso.h 1969-12-31 19:00:00.000000000 -0500
+++ b/bfd/pe-mdso.h 2019-08-15 07:00:00.000000000 -0400
-@@ -0,0 +1,8 @@
+@@ -0,0 +1,10 @@
+#ifndef PEMDSO_H
+#define PEMDSO_H
+
@@ -15,7 +254,30 @@ diff -ru --new-file a/bfd/pe-mdso.h b/bfd/pe-mdso.h
+#define PE_DSOLIB_SUFFIX ".dso.a"
+#define PE_IMPLIB_SUFFIX ".lib.a"
+
++const char * pe_mdso_input_name(const char * input_name);
++
+#endif
+diff -ru --new-file a/ld/ldlang.c b/ld/ldlang.c
+--- a/ld/ldlang.c 2014-07-03 01:37:48.000000000 -0400
++++ b/ld/ldlang.c 2019-08-16 12:31:17.048504021 -0400
+@@ -1117,6 +1117,16 @@
+ lang_input_file_enum_type file_type,
+ const char *target)
+ {
++#ifdef PE_TARGET_MDSO
++ if (file_type == lang_input_file_is_marker_enum) {
++ (void)0;
++ } else if (file_type == lang_input_file_is_l_enum) {
++ (void)0;
++ } else if (!(name = pe_mdso_input_name(name))) {
++ fprintf(stderr,"%s: pe_mdso_input_name() returned an error.\n",program_name);
++ xexit(EXIT_FAILURE);
++ }
++#endif
+ return new_afile (name, file_type, target, TRUE);
+ }
+
+diff -ru --new-file a/ld/configure b/ld/configure
--- a/ld/configure 2014-07-03 01:37:48.000000000 -0400
+++ b/ld/configure 2015-03-11 20:01:08.888756786 -0400
@@ -19773,3 +19773,31 @@