diff mbox series

[scarthgap] binutils: File name too long causing failure to open temporary head file in dlltool

Message ID 20250205080635.2915215-1-jiaying.song.cn@windriver.com
State New
Headers show
Series [scarthgap] binutils: File name too long causing failure to open temporary head file in dlltool | expand

Commit Message

Song, Jiaying (CN) Feb. 5, 2025, 8:06 a.m. UTC
From: Jiaying Song <jiaying.song.cn@windriver.com>

During the execution of the command: i686-w64-mingw32-dlltool
--input-def $def_filepath --output-delaylib $filepath --dllname qemu.exe
An error occurred:
i686-w64-mingw32-dlltool: failed to open temporary head file: ..._w64_mingw32_nativesdk_qemu_8_2_2_build_plugins_libqemu_plugin_api_a_h.s

Due to the path length exceeding the Linux system's file name length
limit (NAME_MAX=255), the temporary file name generated by the
i686-w64-mingw32-dlltool command becomes too long to open. To address
this, a new temporary file name prefix is generated using tmp_prefix =
prefix_encode ("d", getpid()), ensuring that the file name does not
exceed the system's length limit.

Allow for "snnnnn.o" suffix when testing against NAME_MAX, and tidy
TMP_STUB handling by overwriting a prior nnnnn.o string rather than
copying the entire name.

Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
---
 .../binutils/binutils-2.42.inc                |   1 +
 .../0017-dlltool-file-name-too-long.patch     | 208 ++++++++++++++++++
 2 files changed, 209 insertions(+)
 create mode 100644 meta/recipes-devtools/binutils/binutils/0017-dlltool-file-name-too-long.patch
diff mbox series

Patch

diff --git a/meta/recipes-devtools/binutils/binutils-2.42.inc b/meta/recipes-devtools/binutils/binutils-2.42.inc
index 41ed39632d..89c552cf03 100644
--- a/meta/recipes-devtools/binutils/binutils-2.42.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.42.inc
@@ -37,5 +37,6 @@  SRC_URI = "\
      file://0014-Remove-duplicate-pe-dll.o-entry-deom-targ_extra_ofil.patch \
      file://0015-gprofng-change-use-of-bignum-to-bigint.patch \
      file://0016-CVE-2024-53589.patch \
+     file://0017-dlltool-file-name-too-long.patch \
 "
 S  = "${WORKDIR}/git"
diff --git a/meta/recipes-devtools/binutils/binutils/0017-dlltool-file-name-too-long.patch b/meta/recipes-devtools/binutils/binutils/0017-dlltool-file-name-too-long.patch
new file mode 100644
index 0000000000..2b759c1ee8
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/0017-dlltool-file-name-too-long.patch
@@ -0,0 +1,208 @@ 
+From d95d8395b3a533461f46e8b7e55fef540fc2621b Mon Sep 17 00:00:00 2001
+From: Jiaying Song <jiaying.song.cn@windriver.com>
+Date: Tue, 13 Aug 2024 10:31:21 +0800
+Subject: [PATCH] dlltool: file name too long
+
+During the execution of the command: i686-w64-mingw32-dlltool
+--input-def $def_filepath --output-delaylib $filepath --dllname qemu.exe
+An error occurred:
+i686-w64-mingw32-dlltool: failed to open temporary head file: ..._w64_mingw32_nativesdk_qemu_8_2_2_build_plugins_libqemu_plugin_api_a_h.s
+
+Due to the path length exceeding the Linux system's file name length
+limit (NAME_MAX=255), the temporary file name generated by the
+i686-w64-mingw32-dlltool command becomes too long to open. To address
+this, a new temporary file name prefix is generated using tmp_prefix =
+prefix_encode ("d", getpid()), ensuring that the file name does not
+exceed the system's length limit.
+
+Upstream-Status: Backport
+[https://github.com/bminor/binutils-gdb/commit/a253bea8995323201b016fe477280c1782688ab4]
+
+Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
+Reviewed-by: Alan Modra <amodra@gmail.com>
+
+Allow for "snnnnn.o" suffix when testing against NAME_MAX, and tidy
+TMP_STUB handling by overwriting a prior nnnnn.o string rather than
+copying the entire name.
+
+* dlltool.c (TMP_STUB): Add "nnnnn.o" to format.
+(make_one_lib_file): Localise variables.  Don't copy TMP_STUB,
+overwrite suffix instead.
+(gen_lib_file): Similarly.
+(main): Allow for max suffix when testing against NAME_MAX.
+
+Upstream-Status: Backport
+[https://github.com/bminor/binutils-gdb/commit/d0285cdf58adf04e861cd1687f7ecec65937c99d]
+
+Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
+---
+ binutils/dlltool.c | 64 +++++++++++++++++-----------------------------
+ 1 file changed, 24 insertions(+), 40 deletions(-)
+
+diff --git a/binutils/dlltool.c b/binutils/dlltool.c
+index 066c99a4..94f6c34b 100644
+--- a/binutils/dlltool.c
++++ b/binutils/dlltool.c
+@@ -498,7 +498,7 @@ char *tmp_stub_buf;
+ #define TMP_HEAD_O	dlltmp (&tmp_head_o_buf, "%sh.o")
+ #define TMP_TAIL_S	dlltmp (&tmp_tail_s_buf, "%st.s")
+ #define TMP_TAIL_O	dlltmp (&tmp_tail_o_buf, "%st.o")
+-#define TMP_STUB	dlltmp (&tmp_stub_buf, "%ss")
++#define TMP_STUB	dlltmp (&tmp_stub_buf, "%ssnnnnn.o")
+ 
+ /* This bit of assembly does jmp * ....  */
+ static const unsigned char i386_jtab[] =
+@@ -2401,26 +2401,11 @@ make_imp_label (const char *prefix, const char *name)
+ static bfd *
+ make_one_lib_file (export_type *exp, int i, int delay)
+ {
+-  bfd *      abfd;
+-  asymbol *  exp_label;
+-  asymbol *  iname = 0;
+-  asymbol *  iname2;
+-  asymbol *  iname_lab;
+-  asymbol ** iname_lab_pp;
+-  asymbol ** iname_pp;
+-#ifndef EXTRA
+-#define EXTRA    0
+-#endif
+-  asymbol *  ptrs[NSECS + 4 + EXTRA + 1];
+-  flagword   applicable;
+-  char *     outname = xmalloc (strlen (TMP_STUB) + 10);
+-  int        oidx = 0;
+-
+-
+-  sprintf (outname, "%s%05d.o", TMP_STUB, i);
+-
+-  abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET);
++  char *outname = TMP_STUB;
++  size_t name_len = strlen (outname);
++  sprintf (outname + name_len - 7, "%05d.o", i);
+ 
++  bfd *abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET);
+   if (!abfd)
+     /* xgettext:c-format */
+     fatal (_("bfd_open failed open stub file: %s: %s"),
+@@ -2437,9 +2422,13 @@ make_one_lib_file (export_type *exp, int i, int delay)
+     bfd_set_private_flags (abfd, F_INTERWORK);
+ #endif
+ 
+-  applicable = bfd_applicable_section_flags (abfd);
+-
+   /* First make symbols for the sections.  */
++  flagword applicable = bfd_applicable_section_flags (abfd);
++#ifndef EXTRA
++#define EXTRA    0
++#endif
++  asymbol *ptrs[NSECS + 4 + EXTRA + 1];
++  int oidx = 0;
+   for (i = 0; i < NSECS; i++)
+     {
+       sinfo *si = secdata + i;
+@@ -2466,7 +2455,7 @@ make_one_lib_file (export_type *exp, int i, int delay)
+ 
+   if (! exp->data)
+     {
+-      exp_label = bfd_make_empty_symbol (abfd);
++      asymbol *exp_label = bfd_make_empty_symbol (abfd);
+       exp_label->name = make_imp_label ("", exp->name);
+       exp_label->section = secdata[TEXT].sec;
+       exp_label->flags = BSF_GLOBAL;
+@@ -2482,6 +2471,7 @@ make_one_lib_file (export_type *exp, int i, int delay)
+   /* Generate imp symbols with one underscore for Microsoft
+      compatibility, and with two underscores for backward
+      compatibility with old versions of cygwin.  */
++  asymbol *iname = NULL;
+   if (create_compat_implib)
+     {
+       iname = bfd_make_empty_symbol (abfd);
+@@ -2491,25 +2481,24 @@ make_one_lib_file (export_type *exp, int i, int delay)
+       iname->value = 0;
+     }
+ 
+-  iname2 = bfd_make_empty_symbol (abfd);
++  asymbol *iname2 = bfd_make_empty_symbol (abfd);
+   iname2->name = make_imp_label ("__imp_", exp->name);
+   iname2->section = secdata[IDATA5].sec;
+   iname2->flags = BSF_GLOBAL;
+   iname2->value = 0;
+ 
+-  iname_lab = bfd_make_empty_symbol (abfd);
+-
++  asymbol *iname_lab = bfd_make_empty_symbol (abfd);
+   iname_lab->name = head_label;
+   iname_lab->section = bfd_und_section_ptr;
+   iname_lab->flags = 0;
+   iname_lab->value = 0;
+ 
+-  iname_pp = ptrs + oidx;
++  asymbol **iname_pp = ptrs + oidx;
+   if (create_compat_implib)
+     ptrs[oidx++] = iname;
+   ptrs[oidx++] = iname2;
+ 
+-  iname_lab_pp = ptrs + oidx;
++  asymbol **iname_lab_pp = ptrs + oidx;
+   ptrs[oidx++] = iname_lab;
+ 
+   ptrs[oidx] = 0;
+@@ -3089,29 +3078,26 @@ gen_lib_file (int delay)
+ 
+   if (dontdeltemps < 2)
+     {
+-      char *name;
+-      size_t stub_len = strlen (TMP_STUB);
++      char *name = TMP_STUB;
++      size_t name_len = strlen (name);
+ 
+-      name = xmalloc (stub_len + 10);
+-      memcpy (name, TMP_STUB, stub_len);
+       for (i = 0; (exp = d_exports_lexically[i]); i++)
+ 	{
+ 	  /* Don't delete non-existent stubs for PRIVATE entries.  */
+           if (exp->private)
+ 	    continue;
+-	  sprintf (name + stub_len, "%05d.o", i);
++	  sprintf (name + name_len - 7, "%05d.o", i);
+ 	  if (unlink (name) < 0)
+ 	    /* xgettext:c-format */
+ 	    non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
+ 	  if (ext_prefix_alias)
+ 	    {
+-	      sprintf (name + stub_len, "%05d.o", i + PREFIX_ALIAS_BASE);
++	      sprintf (name + name_len - 7, "%05d.o", i + PREFIX_ALIAS_BASE);
+ 	      if (unlink (name) < 0)
+ 		/* xgettext:c-format */
+ 		non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
+ 	    }
+ 	}
+-      free (name);
+     }
+ 
+   inform (_("Created lib file"));
+@@ -4096,9 +4082,9 @@ main (int ac, char **av)
+   if (tmp_prefix == NULL)
+     {
+       /* If possible use a deterministic prefix.  */
+-      if (imp_name || delayimp_name)
++      const char *input = imp_name ? imp_name : delayimp_name;
++      if (input && strlen (input) + sizeof ("_snnnnn.o") - 1 <= NAME_MAX)
+         {
+-          const char *input = imp_name ? imp_name : delayimp_name;
+           tmp_prefix = xmalloc (strlen (input) + 2);
+           sprintf (tmp_prefix, "%s_", input);
+           for (i = 0; tmp_prefix[i]; i++)
+@@ -4106,9 +4092,7 @@ main (int ac, char **av)
+               tmp_prefix[i] = '_';
+         }
+       else
+-        {
+-          tmp_prefix = prefix_encode ("d", getpid ());
+-        }
++        tmp_prefix = prefix_encode ("d", getpid ());
+     }
+ 
+   mangle_defs ();
+-- 
+2.34.1
+