From: Felix Fietkau Date: Tue, 10 Jul 2018 12:19:36 +0000 (+0200) Subject: binutils: backport an upstream fix for a linker bug that triggers with LTO X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=55055aee50f7837a50a623b00c98a84e68080f91;p=openwrt%2Fstaging%2Fneocturne.git binutils: backport an upstream fix for a linker bug that triggers with LTO Signed-off-by: Felix Fietkau --- diff --git a/toolchain/binutils/patches/2.30/100-PR23254-ld.bfd-mishandles-file-pointers-while-scanni.patch b/toolchain/binutils/patches/2.30/100-PR23254-ld.bfd-mishandles-file-pointers-while-scanni.patch new file mode 100644 index 0000000000..8a0b675538 --- /dev/null +++ b/toolchain/binutils/patches/2.30/100-PR23254-ld.bfd-mishandles-file-pointers-while-scanni.patch @@ -0,0 +1,112 @@ +From: Alan Modra +Date: Tue, 5 Jun 2018 21:04:00 +0930 +Subject: [PATCH] PR23254, ld.bfd mishandles file pointers while scanning + archive + +Best practice is to not mix lseek/read with fseek/fread on the same +underlying file descriptor, as not all stdio implementations will cope. +Since the plugin uses lseek/read while bfd uses fseek/fread this patch +reopens the file for exclusive use by the plugin rather than trying to +restore the file descriptor. That allows the plugin to read the file +after plugin_call_claim_file too. + +bfd/ + PR 23254 + * plugin.c (bfd_plugin_open_input): Allow for possibility of + nested archives. Open file again for plugin. + (try_claim): Don't save and restore file position. Close file + if not claimed. + * sysdep.h (O_BINARY): Define. +ld/ + PR 23254 + * plugin.c (plugin_call_claim_file): Revert 2016-07-19 patch. + (plugin_object_p): Don't dup file descriptor. +--- + +--- a/bfd/plugin.c ++++ b/bfd/plugin.c +@@ -165,14 +165,22 @@ bfd_plugin_open_input (bfd *ibfd, struct + bfd *iobfd; + + iobfd = ibfd; +- if (ibfd->my_archive && !bfd_is_thin_archive (ibfd->my_archive)) +- iobfd = ibfd->my_archive; ++ while (iobfd->my_archive ++ && !bfd_is_thin_archive (iobfd->my_archive)) ++ iobfd = iobfd->my_archive; + file->name = iobfd->filename; + + if (!iobfd->iostream && !bfd_open_file (iobfd)) + return 0; + +- file->fd = fileno ((FILE *) iobfd->iostream); ++ /* The plugin API expects that the file descriptor won't be closed ++ and reused as done by the bfd file cache. So open it again. ++ dup isn't good enough. plugin IO uses lseek/read while BFD uses ++ fseek/fread. It isn't wise to mix the unistd and stdio calls on ++ the same underlying file descriptor. */ ++ file->fd = open (file->name, O_RDONLY | O_BINARY); ++ if (file->fd < 0) ++ return 0; + + if (iobfd == ibfd) + { +@@ -196,12 +204,12 @@ try_claim (bfd *abfd) + int claimed = 0; + struct ld_plugin_input_file file; + ++ file.handle = abfd; + if (!bfd_plugin_open_input (abfd, &file)) + return 0; +- file.handle = abfd; +- off_t cur_offset = lseek (file.fd, 0, SEEK_CUR); + claim_file (&file, &claimed); +- lseek (file.fd, cur_offset, SEEK_SET); ++ if (!claimed) ++ close (file.fd); + return claimed; + } + +--- a/bfd/sysdep.h ++++ b/bfd/sysdep.h +@@ -108,6 +108,10 @@ extern char *strrchr (); + #ifndef O_ACCMODE + #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) + #endif ++/* Systems that don't already define this, don't need it. */ ++#ifndef O_BINARY ++#define O_BINARY 0 ++#endif + + #ifndef SEEK_SET + #define SEEK_SET 0 +--- a/ld/plugin.c ++++ b/ld/plugin.c +@@ -1053,14 +1053,10 @@ plugin_call_claim_file (const struct ld_ + { + if (curplug->claim_file_handler) + { +- off_t cur_offset; + enum ld_plugin_status rv; + + called_plugin = curplug; +- cur_offset = lseek (file->fd, 0, SEEK_CUR); + rv = (*curplug->claim_file_handler) (file, claimed); +- if (!*claimed) +- lseek (file->fd, cur_offset, SEEK_SET); + called_plugin = NULL; + if (rv != LDPS_OK) + set_plugin_error (curplug->name); +@@ -1126,12 +1122,6 @@ plugin_object_p (bfd *ibfd) + } + + file.handle = input; +- /* The plugin API expects that the file descriptor won't be closed +- and reused as done by the bfd file cache. So dup one. */ +- file.fd = dup (file.fd); +- if (file.fd < 0) +- return NULL; +- + input->abfd = abfd; + input->view_buffer.addr = NULL; + input->view_buffer.filesize = 0;