With -m32 -fcf-protection, GCC generates an `endbr32` instruction at the
function entry:
[hjl@gnu-cfl-2 gdb]$ cat /tmp/x.c
int
main(void)
{
return 0;
}
[hjl@gnu-cfl-2 gdb]$ gcc -g -fcf-protection /tmp/x.c -m32
(gdb) b main
Breakpoint 1 at 0x8049176: file /tmp/x.c, line 3.
(gdb) r
Breakpoint 1, main () at /tmp/x.c:3
3 {
(gdb) disass
Dump of assembler code for function main:
=> 0x08049176 <+0>: endbr32
0x0804917a <+4>: push %ebp
0x0804917b <+5>: mov %esp,%ebp
0x0804917d <+7>: mov $0x0,%eax
0x08049182 <+12>: pop %ebp
0x08049183 <+13>: ret
End of assembler dump.
(gdb)
Update i386_analyze_prologue to skip `endbr32`:
(gdb) b main
Breakpoint 1 at 0x804917d: file /tmp/x.c, line 4.
(gdb) r
Breakpoint 1, main () at /tmp/x.c:4
4 return 0;
(gdb) disass
Dump of assembler code for function main:
0x08049176 <+0>: endbr32
0x0804917a <+4>: push %ebp
0x0804917b <+5>: mov %esp,%ebp
=> 0x0804917d <+7>: mov $0x0,%eax
0x08049182 <+12>: pop %ebp
0x08049183 <+13>: ret
End of assembler dump.
(gdb)
Tested with
$ make check RUNTESTFLAGS="--target_board='unix{-m32,}' i386-prologue-skip-cf-protection.exp"
on Fedora 32/x86-64.
2020-0X-YY Victor Collod <vcollod@nvidia.com>
gdb/ChangeLog:
PR gdb/26635
* i386-tdep.c (i386_skip_endbr): Add a helper function to skip endbr.
(i386_analyze_prologue): Call i386_skip_endbr.
gdb/testsuite/ChangeLog:
PR gdb/26635
* gdb.arch/amd64-prologue-skip-cf-protection.exp: Make the test
compatible with i386, and move it to...
* gdb.arch/i386-prologue-skip-cf-protection.exp: ... here.
* gdb.arch/amd64-prologue-skip-cf-protection.c: Move to...
* gdb.arch/i386-prologue-skip-cf-protection.c: ... here.
In this commit:
commit 6108fd1823
Date: Thu Sep 17 11:47:50 2020 -0600
Use htab_up in type copying
A use after free bug was introduced. In compile-object-run.c, in the
function compile_object_run, the code used to look like this:
htab_t copied_types;
/* .... snip .... */
/* OBJFILE may disappear while FUNC_TYPE still will be in use. */
copied_types = create_copied_types_hash (objfile);
func_type = copy_type_recursive (objfile, func_type, copied_types);
htab_delete (copied_types);
/* .... snip .... */
call_function_by_hand_dummy (func_val, NULL, args,
do_module_cleanup, data);
The copied_types table exists on the obstack of objfile, but is
deleted once the call to copy_type_recursive has been completed.
After the change the code now looks like this:
/* OBJFILE may disappear while FUNC_TYPE still will be in use. */
htab_up copied_types = create_copied_types_hash (objfile);
func_type = copy_type_recursive (objfile, func_type, copied_types.get ());
/* .... snip .... */
call_function_by_hand_dummy (func_val, NULL, args,
do_module_cleanup, data);
The copied_types is now a unique_ptr and deleted automatically when it
goes out of scope.
The problem however is that objfile, and its included obstack, may be
deleted by the call to do_module_cleanup, which is called by
call_function_by_hand_dummy.
This means that in the new code the objfile, and its obstack, are
deleted before copied_types is deleted, and as copied_types is on the
objfiles obstack, we are now reading undefined memory.
The solution in this commit is to wrap the call to
create_copied_types_hash and copy_type_recursive into a new static
helper function. The htab_up will then be deleted within the new
function's scope, before objfile is deleted.
This resolves some non-deterministic test failures I was seeing in
gdb.compile/*.exp tests.
gdb/ChangeLog:
* compile/compile-object-run.c (create_copied_type_recursive): New
function.
(compile_object_run): Use new function.
Add gas and opcodes support for two xBPF-exclusive ALU operations:
SDIV (signed division) and SMOD (signed modulo), and add tests for
them in gas.
cpu/
* bpf.cpu (insn-op-code-alu): Add SDIV and SMOD.
(define-alu-insn-bin, daib): Take ISAs as an argument.
(define-alu-instructions): Update calls to daib pmacro with
ISAs; add sdiv and smod.
gas/
* testsuite/gas/bpf/alu-xbpf.d: New file.
* testsuite/gas/bpf/alu-xbpf.s: Likewise.
* testsuite/gas/bpf/alu32-xbpf.d: Likewise.
* testsuite/gas/bpf/alu32-xbpf.d: Likewise.
* testuiste/gas/bpf/bpf.exp: Run new tests.
opcodes/
* bpf-desc.c: Regenerate.
* bpf-desc.h: Likewise.
* bpf-opc.c: Likewise.
* bpf-opc.h: Likewise.
The m32r simulator currently always returns -1 for the register size
after both a fetch and a store. In the fetch case GDB is forgiving of
this, but in the store case GDB treats a return value of -1 as an
error.
This commit updates the m32r simulator to return a valid register size
when fetching or storing a register. This fixes any GDB test that
writes to a register, which will include any GDB test that makes an
inferior call, for example gdb.base/break.exp.
sim/m32r/ChangeLog:
* m32r.c (m32rbf_register_size): New function.
(m32rbf_fetch_register): Use new function.
(m32rbf_store_register): Likewise.
Move windows_core_xfer_shared_libraries() and windows_core_pid_to_str()
to windows-tdep, and use in amd64-windows-tdep.c to handle Cygwin x86_64
core dumps.
v2:
Keep _initialize function at the bottom of the file.
gdb/ChangeLog:
2020-07-01 Jon Turney <jon.turney@dronecode.org.uk>
* windows-tdep.h: Add prototypes.
* i386-windows-tdep.c(windows_core_xfer_shared_libraries): Move.
(i386_windows_core_pid_to_str): Move and rename ...
* windows-tdep.c (windows_core_xfer_shared_libraries): ... to here
(windows_core_pid_to_str): ... and here.
* amd64-windows-tdep.c (amd64_windows_init_abi_common): Register here.
Register a gregset_reg_offset array for Cygwin x86_64 core dump parsing
(this causes the generic i386_iterate_over_regset_sections() '.reg'
section iterator to get installed by i386_gdbarch_init()).
gdb/ChangeLog:
2020-07-01 Jon Turney <jon.turney@dronecode.org.uk>
* amd64-windows-tdep.c(amd64_windows_gregset_reg_offset): Add.
(amd64_windows_init_abi_common): ... and register.
"thread find" with multiple inferiors got broken with the multi-target
work:
Thread 1 "gdb" hit Breakpoint 1, internal_error (...) at ../../src/gdbsupport/errors.cc:51
51 {
(top-gdb) bt
#0 internal_error (file=0xffffd4d0 <error: Cannot access memory at address 0xffffd4d0>, line=0, fmt=0x555556330320 "en_US.UTF-8") at ../../src/gdbsupport/errors.cc:51
#1 0x0000555555bca4c7 in target_thread_name (info=0x555556801290) at ../../src/gdb/target.c:2035
#2 0x0000555555beb07a in thread_find_command (arg=0x7fffffffe08e "1", from_tty=0) at ../../src/gdb/thread.c:1959
#3 0x000055555572ec49 in do_const_cfunc (c=0x555556786bc0, args=0x7fffffffe08e "1", from_tty=0) at ../../src/gdb/cli/cli-decode.c:95
#4 0x0000555555732abd in cmd_func (cmd=0x555556786bc0, args=0x7fffffffe08e "1", from_tty=0) at ../../src/gdb/cli/cli-decode.c:2181
#5 0x0000555555bf1245 in execute_command (p=0x7fffffffe08e "1", from_tty=0) at ../../src/gdb/top.c:664
#6 0x00005555559cad10 in catch_command_errors (command=0x555555bf0c31 <execute_command(char const*, int)>, arg=0x7fffffffe082 "thread find 1", from_tty=0) at ../../src/gdb/main.c:457
#7 0x00005555559cc33d in captured_main_1 (context=0x7fffffffdb60) at ../../src/gdb/main.c:1218
#8 0x00005555559cc571 in captured_main (data=0x7fffffffdb60) at ../../src/gdb/main.c:1243
#9 0x00005555559cc5e8 in gdb_main (args=0x7fffffffdb60) at ../../src/gdb/main.c:1268
#10 0x0000555555623816 in main (argc=17, argv=0x7fffffffdc78) at ../../src/gdb/gdb.c:32
The problem is that we're not switching to the inferior/target before
calling target methods, which trips on an assertion put in place
exactly to catch this sort of problem.
gdb/testsuite/ChangeLog:
PR gdb/26631
* gdb.multi/multi-target-thread-find.exp: New file.
gdb/ChangeLog:
PR gdb/26631
* thread.c (thread_find_command): Switch inferior before calling
target methods.
gdb.multi/multi-target.exp sets up a debug environment with multiple
gdbservers, multiple native processes, and multiple cores, which has
proved useful for exercising a number of multi-target scenarios.
But, as we add more tests to gdb.base/multi-target.exp, it is growing
a bit too large (making a bit cumbersome to debug) and too slow to run
(if you have glibc debug info).
This commit thus splits the multi-target.exp into several testcases,
one per use case. The common setup code is moved to a new
multi-target.exp.tcl file that is included by all the resulting
multi-target testcases.
gdb/testsuite/ChangeLog:
* gdb.multi/multi-target-continue.exp: New file, factored out from
multi-target.exp.
* gdb.multi/multi-target-info-inferiors.exp: New file, factored out from
multi-target.exp.
* gdb.multi/multi-target-interrupt.exp: New file, factored out from
multi-target.exp.
* gdb.multi/multi-target-no-resumed.exp: New file, factored out from
multi-target.exp.
* gdb.multi/multi-target-ping-pong-next.exp: New file, factored out from
multi-target.exp.
* gdb.multi/multi-target.exp.tcl: New file, factored out from
multi-target.exp.
* gdb.multi/multi-target.exp: Delete.
The tests in this script are driven from two lists of expected
results, one of the lists is missing some data so DejaGNU ends up
passing the empty string to gdb_test, which means the test always
passes.
This commit adds the missing expected results into the script. The
tests still pass so there's no change in the results, but we are now
actually checking GDB's behaviour.
gdb/testsuite/ChangeLog:
* gdb.fortran/array-slices.exp: Add missing message data.
Make the testcase work when built with a C++ compiler.
gdb/testsuite/ChangeLog:
* gdb.python/py-frame-inline.exp: Adjust to optionally expect a
full prototype.
Fixes:
src/gdb/testsuite/gdb.base/sizeof.c:54:9: error: cannot initialize a variable of type 'char *' with an lvalue of type 'void *'
... when the testcase is built with a C++ compiler.
gdb/testsuite/ChangeLog:
* gdb.base/sizeof.c (fill): Add cast.
Make these testcases work when compiled as C++ programs.
These testcases use the alias attribute, which requires passing in the
target function's mangled name in C++. To avoid having to figure out
how the functions are mangled, explicitly specify a linkage name.
This is preferred over 'extern "C"' because that doesn't work with
static functions.
gdb/testsuite/ChangeLog:
* gdb.base/prologue.c [__cplusplus] (marker): Explicitly specify
linkage name.
* gdb.base/prologue.exp: Use print /d.
* gdb.base/symbol-alias.exp: Handle C++ output.
* gdb.base/symbol-alias2.c: Handle C++ output.
[__cplusplus] (func): Explicitly specify linkage name.
This adjusts gdb.python/py-nested-maps.c to make it buildable as C++ program.
key_t is renamed because of:
src/gdb/testsuite/gdb.python/py-nested-maps.c:23:8: error: definition of type 'key_t' conflicts with typedef of the same name
struct key_t
^
/usr/include/x86_64-linux-gnu/sys/types.h:121:17: note: 'key_t' declared here
typedef __key_t key_t;
^
gdb/testsuite/ChangeLog:
* gdb.python/py-nested-maps.c (struct key_t): Rename to...
(struct my_key_t): ... this. Adjust all references.
(struct value_t): Rename to ...
(struct my_value_t): ... this. Adjust all references.
(create_map, add_map_element, create_map_map)
(add_map_map_element): Add casts.
This adjusts:
gdb.python/{py-framefilter-mi,py-framefilter}.c
to make them buildable as C++ programs.
gdb/testsuite/ChangeLog:
* gdb.python/py-framefilter-mi.c (funca): Add casts.
* gdb.python/py-framefilter.c.c (funca, func2): Add casts.
This adjusts:
gdb.base/{exprs,ptype,ptype1,setvar,whatis}.c,
to make them buildable as C++ programs.
gdb/testsuite/ChangeLog:
* gdb.base/exprs.c: Replace 'this' with 'self' throughout.
* gdb.base/ptype.c: : Replace 'this' with 'self' throughout.
(charfoo, intfoo): Define full prototype.
* gdb.base/ptype1.c (charfoo): Define full prototype.
* gdb.base/setvar.c: Replace 'this' with 'self' throughout.
* gdb.base/whatis.c: Replace 'this' with 'self' throughout.
Adjust gdb.base/charset.{c,exp} so that the testcase works when
compiled as a C++ program.
wchar_t is built-in in C++, so don't make a phony typedef.
The "print /d" is so that we also get "1" instead of "true" in C++
mode.
gdb/testsuite/ChangeLog:
* gdb.base/charset.c [__cplusplus] (wchar_t, char16_t, char32_t):
Don't define.
(utf_32_string): Compile for both C and C++.
* gdb.base/charset.exp: Use "print /d".
Adjust gdb.base/watchpoint.c so that it can be built as a C++ program.
Fixes:
gdb compile failed, src/gdb/testsuite/gdb.base/watchpoint.c:33:16: error: initializer-string for array of chars is too long [-fpermissive]
33 | char buf[30] = "testtesttesttesttesttesttestte";
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/gdb/testsuite/gdb.base/watchpoint.c:62:14: error: expected unqualified-id before 'nullptr'
62 | struct foo5 *nullptr;
| ^~~~~~~
gdb/testsuite/ChangeLog:
* gdb.base/watchpoint.c (buf): Make it 31 bytes.
(nullptr): Rename to ...
(null_ptr): ... this.
* gdb.base/watchpoint.exp: Adjust to rename.
Adjust gdb.base/printcmds.c to make it buildable as a C++ program.
gdb/testsuite/ChangeLog:
* gdb.base/printcmds.c (three, flag_enum_without_zero)
(three_not_flag): Add casts.
Adjust gdb.base/examine-backward.exp to let the testcase build and run
as a C++ program, built with either G++ or Clang++.
The change to use unsigned char instead of plain char is to avoid
narrowing warnings:
gdb compile failed, src/gdb/testsuite/gdb.base/examine-backward.c:55:1: error: narrowing conversion of '227' from 'int' to 'char' [-Wnarrowing]
55 | };
| ^
gdb/testsuite/ChangeLog:
* gdb.base/examine-backward.c (Barrier, TestStrings): Now unsigned
char array.
(main): Add references to Barrier, TestStrings, TestStringsH and
TestStringsW.
* gdb.base/examine-backward.exp: Issue "set print asm-demangle on"
and expect a full prototype in C++.
Adjust gdb.base/nested-addr.exp to let the testcase build and run as a
C++ program. "print /d" is used so we get "= 1" instead of "= true"
in C++ mode.
gdb/testsuite/ChangeLog:
* gdb.base/nested-addr.c (main): Add cast.
* gdb.base/nested-addr.exp: Use "print /d".
Some adjustments to make gdb.base/break.exp work when compiled as a
C++ program. Passes cleanly with Clang++, but not with G++. The
latter puts a breakpoint at an unexpected line in one case. It seems
like a bug that gcc and g++ behave differently here.
gdb/testsuite/ChangeLog:
* gdb.base/break.exp (func): New. Use it throughout when
expecting a function name.
This makes the testcase work when compiled with C++ compiler.
We need #include <string.h> for memset.
gdb/testsuite/ChangeLog:
* gdb.base/find.c: Include <string.h>.
(init_bufs): Add cast.
* gdb.base/find.exp: Issue "set print asm-demangle on".
While working on something else, I noticed that tdesc_data_cleanup
took a void* parameter. Looking more into this, I found that
tdesc_use_registers expected a transfer of ownership.
I think it's better to express this sort of thing via the type system,
when possible. This patch changes tdesc_data_alloc to return a unique
pointer, changes tdesc_use_registers to accept an rvalue reference,
and then adapts all the users.
Note that a deleter structure is introduced to avoid having to move
tdesc_arch_data to the header file.
2020-09-17 Tom Tromey <tromey@adacore.com>
* tic6x-tdep.c (tic6x_gdbarch_init): Update.
* target-descriptions.h (struct tdesc_arch_data_deleter): New.
(tdesc_arch_data_up): New typedef.
(tdesc_use_registers, tdesc_data_alloc): Update.
(tdesc_data_cleanup): Don't declare.
* target-descriptions.c (tdesc_data_alloc): Return a
tdesc_arch_data_up.
(tdesc_arch_data_deleter::operator()): Rename from
tdesc_data_cleanup. Change argument type.
(tdesc_use_registers): Change early_data to an rvalue reference.
(tdesc_use_registers): Don't use delete.
* sparc-tdep.c (sparc32_gdbarch_init): Update.
* s390-tdep.c (s390_gdbarch_init): Update.
* rx-tdep.c (rx_gdbarch_init): Update.
* rs6000-tdep.c (rs6000_gdbarch_init): Update.
* riscv-tdep.c (riscv_gdbarch_init): Update.
* or1k-tdep.c (or1k_gdbarch_init): Update.
* nios2-tdep.c (nios2_gdbarch_init): Update.
* nds32-tdep.c (nds32_gdbarch_init): Update.
* mips-tdep.c (mips_gdbarch_init): Update.
* microblaze-tdep.c (microblaze_gdbarch_init): Update.
* m68k-tdep.c (m68k_gdbarch_init): Update.
* i386-tdep.c (i386_gdbarch_init): Update.
* arm-tdep.c (arm_gdbarch_init): Update.
* arc-tdep.c (arc_tdesc_init): Update.
(arc_gdbarch_init): Update.
* aarch64-tdep.c (aarch64_gdbarch_init): Update.
DebugBreakProcess starts a new thread in the target process with the
entry point DbgUiRemoteBreakin, where an int3 triggers a breakpoint
exception for gdb.
But this uses DbgUiRemoteBreakin of the 64bit ntdll.dll even for
WOW64 processes.
It stops in 64bit code, Wow64GetThreadContext reports a wrong pc without
the int3, and gdb lets the target process continue.
So this uses DbgUiRemoteBreakin of the 32bit ntdll.dll as the thread
entry point for WOW64 processes instead.
gdb/ChangeLog:
2020-09-17 Hannes Domani <ssbssa@yahoo.de>
* windows-nat.c (ctrl_c_handler): Use 32bit DbgUiRemoteBreakin
for WOW64 processes.
This changes dwarf2/read.c to use htab_up rather than explicit calls
to htab_delete.
gdb/ChangeLog
2020-09-17 Tom Tromey <tom@tromey.com>
* dwarf2/read.c (compute_compunit_symtab_includes): Use htab_up.
This changes typedef_hash_table to use htab_up rather than explicit
calls to htab_delete.
gdb/ChangeLog
2020-09-17 Tom Tromey <tom@tromey.com>
* typeprint.h (class typedef_hash_table) <~typedef_hash_table>:
Remove.
<m_table>: Now htab_up.
* typeprint.c (typedef_hash_table::recursively_update)
(typedef_hash_table::add_template_parameters)
(typedef_hash_table::typedef_hash_table): Update.
(typedef_hash_table::~typedef_hash_table): Remove.
(typedef_hash_table::typedef_hash_table)
(typedef_hash_table::find_global_typedef)
(typedef_hash_table::find_typedef): Update.
This changes target-descriptions.c to use htab_up rather than explicit
calls to htab_delete.
gdb/ChangeLog
2020-09-17 Tom Tromey <tom@tromey.com>
* target-descriptions.c (tdesc_use_registers): Use htab_up.
This changes linespec.c to use htab_up rather than explicit calls to
htab_delete. Note that a use still exists in this file, because
linespec_state hasn't been converted to have a real destructor.
gdb/ChangeLog
2020-09-17 Tom Tromey <tom@tromey.com>
* linespec.c (class decode_compound_collector)
<~decode_compound_collector>: Remove.
<m_unique_syms>: Now htab_up.
(decode_compound_collector::operator ()): Update.
(class symtab_collector) <~symtab_collector>: Remove.
<m_symtab_table>: Now htab_up.
(symtab_collector::operator ()): Update.
This changes filename_seen_cache to use htab_up, rather than explicit
calls to htab_delete.
gdb/ChangeLog
2020-09-17 Tom Tromey <tom@tromey.com>
* filename-seen-cache.c (filename_seen_cache::filename_seen_cache)
(filename_seen_cache::clear): Update.
(~filename_seen_cache): Remove.
(filename_seen_cache::seen): Update.
* filename-seen-cache.h (class filename_seen_cache) <m_tab>: Now
htab_up.
<~filename_seen_cache>: Remove.
<traverse>: Update.
This changes completion_tracker to use htab_up, rather than explicit
calls to htab_delete.
gdb/ChangeLog
2020-09-17 Tom Tromey <tom@tromey.com>
* completer.c (completion_tracker::discard_completions)
(completion_tracker::~completion_tracker)
(completion_tracker::maybe_add_completion)
(completion_tracker::remove_completion)
(completion_tracker::recompute_lowest_common_denominator)
(completion_tracker::build_completion_result): Update.
* completer.h (class completion_tracker) <have_completions>:
Update.
<m_entries_hash>: Now htab_up.
This changes breakpoint.c to use htab_up rather than an explicit
htab_delete. This simplifies the code somewhat.
gdb/ChangeLog
2020-09-17 Tom Tromey <tom@tromey.com>
* breakpoint.c (ambiguous_names_p): Use htab_up.
This changes auto-load.c to use htab_up, rather than manually calling
htab_delete.
gdb/ChangeLog
2020-09-17 Tom Tromey <tom@tromey.com>
* auto-load.c (struct auto_load_pspace_info)
<~auto_load_pspace_info, auto_load_pspace_info>: Remove.
<loaded_script_files, loaded_script_texts>: Change type to
htab_up.
(~auto_load_pspace_info) Remove.
(init_loaded_scripts_info, maybe_add_script_file)
(maybe_add_script_text, auto_load_info_scripts): Update.
c-exp.y:name_obstack is not static, but should be. This patch makes
the change. Tested by rebuilding.
gdb/ChangeLog
2020-09-17 Tom Tromey <tromey@adacore.com>
* c-exp.y (name_obstack): Now static.
The decode of c.sdsp was incorrectly claiming to be a 4-byte store
instead of an 8-byte store.
gdb/ChangeLog:
* riscv-tdep.c (riscv-insn::decode): Fix recorded insn type.
The disassembler function should return a valid disassembler function
even when there is no BFD present. This is implied (I believe) by the
comment in dis-asm.h which says the BFD may be NULL. Further, it
makes sense when considering that the disassembler is used in GDB, and
GDB may connect to a target and perform debugging even without a BFD
being supplied.
This commit makes the csky_get_disassembler function return the
default disassembler configuration when no bfd is supplied, this is
the same default configuration as is used when a BFD is supplied, but
the BFD has no attributes section.
Before the change configuring GDB with --enable-targets=all and
running the tests gdb.base/all-architectures-2.exp results in many
errors, but after this change there are no failures.
opcodes/ChangeLog:
* csky-dis.c (csky_get_disassembler): Don't return NULL when there
is no BFD.