diff options
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 12 | ||||
-rw-r--r-- | ld/plugin.c | 5 | ||||
-rw-r--r-- | ld/testplug.c | 41 | ||||
-rw-r--r-- | ld/testsuite/ld-plugin/plugin-30.d | 26 | ||||
-rw-r--r-- | ld/testsuite/ld-plugin/plugin.exp | 7 |
5 files changed, 90 insertions, 1 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 758d7ad..35a2b80 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +2016-07-19 Andrew Burgess <andrew.burgess@embecosm.com> + + * plugin.c (plugin_call_claim_file): Restore the file offset after + an unsuccessful attempt to claim a file. + * testplug.c (bytes_to_read_before_claim): New global. + (record_read_length): New function, sets new global + bytes_to_read_before_claim. + (parse_option): Handle 'read:<NUMBER>' option. + (onclaim_file): Read file content before checking for claim. + * testsuite/ld-plugin/plugin-30.d: New file. + * testsuite/ld-plugin/plugin.exp: Add new test. + 2016-07-16 Alan Modra <amodra@gmail.com> * plugin.c: Don't include libbfd.h. Include plugin-api.h diff --git a/ld/plugin.c b/ld/plugin.c index ffa0dd3..36094dd 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -1049,9 +1049,14 @@ plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed) { if (curplug->claim_file_handler) { + off_t cur_offset; enum ld_plugin_status rv; + called_plugin = curplug; + cur_offset = lseek (file->fd, 0, SEEK_CUR); rv = (*curplug->claim_file_handler) (file, claimed); + if (!*claimed) + lseek (file->fd, cur_offset, SEEK_SET); called_plugin = NULL; if (rv != LDPS_OK) set_plugin_error (curplug->name); diff --git a/ld/testplug.c b/ld/testplug.c index cec947c..684fc41 100644 --- a/ld/testplug.c +++ b/ld/testplug.c @@ -24,6 +24,8 @@ /* For ARRAY_SIZE macro only - we don't link the library itself. */ #include "libiberty.h" +#include <ctype.h> /* For isdigit. */ + extern enum ld_plugin_status onload (struct ld_plugin_tv *tv); static enum ld_plugin_status onclaim_file (const struct ld_plugin_input_file *file, int *claimed); @@ -139,6 +141,10 @@ static add_file_t *addfiles_list = NULL; /* We keep a tail pointer for easy linking on the end. */ static add_file_t **addfiles_tail_chain_ptr = &addfiles_list; +/* Number of bytes read in claim file before deciding if the file can be + claimed. */ +static int bytes_to_read_before_claim = 0; + /* Add a new claimfile on the end of the chain. */ static enum ld_plugin_status record_claim_file (const char *file) @@ -159,6 +165,25 @@ record_claim_file (const char *file) return LDPS_OK; } +/* How many bytes to read before claiming (or not) an input file. */ +static enum ld_plugin_status +record_read_length (const char *length) +{ + const char *tmp; + + tmp = length; + while (*tmp != '\0' && isdigit (*tmp)) + ++tmp; + if (*tmp != '\0' || *length == '\0') + { + fprintf (stderr, "APB: Bad length string: %s\n", tmp); + return LDPS_ERR; + } + + bytes_to_read_before_claim = atoi (length); + return LDPS_OK; +} + /* Add a new addfile on the end of the chain. */ static enum ld_plugin_status record_add_file (const char *file, addfile_enum_t type) @@ -325,6 +350,8 @@ parse_option (const char *opt) return set_register_hook (opt + 10, FALSE); else if (!strncmp ("claim:", opt, 6)) return record_claim_file (opt + 6); + else if (!strncmp ("read:", opt, 5)) + return record_read_length (opt + 5); else if (!strncmp ("sym:", opt, 4)) return record_claimed_file_symbol (opt + 4); else if (!strncmp ("add:", opt, 4)) @@ -527,6 +554,20 @@ onload (struct ld_plugin_tv *tv) static enum ld_plugin_status onclaim_file (const struct ld_plugin_input_file *file, int *claimed) { + /* Possible read of some bytes out of the input file into a buffer. This + simulates a plugin that reads some file content in order to decide if + the file should be claimed or not. */ + if (bytes_to_read_before_claim > 0) + { + char *buffer = malloc (bytes_to_read_before_claim); + + if (buffer == NULL) + return LDPS_ERR; + if (read (file->fd, buffer, bytes_to_read_before_claim) < 0) + return LDPS_ERR; + free (buffer); + } + /* Let's see if we want to claim this file. */ claim_file_t *claimfile = claimfiles_list; while (claimfile) diff --git a/ld/testsuite/ld-plugin/plugin-30.d b/ld/testsuite/ld-plugin/plugin-30.d new file mode 100644 index 0000000..eb9d424 --- /dev/null +++ b/ld/testsuite/ld-plugin/plugin-30.d @@ -0,0 +1,26 @@ +Hello from testplugin. +.*: LDPT_MESSAGE func@0x.* +.*: LDPT_API_VERSION value 0x1 \(1\) +.*: LDPT_GNU_LD_VERSION value 0x.* +.*: LDPT_LINKER_OUTPUT value 0x1 \(1\) +.*: LDPT_OUTPUT_NAME 'tmpdir/main.x' +.*: LDPT_REGISTER_CLAIM_FILE_HOOK func@0x.* +.*: LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK func@0x.* +.*: LDPT_REGISTER_CLEANUP_HOOK func@0x.* +.*: LDPT_ADD_SYMBOLS func@0x.* +.*: LDPT_GET_INPUT_FILE func@0x.* +.*: LDPT_GET_VIEW func@0x.* +.*: LDPT_RELEASE_INPUT_FILE func@0x.* +.*: LDPT_GET_SYMBOLS func@0x.* +.*: LDPT_GET_SYMBOLS_V2 func@0x.* +.*: LDPT_ADD_INPUT_FILE func@0x.* +.*: LDPT_ADD_INPUT_LIBRARY func@0x.* +.*: LDPT_SET_EXTRA_LIBRARY_PATH func@0x.* +.*: LDPT_OPTION 'registerclaimfile' +.*: LDPT_OPTION 'read:8' +.*: LDPT_NULL value 0x0 \(0\) +#... +hook called: claim_file tmpdir/main.o \[@0/.* not claimed +hook called: claim_file tmpdir/func.o \[@0/.* not claimed +hook called: claim_file tmpdir/text.o \[@0/.* not claimed +hook called: claim_file tmpdir/libempty.a \[@.* not claimed diff --git a/ld/testsuite/ld-plugin/plugin.exp b/ld/testsuite/ld-plugin/plugin.exp index 4c9116b..a6946c4 100644 --- a/ld/testsuite/ld-plugin/plugin.exp +++ b/ld/testsuite/ld-plugin/plugin.exp @@ -236,6 +236,10 @@ set plugin_lib_tests [list \ -plugin-opt sym:${_}text::0:0:0 \ -plugin-opt add:tmpdir/text.o \ $testsrcfiles_notext -Ltmpdir -ltext $libs" "" "" "" {{ld plugin-19.d}} "main.x" ] \ + [list "plugin with empty archive" \ + "-plugin $plugin_path $regclm \ + -plugin-opt read:8 \ + $testobjfiles tmpdir/libempty.a $libs" "" "" "" {{ld plugin-30.d}} "main.x" ] \ ] set plugin_extra_elf_tests [list \ @@ -289,7 +293,8 @@ if { [is_elf_format] \ run_ld_link_tests $plugin_extra_elf_tests } -if ![ar_simple_create $ar "" "tmpdir/libtext.a" "tmpdir/text.o"] { +if {![ar_simple_create $ar "" "tmpdir/libtext.a" "tmpdir/text.o"] || \ + ![ar_simple_create $ar "" "tmpdir/libempty.a" ""]} { foreach testitem $plugin_lib_tests { unresolved [lindex $testitem 0] } |