From patchwork Mon Jun 11 12:08:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Tesarik X-Patchwork-Id: 27742 Received: (qmail 38283 invoked by alias); 11 Jun 2018 12:23:49 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 37198 invoked by uid 89); 11 Jun 2018 12:23:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 11 Jun 2018 12:23:46 +0000 Received: from relay1.suse.de (charybdis-ext-too.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id B4E4FAECB for ; Mon, 11 Jun 2018 12:08:48 +0000 (UTC) From: Petr Tesarik To: gdb-patches@sourceware.org Cc: Petr Tesarik , Jeff Mahoney Subject: [PATCH v2 4/4] Add an optional offset option to the "add-symbol-file" command Date: Mon, 11 Jun 2018 14:08:35 +0200 Message-Id: <20180611120835.27343-5-ptesarik@suse.cz> In-Reply-To: <20180611120835.27343-1-ptesarik@suse.cz> References: <20180611120835.27343-1-ptesarik@suse.cz> X-IsSubscribed: yes If all sections of a symbol file are loaded with a fixed offset, it is easier to specify that offset than listing all sections explicitly. There is also a similar option for "symbol-file". gdb/ChangeLog: 2018-06-11 Petr Tesarik * symfile.c (add_symbol_file_command, _initialize_symfile): Add option "-o" to add-symbol-file-load to add an offset to each section's load address. gdb/doc/ChangeLog: 2018-06-11 Petr Tesarik * gdb.texinfo (Files): Document "add-symbol-file -o offset". gdb/testsuite/ChangeLog: 2018-06-11 Petr Tesarik * gdb.base/relocate.exp: Add test for "add-symbol-file -o ". --- gdb/ChangeLog | 6 ++++ gdb/NEWS | 4 +++ gdb/doc/ChangeLog | 4 +++ gdb/doc/gdb.texinfo | 10 ++++-- gdb/symfile.c | 61 +++++++++++++++++++++++++++++++++++-- gdb/testsuite/ChangeLog | 4 +++ gdb/testsuite/gdb.base/relocate.exp | 56 ++++++++++++++++++++++++++++++++++ 7 files changed, 139 insertions(+), 6 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0f75992d4c..337165e39e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,11 @@ 2018-06-11 Petr Tesarik + * symfile.c (add_symbol_file_command, _initialize_symfile): Add + option "-o" to add-symbol-file-load to add an offset to each + section's load address. + +2018-06-11 Petr Tesarik + * symfile.c (add_symbol_file_command): Make sure that sections with the same name are sorted in the same order. diff --git a/gdb/NEWS b/gdb/NEWS index 54c0f1d19b..016796a802 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -6,6 +6,10 @@ * The 'symbol-file' command now accepts an '-o' option to add a relative offset to all sections. +* Similarly, the 'add-symbol-file' command also accepts an '-o' option to add + a relative offset to all sections, but it allows to override the load + address of individual sections using '-s'. + * The 'add-symbol-file' command no longer requires the second argument (address of the text section). diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index b8f48733f9..09ae56db1c 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,5 +1,9 @@ 2018-06-11 Petr Tesarik + * gdb.texinfo (Files): Document "add-symbol-file -o offset". + +2018-06-11 Petr Tesarik + * gdb.texinfo (Files): The address argument for "add-symbol-file" is no longer mandatory. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 84600bfe5f..fb1b9ece62 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -18917,9 +18917,9 @@ the program is running. To do this, use the @code{kill} command @kindex add-symbol-file @cindex dynamic linking -@item add-symbol-file @var{filename} @r{[} @var{address} @r{]} -@itemx add-symbol-file @var{filename} @r{[} @var{address} @r{]} @r{[} -readnow @r{|} -readnever @r{]} -@itemx add-symbol-file @var{filename} @r{[} @var{address} @r{]} -s @var{section} @var{address} @dots{} +@item add-symbol-file @var{filename} @r{[} @var{address} @r{]} @r{[} -o @var{offset} @r{]} +@itemx add-symbol-file @var{filename} @r{[} @var{address} @r{]} @r{[} -o @var{offset} @r{]} @r{]} @r{[} -readnow @r{|} -readnever @r{]} +@itemx add-symbol-file @var{filename} @r{[} @var{address} @r{]} @r{[} -o @var{offset} @r{]} @r{]} -s @var{section} @var{address} @dots{} The @code{add-symbol-file} command reads additional symbol table information from the file @var{filename}. You would use this command when @var{filename} has been dynamically loaded (by some other means) @@ -18933,6 +18933,10 @@ If @var{address} is omitted, @value{GDBN} will use the section addresses found in @var{filename}. You can use @samp{-s} to override this default and load a section at a different address. +If an optional @var{offset} is specified, it is added to the start +address of each section, except those for which the address was +specified explicitly. + The symbol table of the file @var{filename} is added to the symbol table originally read with the @code{symbol-file} command. You can use the @code{add-symbol-file} command any number of times; the new symbol data diff --git a/gdb/symfile.c b/gdb/symfile.c index 8b8b194334..a8904f1f4a 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -2106,6 +2106,7 @@ add_symbol_file_command (const char *args, int from_tty) std::vector sect_opts = { { ".text", NULL } }; bool stop_processing_options = false; + CORE_ADDR offset = 0; dont_repeat (); @@ -2113,6 +2114,7 @@ add_symbol_file_command (const char *args, int from_tty) error (_("add-symbol-file takes a file name and an address")); bool seen_addr = false; + bool seen_offset = false; gdb_argv argv (args); for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt]) @@ -2150,6 +2152,15 @@ add_symbol_file_command (const char *args, int from_tty) sect_opts.push_back (sect); argcnt += 2; } + else if (strcmp (arg, "-o") == 0) + { + arg = argv[++argcnt]; + if (arg == NULL) + error (_("Missing argument to -o")); + + offset = parse_and_eval_address (arg); + seen_offset = true; + } else if (strcmp (arg, "--") == 0) stop_processing_options = true; else @@ -2195,7 +2206,13 @@ add_symbol_file_command (const char *args, int from_tty) At this point, we don't know what file type this is, so we can't determine what section names are valid. */ } - if (section_addrs.size () == 0) + if (seen_offset) + printf_unfiltered (_("%s offset by %s\n"), + (section_addrs.size () == 0 + ? _(" with all sections") + : _("with other sections")), + paddress (gdbarch, offset)); + else if (section_addrs.size () == 0) printf_unfiltered ("\n"); if (from_tty && (!query ("%s", ""))) @@ -2204,6 +2221,42 @@ add_symbol_file_command (const char *args, int from_tty) objf = symbol_file_add (filename.get (), add_flags, §ion_addrs, flags); + if (seen_offset) + { + std::vector new_offsets (objf->num_sections, + { offset }); + + std::vector sect_addrs_sorted + = addrs_section_sort (section_addrs); + + section_addr_info objf_addrs + = build_section_addr_info_from_objfile (objf); + std::vector objf_addrs_sorted + = addrs_section_sort (objf_addrs); + + std::vector::iterator sect_sorted_iter + = sect_addrs_sorted.begin (); + for (const struct other_sections *objf_sect : objf_addrs_sorted) + { + const char *objf_name = addr_section_name (objf_sect->name.c_str ()); + int cmp = -1; + + while (cmp < 0 && sect_sorted_iter != sect_addrs_sorted.end ()) + { + const struct other_sections *sect = *sect_sorted_iter; + const char *sect_name = addr_section_name (sect->name.c_str ()); + cmp = strcmp (sect_name, objf_name); + if (cmp <= 0) + ++sect_sorted_iter; + } + + if (cmp == 0) + new_offsets[objf_sect->sectindex].offsets[0] = 0; + } + + objfile_relocate (objf, new_offsets.data ()); + } + add_target_sections_of_objfile (objf); /* Getting new symbols may change our opinion about what is @@ -3792,12 +3845,14 @@ to execute.\n" READNOW_READNEVER_HELP), &cmdlist); c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command, _("\ Load symbols from FILE, assuming FILE has been dynamically loaded.\n\ -Usage: add-symbol-file FILE [ADDR] [-readnow | -readnever | \ +Usage: add-symbol-file FILE [ADDR] [-o OFF] [-readnow | -readnever | \ -s SECT-NAME SECT-ADDR]...\n\ ADDR is the starting address of the file's text.\n\ Each '-s' argument provides a section name and address, and\n\ should be specified if the data and bss segments are not contiguous\n\ -with the text. SECT-NAME is a section name to be loaded at SECT-ADDR.\n" +with the text. SECT-NAME is a section name to be loaded at SECT-ADDR.\n\ +OFF is an optional offset which is added to the default load addresses\n\ +of all sections for which no other address was specified.\n" READNOW_READNEVER_HELP), &cmdlist); set_cmd_completer (c, filename_completer); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index f2e7aa98a8..ce34c4b208 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2018-06-11 Petr Tesarik + * gdb.base/relocate.exp: Add test for "add-symbol-file -o ". + +2018-06-11 Petr Tesarik + * gdb.base/relocate.exp: Test add-symbol-file behavior when the address argument is omitted. diff --git a/gdb/testsuite/gdb.base/relocate.exp b/gdb/testsuite/gdb.base/relocate.exp index a3af8cea61..119495dd94 100644 --- a/gdb/testsuite/gdb.base/relocate.exp +++ b/gdb/testsuite/gdb.base/relocate.exp @@ -235,6 +235,62 @@ set new_function_foo_addr [get_var_address function_foo] gdb_assert {${new_function_foo_addr} == ${function_foo_addr} + $offset} \ "function foo is moved by offset" +# Load the object using add-symbol-file with an offset and check that +# all addresses are moved by that offset. + +set offset 0x10000 +clean_restart +gdb_test "add-symbol-file -o $offset $binfile" \ + "Reading symbols from ${binfile}\.\.\.done\." \ + "add-symbol-file with offset" \ + "add symbol table from file \".*${testfile}\\.o\" with all sections offset by $offset\[\r\n\]+\\(y or n\\) " \ + "y" + +# Make sure the address of a static variable is moved by offset. +set new_static_foo_addr [get_var_address static_foo] +gdb_assert { ${new_static_foo_addr} == ${static_foo_addr} + $offset } \ + "static variable foo is moved by offset" + +# Make sure the address of a global variable is moved by offset. +set new_global_foo_addr [get_var_address global_foo] +gdb_assert { ${new_global_foo_addr} == ${global_foo_addr} + $offset } \ + "global variable foo is moved by offset" + +# Make sure the address of a function is moved by offset. +set new_function_foo_addr [get_var_address function_foo] +gdb_assert { ${new_function_foo_addr} == ${function_foo_addr} + $offset } \ + "function foo is moved by offset" + +# Re-load the object giving an explicit address for .text + +set text [ format "0x%x" [expr ${function_foo_addr} + 0x20000] ] +clean_restart +gdb_test "add-symbol-file $binfile -o $offset $text" \ + "Reading symbols from ${binfile}\.\.\.done\." \ + "add-symbol-file with offset, text address given" \ + "add symbol table from file \".*${testfile}\\.o\" at\[ \t\r\n\]+\.text_addr = ${text}\[\r\n\]+with other sections offset by ${offset}\[\r\n\]+\\(y or n\\) " \ + "y" + +# Make sure function has a different addresses now. +set function_foo_addr [get_var_address function_foo] +gdb_assert { ${function_foo_addr} != ${new_function_foo_addr} } \ + "function foo has a different address" + +# Re-load the object giving an explicit address for .data + +set data [ format "0x%x" [expr ${global_foo_addr} + 0x20000] ] +clean_restart +gdb_test "add-symbol-file $binfile -o $offset -s .data $data" \ + "Reading symbols from ${binfile}\.\.\.done\." \ + "add-symbol-file with offset, data address given" \ + "add symbol table from file \".*${testfile}\\.o\" at\[ \t\r\n\]+\.data_addr = ${data}\[\r\n\]+with other sections offset by ${offset}\[\r\n\]+\\(y or n\\) " \ + "y" + +# Make sure variable has a different addresses now. +set global_foo_addr [get_var_address global_foo] +gdb_assert { ${global_foo_addr} != ${new_global_foo_addr} } \ + "global variable foo has a different address" + # Now try loading the object as an exec-file; we should be able to print # the values of variables after we do this.