From 35a1e5f3055fc28f129e4d5d0a993218d8af1baf Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Sat, 7 Feb 2015 11:01:22 -0800 Subject: [PATCH] Update plugin_maybe_claim This patch removes the argument of pointer to struct ld_plugin_input_file. This is the first step to extract a plugin_object_p out of plugin_maybe_claim for BFD. * plugin.c: Include "libbfd.h". (plugin_strdup): New. (plugin_maybe_claim): Remove the argument of pointer to struct ld_plugin_input_file. Open and handle input entry. * plugin.h (plugin_maybe_claim): Updated. * ldfile.c (ldfile_try_open_bfd): Call plugin_maybe_claim directly without passing a pointer to struct ld_plugin_input_file. * ldmain.c: Don't include "libbfd.h". (add_archive_element): Call plugin_maybe_claim directly without passing a pointer to struct ld_plugin_input_file. --- ld/ChangeLog | 13 ++++++++ ld/ldfile.c | 14 +-------- ld/ldmain.c | 25 +++------------- ld/plugin.c | 85 +++++++++++++++++++++++++++++++++++++++------------- ld/plugin.h | 3 +- 5 files changed, 83 insertions(+), 57 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 52c3ba05b4..d7125ff498 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,16 @@ +2015-02-07 H.J. Lu + + * plugin.c: Include "libbfd.h". + (plugin_strdup): New. + (plugin_maybe_claim): Remove the argument of pointer to struct + ld_plugin_input_file. Open and handle input entry. + * plugin.h (plugin_maybe_claim): Updated. + * ldfile.c (ldfile_try_open_bfd): Call plugin_maybe_claim directly + without passing a pointer to struct ld_plugin_input_file. + * ldmain.c: Don't include "libbfd.h". + (add_archive_element): Call plugin_maybe_claim directly without + passing a pointer to struct ld_plugin_input_file. + 2015-02-06 H.J. Lu * ld.texinfo: Document -z text, -z notext and -z textoff. diff --git a/ld/ldfile.c b/ld/ldfile.c index c9c954166e..05889f2e6c 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -304,19 +304,7 @@ success: if (bfd_check_format (entry->the_bfd, bfd_object) && link_info.lto_plugin_active && !no_more_claiming) - { - int fd = open (attempt, O_RDONLY | O_BINARY); - if (fd >= 0) - { - struct ld_plugin_input_file file; - - file.name = attempt; - file.offset = 0; - file.filesize = lseek (fd, 0, SEEK_END); - file.fd = fd; - plugin_maybe_claim (&file, entry); - } - } + plugin_maybe_claim (entry); #endif /* ENABLE_PLUGINS */ /* It opened OK, the format checked out, and the plugins have had diff --git a/ld/ldmain.c b/ld/ldmain.c index 86f02a6725..4b41288fe5 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -41,7 +41,6 @@ #ifdef ENABLE_PLUGINS #include "plugin.h" #include "plugin-api.h" -#include "libbfd.h" #endif /* ENABLE_PLUGINS */ /* Somewhere above, sys/stat.h got included. */ @@ -793,27 +792,11 @@ add_archive_element (struct bfd_link_info *info, if (link_info.lto_plugin_active && !no_more_claiming) { /* We must offer this archive member to the plugins to claim. */ - const char *filename = (bfd_my_archive (abfd) != NULL - ? bfd_my_archive (abfd)->filename : abfd->filename); - int fd = open (filename, O_RDONLY | O_BINARY); - if (fd >= 0) + plugin_maybe_claim (input); + if (input->flags.claimed) { - struct ld_plugin_input_file file; - - /* Offset and filesize must refer to the individual archive - member, not the whole file, and must exclude the header. - Fortunately for us, that is how the data is stored in the - origin field of the bfd and in the arelt_data. */ - file.name = filename; - file.offset = abfd->origin; - file.filesize = arelt_size (abfd); - file.fd = fd; - plugin_maybe_claim (&file, input); - if (input->flags.claimed) - { - input->flags.claim_archive = TRUE; - *subsbfd = input->the_bfd; - } + input->flags.claim_archive = TRUE; + *subsbfd = input->the_bfd; } } #endif /* ENABLE_PLUGINS */ diff --git a/ld/plugin.c b/ld/plugin.c index 7ee45a2ecc..30e4ab4e26 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -21,6 +21,7 @@ #include "sysdep.h" #include "libiberty.h" #include "bfd.h" +#include "libbfd.h" #include "bfdlink.h" #include "bfdver.h" #include "ld.h" @@ -980,41 +981,83 @@ plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed) return plugin_error_p () ? -1 : 0; } +/* Duplicates a character string with memory attached to ABFD. */ + +static char * +plugin_strdup (bfd *abfd, const char *str) +{ + size_t strlength; + char *copy; + strlength = strlen (str) + 1; + copy = bfd_alloc (abfd, strlength); + if (copy == NULL) + einfo (_("%P%F: plugin_strdup failed to allocate memory: %s\n"), + bfd_get_error ()); + memcpy (copy, str, strlength); + return copy; +} + void -plugin_maybe_claim (struct ld_plugin_input_file *file, - lang_input_statement_type *entry) +plugin_maybe_claim (lang_input_statement_type *entry) { int claimed = 0; plugin_input_file_t *input; - size_t namelength; + off_t offset, filesize; + struct ld_plugin_input_file file; + bfd *abfd; + bfd *ibfd = entry->the_bfd; + bfd_boolean inarchive = bfd_my_archive (ibfd) != NULL; + const char *name + = inarchive ? bfd_my_archive (ibfd)->filename : ibfd->filename; + int fd = open (name, O_RDONLY | O_BINARY); + + if (fd < 0) + return; /* We create a dummy BFD, initially empty, to house whatever symbols the plugin may want to add. */ - bfd *abfd = plugin_get_ir_dummy_bfd (entry->the_bfd->filename, - entry->the_bfd); + abfd = plugin_get_ir_dummy_bfd (ibfd->filename, ibfd); input = bfd_alloc (abfd, sizeof (*input)); if (input == NULL) einfo (_("%P%F: plugin failed to allocate memory for input: %s\n"), bfd_get_error ()); + if (inarchive) + { + /* Offset and filesize must refer to the individual archive + member, not the whole file, and must exclude the header. + Fortunately for us, that is how the data is stored in the + origin field of the bfd and in the arelt_data. */ + offset = ibfd->origin; + filesize = arelt_size (ibfd); + } + else + { + offset = 0; + filesize = lseek (fd, 0, SEEK_END); + + /* We must copy filename attached to ibfd if it is not an archive + member since it may be freed by bfd_close below. */ + name = plugin_strdup (abfd, name); + } + + file.name = name; + file.offset = offset; + file.filesize = filesize; + file.fd = fd; + file.handle = input; + input->abfd = abfd; input->view_buffer.addr = NULL; input->view_buffer.filesize = 0; input->view_buffer.offset = 0; - input->fd = file->fd; - input->offset = file->offset; - input->filesize = file->filesize; - namelength = strlen (entry->the_bfd->filename) + 1; - input->name = bfd_alloc (abfd, namelength); - if (input->name == NULL) - einfo (_("%P%F: plugin failed to allocate memory for input filename: %s\n"), - bfd_get_error ()); - memcpy (input->name, entry->the_bfd->filename, namelength); - - file->handle = input; + input->fd = fd; + input->offset = offset; + input->filesize = filesize; + input->name = plugin_strdup (abfd, ibfd->filename); - if (plugin_call_claim_file (file, &claimed)) + if (plugin_call_claim_file (&file, &claimed)) einfo (_("%P%F: %s: plugin reported error claiming file\n"), plugin_error_plugin ()); @@ -1028,7 +1071,7 @@ plugin_maybe_claim (struct ld_plugin_input_file *file, calls release_input_file after it is done, is stored in non-bfd_object file. This scheme doesn't work when a plugin needs fd and its IR is stored in bfd_object file. */ - close (file->fd); + close (fd); input->fd = -1; } @@ -1038,11 +1081,11 @@ plugin_maybe_claim (struct ld_plugin_input_file *file, /* BFD archive handling caches elements so we can't call bfd_close for archives. */ - if (entry->the_bfd->my_archive == NULL) - bfd_close (entry->the_bfd); + if (!inarchive) + bfd_close (ibfd); + bfd_make_readable (abfd); entry->the_bfd = abfd; entry->flags.claimed = TRUE; - bfd_make_readable (entry->the_bfd); } else { diff --git a/ld/plugin.h b/ld/plugin.h index 15532cd0b7..59c0df76e6 100644 --- a/ld/plugin.h +++ b/ld/plugin.h @@ -46,8 +46,7 @@ extern void plugin_load_plugins (void); extern const char *plugin_error_plugin (void); /* Call 'claim file' hook for all plugins. */ -extern void plugin_maybe_claim (struct ld_plugin_input_file *, - lang_input_statement_type *); +extern void plugin_maybe_claim (lang_input_statement_type *); /* Call 'all symbols read' hook for all plugins. */ extern int plugin_call_all_symbols_read (void); -- 2.34.1