toolchain/binutils: v2.37 Close the file descriptor if there is no archive fd
authorHirokazu MORIKAWA <morikw2@gmail.com>
Sat, 8 Jan 2022 00:33:32 +0000 (09:33 +0900)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 8 Jan 2022 20:37:45 +0000 (21:37 +0100)
This fixes the following build error:
/home/build/openwrt/staging_dir/toolchain-aarch64_cortex-a53_gcc-11.2.0_musl/lib/gcc/aarch64-openwrt-linux-musl/11.2.0/../../../../aarch64-openwrt-linux-musl/bin/ld: /home/sergey/openwrt2/build_dir/target-aarch64_cortex-a53_musl/node-v14.18.2/out/Release/obj.target/tools/v8_gypfiles/libv8_base_without_compiler.a: error adding symbols: malformed archive
collect2: error: ld returned 1 exit status

It's a bad error handling related to -EMFILE (too many open files). nodejs is probably just very close to open file limit.

https://sourceware.org/bugzilla/show_bug.cgi?id=28138
https://github.com/nodejs/node/issues/39452

https://github.com/openwrt/packages/issues/17496
https://github.com/openwrt/packages/issues/16729
https://github.com/openwrt/packages/issues/17164

Signed-off-by: Hirokazu MORIKAWA <morikw2@gmail.com>
[Take full patch from 2.37 branch and refresh]
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
toolchain/binutils/patches/2.37/600-Close_the_file_descriptor.patch [new file with mode: 0644]

diff --git a/toolchain/binutils/patches/2.37/600-Close_the_file_descriptor.patch b/toolchain/binutils/patches/2.37/600-Close_the_file_descriptor.patch
new file mode 100644 (file)
index 0000000..fef86a9
--- /dev/null
@@ -0,0 +1,184 @@
+From: H.J. Lu <hjl.tools@gmail.com>
+Date: Mon, 26 Jul 2021 12:59:55 +0000 (-0700)
+Subject: bfd: Close the file descriptor if there is no archive fd
+X-Git-Url: https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff_plain;h=1c611b40e6bfc8029bff7696814330b5bc0ee5c0
+
+bfd: Close the file descriptor if there is no archive fd
+
+Close the file descriptor if there is no archive plugin file descriptor
+to avoid running out of file descriptors on thin archives with many
+archive members.
+
+bfd/
+
+       PR ld/28138
+       * plugin.c (bfd_plugin_close_file_descriptor): Close the file
+       descriptor there is no archive plugin file descriptor.
+
+ld/
+
+       PR ld/28138
+       * testsuite/ld-plugin/lto.exp: Run tmpdir/pr28138 only for
+       native build.
+
+       PR ld/28138
+       * testsuite/ld-plugin/lto.exp: Run ld/28138 tests.
+       * testsuite/ld-plugin/pr28138.c: New file.
+       * testsuite/ld-plugin/pr28138-1.c: Likewise.
+       * testsuite/ld-plugin/pr28138-2.c: Likewise.
+       * testsuite/ld-plugin/pr28138-3.c: Likewise.
+       * testsuite/ld-plugin/pr28138-4.c: Likewise.
+       * testsuite/ld-plugin/pr28138-5.c: Likewise.
+       * testsuite/ld-plugin/pr28138-6.c: Likewise.
+       * testsuite/ld-plugin/pr28138-7.c: Likewise.
+
+(cherry picked from commit 5a98fb7513b559e20dfebdbaa2a471afda3b4742)
+(cherry picked from commit 7dc37e1e1209c80e0bab784df6b6bac335e836f2)
+---
+
+--- a/bfd/plugin.c
++++ b/bfd/plugin.c
+@@ -291,6 +291,14 @@ bfd_plugin_close_file_descriptor (bfd *a
+            && !bfd_is_thin_archive (abfd->my_archive))
+       abfd = abfd->my_archive;
++      /* Close the file descriptor if there is no archive plugin file
++       descriptor.  */
++      if (abfd->archive_plugin_fd == -1)
++      {
++        close (fd);
++        return;
++      }
++
+       abfd->archive_plugin_fd_open_count--;
+       /* Dup the archive plugin file descriptor for later use, which
+        will be closed by _bfd_archive_close_and_cleanup.  */
+--- a/ld/testsuite/ld-plugin/lto.exp
++++ b/ld/testsuite/ld-plugin/lto.exp
+@@ -687,6 +687,40 @@ if { [is_elf_format] && [check_lto_share
+     }
+ }
++run_cc_link_tests [list \
++    [list \
++      "Build pr28138.a" \
++      "-T" "" \
++      {pr28138-1.c pr28138-2.c pr28138-3.c pr28138-4.c pr28138-5.c \
++       pr28138-6.c pr28138-7.c} {} "pr28138.a" \
++    ] \
++    [list \
++      "Build pr28138.o" \
++      "" "" \
++      {pr28138.c} {} \
++    ] \
++]
++
++set exec_output [run_host_cmd "sh" \
++                            "-c \"ulimit -n 20; \
++                            $CC -Btmpdir/ld -o tmpdir/pr28138 \
++                            tmpdir/pr28138.o tmpdir/pr28138.a\""]
++set exec_output [prune_warnings $exec_output]
++if [string match "" $exec_output] then {
++    if { [isnative] } {
++      set exec_output [run_host_cmd "tmpdir/pr28138" ""]
++      if [string match "PASS" $exec_output] then {
++          pass "PR ld/28138"
++      } else {
++          fail "PR ld/28138"
++      }
++    } else {
++      pass "PR ld/28138"
++    }
++} else {
++    fail "PR ld/28138"
++}
++
+ set testname "Build liblto-11.a"
+ remote_file host delete "tmpdir/liblto-11.a"
+ set catch_output [run_host_cmd "$ar" "rc $plug_opt tmpdir/liblto-11.a tmpdir/lto-11a.o tmpdir/lto-11b.o tmpdir/lto-11c.o"]
+--- /dev/null
++++ b/ld/testsuite/ld-plugin/pr28138-1.c
+@@ -0,0 +1,6 @@
++extern int a0(void);
++int
++a1(void)
++{
++  return 1 + a0();
++}
+--- /dev/null
++++ b/ld/testsuite/ld-plugin/pr28138-2.c
+@@ -0,0 +1,6 @@
++extern int a1(void);
++int
++a2(void)
++{
++  return 1 + a1();
++}
+--- /dev/null
++++ b/ld/testsuite/ld-plugin/pr28138-3.c
+@@ -0,0 +1,6 @@
++extern int a2(void);
++int
++a3(void)
++{
++  return 1 + a2();
++}
+--- /dev/null
++++ b/ld/testsuite/ld-plugin/pr28138-4.c
+@@ -0,0 +1,6 @@
++extern int a3(void);
++int
++a4(void)
++{
++  return 1 + a3();
++}
+--- /dev/null
++++ b/ld/testsuite/ld-plugin/pr28138-5.c
+@@ -0,0 +1,6 @@
++extern int a4(void);
++int
++a5(void)
++{
++  return 1 + a4();
++}
+--- /dev/null
++++ b/ld/testsuite/ld-plugin/pr28138-6.c
+@@ -0,0 +1,6 @@
++extern int a5(void);
++int
++a6(void)
++{
++  return 1 + a5();
++}
+--- /dev/null
++++ b/ld/testsuite/ld-plugin/pr28138-7.c
+@@ -0,0 +1,6 @@
++extern int a6(void);
++int
++a7(void)
++{
++  return 1 + a6();
++}
+--- /dev/null
++++ b/ld/testsuite/ld-plugin/pr28138.c
+@@ -0,0 +1,20 @@
++#include <stdio.h>
++
++extern int a7(void);
++
++int
++a0(void)
++{
++  return 0;
++}
++
++int
++main()
++{
++  if (a7() == 7)
++    {
++      printf ("PASS\n");
++      return 0;
++    }
++  return 1;
++}