diff options
-rw-r--r-- | libiberty/ChangeLog | 5 | ||||
-rw-r--r-- | libiberty/simple-object.c | 25 | ||||
-rw-r--r-- | lto-plugin/ChangeLog | 4 | ||||
-rw-r--r-- | lto-plugin/lto-plugin.c | 42 |
4 files changed, 56 insertions, 20 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 9dab384ccf2..f20fac0aabb 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,8 @@ +2014-03-28 Richard Biener <rguenther@suse.de> + + * simple-object.c (simple_object_internal_read): Handle + EINTR and short reads. + 2014-03-13 Uros Bizjak <ubizjak@gmail.com> * regex.c (bzero) [!_LIBC]: Define without coma expression. diff --git a/libiberty/simple-object.c b/libiberty/simple-object.c index fde3454dd42..263d174051d 100644 --- a/libiberty/simple-object.c +++ b/libiberty/simple-object.c @@ -63,8 +63,6 @@ simple_object_internal_read (int descriptor, off_t offset, unsigned char *buffer, size_t size, const char **errmsg, int *err) { - ssize_t got; - if (lseek (descriptor, offset, SEEK_SET) < 0) { *errmsg = "lseek"; @@ -72,15 +70,26 @@ simple_object_internal_read (int descriptor, off_t offset, return 0; } - got = read (descriptor, buffer, size); - if (got < 0) + do { - *errmsg = "read"; - *err = errno; - return 0; + ssize_t got = read (descriptor, buffer, size); + if (got == 0) + break; + else if (got > 0) + { + buffer += got; + size -= got; + } + else if (errno != EINTR) + { + *errmsg = "read"; + *err = errno; + return 0; + } } + while (size > 0); - if ((size_t) got < size) + if (size > 0) { *errmsg = "file too short"; *err = 0; diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog index 73688cd1cfc..8dcbc08bb5c 100644 --- a/lto-plugin/ChangeLog +++ b/lto-plugin/ChangeLog @@ -1,3 +1,7 @@ +2014-03-28 Richard Biener <rguenther@suse.de> + + * lto-plugin.c (process_symtab): Handle EINTR and short reads. + 2014-03-17 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * configure.ac (ac_lto_plugin_ldflags): Set to -Wc,-static-libgcc diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c index 6f31ed27384..1432340b015 100644 --- a/lto-plugin/lto-plugin.c +++ b/lto-plugin/lto-plugin.c @@ -39,6 +39,7 @@ along with this program; see the file COPYING3. If not see #include <stdint.h> #endif #include <assert.h> +#include <errno.h> #include <string.h> #include <stdlib.h> #include <stdio.h> @@ -817,7 +818,7 @@ process_symtab (void *data, const char *name, off_t offset, off_t length) { struct plugin_objfile *obj = (struct plugin_objfile *)data; char *s; - char *secdata; + char *secdatastart, *secdata; if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0) return 1; @@ -825,23 +826,40 @@ process_symtab (void *data, const char *name, off_t offset, off_t length) s = strrchr (name, '.'); if (s) sscanf (s, ".%" PRI_LL "x", &obj->out->id); - secdata = xmalloc (length); + secdata = secdatastart = xmalloc (length); offset += obj->file->offset; - if (offset != lseek (obj->file->fd, offset, SEEK_SET) - || length != read (obj->file->fd, secdata, length)) + if (offset != lseek (obj->file->fd, offset, SEEK_SET)) + goto err; + + do { - if (message) - message (LDPL_FATAL, "%s: corrupt object file", obj->file->name); - /* Force claim_file_handler to abandon this file. */ - obj->found = 0; - free (secdata); - return 0; + ssize_t got = read (obj->file->fd, secdata, length); + if (got == 0) + break; + else if (got > 0) + { + secdata += got; + length -= got; + } + else if (errno != EINTR) + goto err; } + while (length > 0); + if (length > 0) + goto err; - translate (secdata, secdata + length, obj->out); + translate (secdatastart, secdata, obj->out); obj->found++; - free (secdata); + free (secdatastart); return 1; + +err: + if (message) + message (LDPL_FATAL, "%s: corrupt object file", obj->file->name); + /* Force claim_file_handler to abandon this file. */ + obj->found = 0; + free (secdatastart); + return 0; } /* Callback used by gold to check if the plugin will claim FILE. Writes |