diff options
author | Kevin Buettner <kevinb@redhat.com> | 2019-07-03 17:35:21 -0700 |
---|---|---|
committer | Kevin Buettner <kevinb@redhat.com> | 2019-07-27 13:28:56 -0700 |
commit | 2dc80cf8a5799120fd4e00199688f721e7de2a62 (patch) | |
tree | 072f408b268c8d838bcac8f82b37e1aa215758ed /gdb/printcmd.c | |
parent | 567238c956c4e5530bd143bfae9393c7ae5524cd (diff) | |
download | gdb-2dc80cf8a5799120fd4e00199688f721e7de2a62.zip gdb-2dc80cf8a5799120fd4e00199688f721e7de2a62.tar.gz gdb-2dc80cf8a5799120fd4e00199688f721e7de2a62.tar.bz2 |
Restrict use of minsym names when printing addresses in disassembled code
build_address_symbolic contains some code which causes it to
prefer the minsym over the the function symbol in certain cases.
The cases where this occurs are the same as the "certain pathological
cases" that used to exist in find_frame_funname().
This commit largely disables that code; it will only prefer the
minsym when the address of minsym is identical to that of the address
under consideration AND the function address for the symbtab sym is
not the same as the address under consideration.
So, without this change, when using the dw2-ranges-func-lo-cold
executable from the gdb.dwarf2/dw2-ranges-func.exp test, GDB exhibits
the following behavior:
(gdb) x/5i foo_cold
0x40110d <foo+4294967277>: push %rbp
0x40110e <foo+4294967278>: mov %rsp,%rbp
0x401111 <foo+4294967281>: callq 0x401106 <baz>
0x401116 <foo+4294967286>: nop
0x401117 <foo+4294967287>: pop %rbp
On the other hand, still without this change, using the
dw2-ranges-func-hi-cold executable from the same test, GDB
does this instead:
(gdb) x/5i foo_cold
0x401128 <foo_cold>: push %rbp
0x401129 <foo_cold+1>: mov %rsp,%rbp
0x40112c <foo_cold+4>: callq 0x401134 <baz>
0x401131 <foo_cold+9>: nop
0x401132 <foo_cold+10>: pop %rbp
This is inconsistent behavior. When foo_cold is at a lower
address than the function's entry point, the symtab symbol (foo)
is displayed along with a large positive offset which would wrap
around the address space if the address space were only 32 bits wide.
(A later patch fixes this problem by displaying negative offsets.)
This commit makes the behavior uniform for both the "lo-cold" and
"hi-cold" cases:
lo-cold:
(gdb) x/5i foo_cold
0x40110d <foo_cold>: push %rbp
0x40110e <foo-18>: mov %rsp,%rbp
0x401111 <foo-15>: callq 0x401106 <baz>
0x401116 <foo-10>: nop
0x401117 <foo-9>: pop %rbp
hi-cold:
(gdb) x/5i foo_cold
0x401128 <foo_cold>: push %rbp
0x401129 <foo+35>: mov %rsp,%rbp
0x40112c <foo+38>: callq 0x401134 <baz>
0x401131 <foo+43>: nop
0x401132 <foo+44>: pop %rbp
In both cases, the symbol shown for the address at which foo_cold
resides is shown as <foo_cold>. Subsequent offsets are shown as
either negative or positive offsets from the entry pc for foo.
When disassembling a function, care must be taken to NOT display
<+0> as the offset for the second range. For this reason, I found
it necessary to add the "prefer_sym_over_minsym" parameter to
build_address_symbolic. The type of this flag is a bool; do_demangle
ought to be a bool also, so I made this change at the same time.
gdb/ChangeLog:
* valprint.h (build_address_symbolic): Add "prefer_sym_over_minsym"
parameter. Change type of "do_demangle" to bool.
* disasm.c (gdb_pretty_print_disassembler::pretty_print_insn):
Pass suitable "prefer_sym_over_minsym" flag to
build_address_symbolic(). Don't output "+" for negative offsets.
* printcmd.c (print_address_symbolic): Update invocation of
build_address_symbolic to include a "prefer_sym_over_minsym"
flag.
(build_address_symbolic): Add "prefer_sym_over_minsym" parameter.
Restrict cases in which use of minimal symbol is preferred to that
of a found symbol. Update comments.
Diffstat (limited to 'gdb/printcmd.c')
-rw-r--r-- | gdb/printcmd.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 2081704..efe6874 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -529,8 +529,8 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr, int offset = 0; int line = 0; - if (build_address_symbolic (gdbarch, addr, do_demangle, &name, &offset, - &filename, &line, &unmapped)) + if (build_address_symbolic (gdbarch, addr, do_demangle, false, &name, + &offset, &filename, &line, &unmapped)) return 0; fputs_filtered (leadin, stream); @@ -564,7 +564,8 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr, int build_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr, /* IN */ - int do_demangle, /* IN */ + bool do_demangle, /* IN */ + bool prefer_sym_over_minsym, /* IN */ std::string *name, /* OUT */ int *offset, /* OUT */ std::string *filename, /* OUT */ @@ -592,8 +593,10 @@ build_address_symbolic (struct gdbarch *gdbarch, } } - /* First try to find the address in the symbol table, then - in the minsyms. Take the closest one. */ + /* Try to find the address in both the symbol table and the minsyms. + In most cases, we'll prefer to use the symbol instead of the + minsym. However, there are cases (see below) where we'll choose + to use the minsym instead. */ /* This is defective in the sense that it only finds text symbols. So really this is kind of pointless--we should make sure that the @@ -630,7 +633,19 @@ build_address_symbolic (struct gdbarch *gdbarch, if (msymbol.minsym != NULL) { - if (BMSYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL) + /* Use the minsym if no symbol is found. + + Additionally, use the minsym instead of a (found) symbol if + the following conditions all hold: + 1) The prefer_sym_over_minsym flag is false. + 2) The minsym address is identical to that of the address under + consideration. + 3) The symbol address is not identical to that of the address + under consideration. */ + if (symbol == NULL || + (!prefer_sym_over_minsym + && BMSYMBOL_VALUE_ADDRESS (msymbol) == addr + && name_location != addr)) { /* If this is a function (i.e. a code address), strip out any non-address bits. For instance, display a pointer to the @@ -643,8 +658,6 @@ build_address_symbolic (struct gdbarch *gdbarch, || MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline) addr = gdbarch_addr_bits_remove (gdbarch, addr); - /* The msymbol is closer to the address than the symbol; - use the msymbol instead. */ symbol = 0; name_location = BMSYMBOL_VALUE_ADDRESS (msymbol); if (do_demangle || asm_demangle) |