+
+ /* FIXME: einfo should support %lld. */
+ if ((off_t) size != input->filesize)
+ einfo (_("%F%P: unsupported input file size: %s (%ld bytes)\n"),
+ input->name, (long) input->filesize);
+
+ /* Check the cached view buffer. */
+ if (input->view_buffer.addr != NULL
+ && input->view_buffer.filesize == size
+ && input->view_buffer.offset == offset)
+ {
+ *viewp = input->view_buffer.addr;
+ return LDPS_OK;
+ }
+
+ input->view_buffer.filesize = size;
+ input->view_buffer.offset = offset;
+
+#if HAVE_MMAP
+# if HAVE_GETPAGESIZE
+ bias = offset % plugin_pagesize;
+ offset -= bias;
+ size += bias;
+# endif
+ buffer = mmap (NULL, size, PROT_READ, MAP_PRIVATE, input->fd, offset);
+ if (buffer != MAP_FAILED)
+ {
+ input->use_mmap = true;
+# if HAVE_GETPAGESIZE
+ buffer += bias;
+# endif
+ }
+ else
+#endif
+ {
+ char *p;
+
+ input->use_mmap = false;
+
+ if (lseek (input->fd, offset, SEEK_SET) < 0)
+ return LDPS_ERR;
+
+ buffer = bfd_alloc (input->abfd, size);
+ if (buffer == NULL)
+ return LDPS_ERR;
+
+ p = buffer;
+ do
+ {
+ ssize_t got = read (input->fd, p, size);
+ if (got == 0)
+ break;
+ else if (got > 0)
+ {
+ p += got;
+ size -= got;
+ }
+ else if (errno != EINTR)
+ return LDPS_ERR;
+ }
+ while (size > 0);
+ }
+
+ input->view_buffer.addr = buffer;
+ *viewp = buffer;
+
+ return LDPS_OK;
+}
+
+/* Release plugin file descriptor. */
+
+static void
+release_plugin_file_descriptor (plugin_input_file_t *input)
+{
+ if (input->fd != -1)
+ {
+ bfd_plugin_close_file_descriptor (input->ibfd, input->fd);
+ input->fd = -1;
+ }