+
+ file->name = input->name;
+ file->offset = input->offset;
+ file->filesize = input->filesize;
+ file->handle = (void *) handle;
+
+ return LDPS_OK;
+}
+
+/* Get view of the input file. */
+static enum ld_plugin_status
+get_view (const void *handle, const void **viewp)
+{
+ plugin_input_file_t *input = (plugin_input_file_t *) handle;
+ char *buffer;
+ size_t size = input->filesize;
+ off_t offset = input->offset;
+#if HAVE_MMAP && HAVE_GETPAGESIZE
+ off_t bias;
+#endif
+
+ ASSERT (called_plugin);
+
+ /* FIXME: einfo should support %lld. */
+ if ((off_t) size != input->filesize)
+ einfo (_("%P%F: 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;