Unmap the buffer if plugin didn't claim the file

If plugin didn't claim the file, unmap the buffer.

	* plugin.c (plugin_input_file_t): Add use_mmap.
	(plugin_pagesize): New.
	(get_view): Use plugin_pagesize.  Set use_mmap if mmap is used.
	(plugin_load_plugins): Initialize plugin_pagesize.
	(plugin_maybe_claim): Unmap the buffer if plugin didn't claim the
	file.
This commit is contained in:
H.J. Lu 2015-02-10 17:01:17 -08:00
parent e7d52ed304
commit 386047969d
2 changed files with 50 additions and 12 deletions

View File

@ -1,3 +1,12 @@
2015-02-10 H.J. Lu <hongjiu.lu@intel.com>
* plugin.c (plugin_input_file_t): Add use_mmap.
(plugin_pagesize): New.
(get_view): Use plugin_pagesize. Set use_mmap if mmap is used.
(plugin_load_plugins): Initialize plugin_pagesize.
(plugin_maybe_claim): Unmap the buffer if plugin didn't claim the
file.
2015-02-10 H.J. Lu <hongjiu.lu@intel.com> 2015-02-10 H.J. Lu <hongjiu.lu@intel.com>
* plugin.c (get_view): Align offset passed to mmap. * plugin.c (get_view): Align offset passed to mmap.

View File

@ -104,6 +104,7 @@ typedef struct plugin_input_file
view_buffer_t view_buffer; view_buffer_t view_buffer;
char *name; char *name;
int fd; int fd;
bfd_boolean use_mmap;
off_t offset; off_t offset;
off_t filesize; off_t filesize;
} plugin_input_file_t; } plugin_input_file_t;
@ -137,6 +138,11 @@ static struct bfd_link_callbacks plugin_callbacks;
its own newly-added input files and libs to claim. */ its own newly-added input files and libs to claim. */
bfd_boolean no_more_claiming = FALSE; bfd_boolean no_more_claiming = FALSE;
#if HAVE_MMAP && HAVE_GETPAGESIZE
/* Page size used by mmap. */
static off_t plugin_pagesize;
#endif
/* List of tags to set in the constant leading part of the tv array. */ /* List of tags to set in the constant leading part of the tv array. */
static const enum ld_plugin_tag tv_header_tags[] = static const enum ld_plugin_tag tv_header_tags[] =
{ {
@ -499,8 +505,9 @@ get_view (const void *handle, const void **viewp)
plugin_input_file_t *input = (plugin_input_file_t *) handle; plugin_input_file_t *input = (plugin_input_file_t *) handle;
char *buffer; char *buffer;
size_t size = input->filesize; size_t size = input->filesize;
#if HAVE_GETPAGESIZE off_t offset = input->offset;
off_t offset, bias; #if HAVE_MMAP && HAVE_GETPAGESIZE
off_t bias;
#endif #endif
ASSERT (called_plugin); ASSERT (called_plugin);
@ -513,34 +520,37 @@ get_view (const void *handle, const void **viewp)
/* Check the cached view buffer. */ /* Check the cached view buffer. */
if (input->view_buffer.addr != NULL if (input->view_buffer.addr != NULL
&& input->view_buffer.filesize == size && input->view_buffer.filesize == size
&& input->view_buffer.offset == input->offset) && input->view_buffer.offset == offset)
{ {
*viewp = input->view_buffer.addr; *viewp = input->view_buffer.addr;
return LDPS_OK; return LDPS_OK;
} }
input->view_buffer.filesize = size; input->view_buffer.filesize = size;
input->view_buffer.offset = input->offset; input->view_buffer.offset = offset;
#if HAVE_MMAP #if HAVE_MMAP
# if HAVE_GETPAGESIZE # if HAVE_GETPAGESIZE
bias = input->offset % getpagesize ();; bias = offset % plugin_pagesize;
offset = input->offset - bias; offset -= bias;
size += bias; size += bias;
# endif # endif
buffer = mmap (NULL, size, PROT_READ, MAP_PRIVATE, input->fd, offset); buffer = mmap (NULL, size, PROT_READ, MAP_PRIVATE, input->fd, offset);
# if HAVE_GETPAGESIZE
if (buffer != MAP_FAILED) if (buffer != MAP_FAILED)
buffer += bias; {
else input->use_mmap = TRUE;
# else # if HAVE_GETPAGESIZE
if (buffer == MAP_FAILED) buffer += bias;
# endif # endif
}
else
#endif #endif
{ {
char *p; char *p;
if (lseek (input->fd, input->offset, SEEK_SET) < 0) input->use_mmap = FALSE;
if (lseek (input->fd, offset, SEEK_SET) < 0)
return LDPS_ERR; return LDPS_ERR;
buffer = bfd_alloc (input->abfd, size); buffer = bfd_alloc (input->abfd, size);
@ -968,6 +978,10 @@ plugin_load_plugins (void)
link_info.notice_all = TRUE; link_info.notice_all = TRUE;
link_info.lto_plugin_active = TRUE; link_info.lto_plugin_active = TRUE;
link_info.callbacks = &plugin_callbacks; link_info.callbacks = &plugin_callbacks;
#if HAVE_MMAP && HAVE_GETPAGESIZE
plugin_pagesize = getpagesize ();;
#endif
} }
/* Call 'claim file' hook for all plugins. */ /* Call 'claim file' hook for all plugins. */
@ -1102,6 +1116,21 @@ plugin_maybe_claim (lang_input_statement_type *entry)
} }
else else
{ {
#if HAVE_MMAP
if (input->use_mmap)
{
/* If plugin didn't claim the file, unmap the buffer. */
char *addr = input->view_buffer.addr;
off_t size = input->view_buffer.filesize;
# if HAVE_GETPAGESIZE
off_t bias = input->view_buffer.offset % plugin_pagesize;
size += bias;
addr -= bias;
# endif
munmap (addr, size);
}
#endif
/* If plugin didn't claim the file, we don't need the dummy bfd. /* If plugin didn't claim the file, we don't need the dummy bfd.
Can't avoid speculatively creating it, alas. */ Can't avoid speculatively creating it, alas. */
bfd_close_all_done (abfd); bfd_close_all_done (abfd);