[PATCH v3 1/4] Add an optional offset option to the "symbol-file" command

Petr Tesarik
2018-06-27T12:14:57Z

If the main file is relocated at runtime, all symbols are offset by
a fixed amount. Let the user specify this offset when loading a
symbol file.

gdb/ChangeLog:
2018-06-27 Petr Tesarik <ptesarik@suse.com>

* symfile.c (symbol_file_command, symbol_file_add_main_1)
(_initialize_symfile): Add option "-o" to symbol-file to add an
offset to each section of the symbol file.

gdb/doc/ChangeLog:
2018-06-27 Petr Tesarik <ptesarik@suse.com>

* gdb.texinfo (Files): Document "symbol-file -o offset".

gdb/testsuite/ChangeLog:
2018-06-27 Petr Tesarik <ptesarik@suse.com>

* gdb.base/relocate.exp: Add test for "symbol-file -o ".

Note: Documentation already approved by Eli Zaretskii <eliz@gnu.org>

---
gdb/ChangeLog | 6 ++++++
gdb/NEWS | 3 +++
gdb/doc/ChangeLog | 4 ++++
gdb/doc/gdb.texinfo | 7 ++++++-
gdb/symfile.c | 24 ++++++++++++++++++------
gdb/testsuite/ChangeLog | 4 ++++
gdb/testsuite/gdb.base/relocate.exp | 24 ++++++++++++++++++++++++
7 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d4ae16c584..dd52e7d7b8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2018-06-27 Petr Tesarik <ptesarik@suse.com>
+
+ * symfile.c (symbol_file_command, symbol_file_add_main_1)
+ (_initialize_symfile): Add option "-o" to symbol-file to add an
+ offset to each section of the symbol file.
+
2018-06-26 Joel Brobecker <brobecker@adacore.com>

* windows-nat.c (do_windows_fetch_inferior_registers): Rename
diff --git a/gdb/NEWS b/gdb/NEWS
index 13da2f1d4e..101746567a 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,9 @@

*** Changes since GDB 8.1

+* The 'symbol-file' command now accepts an '-o' option to add a relative
+ offset to all sections.
+
* The endianness used with the 'set endian auto' mode in the absence of
an executable selected for debugging is now the last endianness chosen
either by one of the 'set endian big' and 'set endian little' commands
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index ade1799b06..0e57166fe3 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,7 @@
+2018-06-27 Petr Tesarik <ptesarik@suse.com>
+
+ * gdb.texinfo (Files): Document "symbol-file -o offset".
+
2018-06-14 Tom de Vries <tdevries@suse.de>

* gdb.texinfo (Background Execution): Add @cindex for '&'.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index a6bad13d9d..328256236e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18823,11 +18823,16 @@ if necessary to locate your program. Omitting @var{filename} means to
discard information on the executable file.

@kindex symbol-file
-@item symbol-file @r{[} @var{filename} @r{]}
+@item symbol-file @r{[} @var{filename} @r{[} -o @var{offset} @r{]]}
Read symbol table information from file @var{filename}. @code{PATH} is
searched when necessary. Use the @code{file} command to get both symbol
table and program to run from the same file.

+If an optional @var{offset} is specified, it is added to the start
+address of each section in the symbol file. This is useful if the
+program is relocated at runtime, such as the Linux kernel with kASLR
+enabled.
+
@code{symbol-file} with no argument clears out @value{GDBN} information on your
program's symbol table.

diff --git a/gdb/symfile.c b/gdb/symfile.c
index f8177ea8b1..461f60d074 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -87,7 +87,7 @@ int readnever_symbol_files; /* Never read full symbols. */
/* Functions this file defines. */

static void symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags,
- objfile_flags flags);
+ objfile_flags flags, CORE_ADDR reloff);

static const struct sym_fns *find_sym_fns (bfd *);

@@ -1225,16 +1225,18 @@ symbol_file_add (const char *name, symfile_add_flags add_flags,
void
symbol_file_add_main (const char *args, symfile_add_flags add_flags)
{
- symbol_file_add_main_1 (args, add_flags, 0);
+ symbol_file_add_main_1 (args, add_flags, 0, 0);
}

static void
symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags,
- objfile_flags flags)
+ objfile_flags flags, CORE_ADDR reloff)
{
add_flags |= current_inferior ()->symfile_flags | SYMFILE_MAINLINE;

- symbol_file_add (args, add_flags, NULL, flags);
+ struct objfile *objfile = symbol_file_add (args, add_flags, NULL, flags);
+ if (reloff != 0)
+ objfile_rebase (objfile, reloff);

/* Getting new symbols may change our opinion about
what is frameless. */
@@ -1551,6 +1553,7 @@ symbol_file_command (const char *args, int from_tty)
symfile_add_flags add_flags = 0;
char *name = NULL;
bool stop_processing_options = false;
+ CORE_ADDR offset = 0;
int idx;
char *arg;

@@ -1571,6 +1574,14 @@ symbol_file_command (const char *args, int from_tty)
flags |= OBJF_READNOW;
else if (strcmp (arg, "-readnever") == 0)
flags |= OBJF_READNEVER;
+ else if (strcmp (arg, "-o") == 0)
+ {
+ arg = built_argv[++idx];
+ if (arg == NULL)
+ error (_("Missing argument to -o"));
+
+ offset = parse_and_eval_address (arg);
+ }
else if (strcmp (arg, "--") == 0)
stop_processing_options = true;
else
@@ -1582,7 +1593,7 @@ symbol_file_command (const char *args, int from_tty)

validate_readnow_readnever (flags);

- symbol_file_add_main_1 (name, add_flags, flags);
+ symbol_file_add_main_1 (name, add_flags, flags, offset);
}
}

@@ -3774,7 +3785,8 @@ symbolic debug information."

c = add_cmd ("symbol-file", class_files, symbol_file_command, _("\
Load symbol table from executable file FILE.\n\
-Usage: symbol-file [-readnow | -readnever] FILE\n\
+Usage: symbol-file [-readnow | -readnever] [-o OFF] FILE\n\
+OFF is an optional offset which is added to each section address.\n\
The `file' command can also load symbol tables, as well as setting the file\n\
to execute.\n" READNOW_READNEVER_HELP), &cmdlist);
set_cmd_completer (c, filename_completer);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index b2901dbcc5..d9900d3e86 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2018-06-27 Petr Tesarik <ptesarik@suse.com>
+
+ * gdb.base/relocate.exp: Add test for "symbol-file -o ".
+
2018-06-26 Tom Tromey <tom@tromey.com>

PR rust/22574:
diff --git a/gdb/testsuite/gdb.base/relocate.exp b/gdb/testsuite/gdb.base/relocate.exp
index 89f2fffcd9..77f6a88159 100644
--- a/gdb/testsuite/gdb.base/relocate.exp
+++ b/gdb/testsuite/gdb.base/relocate.exp
@@ -196,6 +196,30 @@ if { "${function_foo_addr}" == "${new_function_foo_addr}" } {
pass "function foo has a different address"
}

+# Load the object using symbol-file with an offset and check that
+# all addresses are moved by that offset.
+
+set offset 0x10000
+clean_restart
+gdb_test "symbol-file -o $offset $binfile" \
+ "Reading symbols from ${binfile}\.\.\.done\." \
+ "symbol-file with offset"
+
+# 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"
+
# Now try loading the object as an exec-file; we should be able to print
# the values of variables after we do this.

--
2.16.4