forked from openwrt/openwrt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
binutils: backport an upstream fix for a linker bug that triggers wit…
…h LTO Signed-off-by: Felix Fietkau <nbd@nbd.name>
- Loading branch information
Showing
1 changed file
with
112 additions
and
0 deletions.
There are no files selected for viewing
112 changes: 112 additions & 0 deletions
112
...hain/binutils/patches/2.30/100-PR23254-ld.bfd-mishandles-file-pointers-while-scanni.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
From: Alan Modra <amodra@gmail.com> | ||
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; |