aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2021-03-31Include string.h in bfd.h and delete LITMEMCPY, LITSTRCPYAlan Modra5-15/+13
This fixes the issue that startswith depends on strncpy being declared, and not all projects using bfd.h include string.h before bfd.h. I've also deleted some macros that don't find much use anywhere. bfd/ * bfd-in.h: Include string.h. (LITMEMCPY, LITSTRCPY): Delete. * bfd-in2.h: Regenerate. binutils/ * prdbg.c (pr_function_type): Replace LITSTTCPY with strcpy.
2021-03-31Automatic date update in version.inGDB Administrator1-1/+1
2021-03-30gdb/dwarf: disable per-BFD resource sharing for -readnow objfilesSimon Marchi6-46/+122
New in v2: - Disable sharing only for -readnow objfiles, not all objfiles. As described in PR 27541, we hit an internal error when loading a binary the standard way and then loading it with the -readnow option: $ ./gdb -nx -q --data-directory=data-directory ~/a.out -ex "set confirm off" -ex "file -readnow ~/a.out" Reading symbols from /home/simark/a.out... Reading symbols from ~/a.out... /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8098: internal-error: void create_all_comp_units(dwarf2_per_objfile*): Assertion `per_objfile->per_bfd->all_comp_units.empty ()' failed. This is a recurring problem that exposes a design issue in the DWARF per-BFD sharing feature. Things work well when loading a binary with the same method (with/without index, with/without readnow) twice in a row. But they don't work so well when loading a binary with different methods. See this previous fix, for example: efb763a5ea35 ("gdb: check for partial symtab presence in dwarf2_initialize_objfile") That one handled the case where the first load is normal (uses partial symbols) and the second load uses an index. The problem is that when loading an objfile with a method A, we create a dwarf2_per_bfd and some dwarf2_per_cu_data and initialize them with the data belonging to that method. When loading another obfile sharing the same BFD but with a different method B, it's not clear how to re-use the dwarf2_per_bfd/dwarf2_per_cu_data previously created, because they contain the data specific to method A. I think the most sensible fix would be to not share a dwarf2_per_bfd between two objfiles loaded with different methods. That means that two objfiles sharing the same BFD and loaded the same way would share a dwarf2_per_bfd. Two objfiles sharing the same BFD but loaded with different methods would use two different dwarf2_per_bfd structures. However, this isn't a trivial change. So to fix the known issue quickly (including in the gdb 10 branch), this patch just disables all dwarf2_per_bfd sharing for objfiles using READNOW. Generalize the gdb.base/index-cache-load-twice.exp test to test all the possible combinations of loading a file with partial symtabs, index and readnow. Move it to gdb.dwarf2, since it really exercises features of the DWARF reader. gdb/ChangeLog: PR gdb/27541 * dwarf2/read.c (dwarf2_has_info): Don't share dwarf2_per_bfd with objfiles using READNOW. gdb/testsuite/ChangeLog: PR gdb/27541 * gdb.base/index-cache-load-twice.exp: Remove. * gdb.base/index-cache-load-twice.c: Remove. * gdb.dwarf2/per-bfd-sharing.exp: New. * gdb.dwarf2/per-bfd-sharing.c: New. Change-Id: I9ffcf1e136f3e75242f70e4e58e4ba1fd3083389
2021-03-30[gdb/testsuite] Add missing .debug_abbrev terminator in dw2-cu-size.STom de Vries2-0/+8
Since commit 27012aba8a6 "Remove Irix 6 workaround from DWARF abbrev reader" we have: ... (gdb) file dw2-cu-size^M Reading symbols from dw2-cu-size...^M DW_FORM_strp pointing outside of .debug_str section [in module dw2-cu-size]^M (No debugging symbols found in dw2-cu-size)^M (gdb) ptype noloc^M No symbol table is loaded. Use the "file" command.^M (gdb) FAIL: gdb.dwarf2/dw2-cu-size.exp: ptype noloc ... The problem is a missing .debug_abbrev terminator in dw2-cu-size.S, which causes the .debug_abbrev contribution to be merged with the next: ... Number TAG (0x9b) 1 DW_TAG_compile_unit [has children] DW_AT_name DW_FORM_string DW_AT_producer DW_FORM_string DW_AT_language DW_FORM_data1 DW_AT value: 0 DW_FORM value: 0 2 DW_TAG_variable [no children] DW_AT_name DW_FORM_string DW_AT_type DW_FORM_ref4 DW_AT_external DW_FORM_flag DW_AT value: 0 DW_FORM value: 0 3 DW_TAG_base_type [no children] DW_AT_name DW_FORM_string DW_AT_byte_size DW_FORM_data1 DW_AT_encoding DW_FORM_data1 DW_AT value: 0 DW_FORM value: 0 4 DW_TAG_const_type [no children] DW_AT_type DW_FORM_ref_udata DW_AT value: 0 DW_FORM value: 0 1 DW_TAG_compile_unit [has children] DW_AT_producer DW_FORM_strp DW_AT_language DW_FORM_data1 DW_AT_name DW_FORM_strp DW_AT_comp_dir DW_FORM_strp DW_AT_low_pc DW_FORM_addr DW_AT_high_pc DW_FORM_data8 DW_AT_stmt_list DW_FORM_sec_offset DW_AT value: 0 DW_FORM value: 0 ... and consequently, abbreviation code 1 no longer refers to a unique entry. The eventually causes us to access the first attribute of this DIE: ... <0><124>: Abbrev Number: 1 (DW_TAG_compile_unit) <125> DW_AT_name : file1.txt <12f> DW_AT_producer : GNU C 3.3.3 <13b> DW_AT_language : 1 (ANSI C) ... which has form DW_FORM_string, using DW_FORM_strp. Fix this by adding the missing .debug_abbrev terminator in dw2-cu-size.S. gdb/testsuite/ChangeLog: 2021-03-30 Tom de Vries <tdevries@suse.de> PR testsuite/27604 * gdb.dwarf2/dw2-cu-size.S: Add missing .debug_abbrev terminator.
2021-03-30Fix inverted logic bugLuis Machado2-5/+10
During reviews, I changed the success/failure variables from int to bool, but missed updating the code in a couple spots. Given the logic inversion, the gdbserver code fails instead of succeeding. Fixed with the following patch. Seems fairly obvious, so I'll push it soon. gdbserver/ChangeLog: 2021-03-30 Luis Machado <luis.machado@linaro.org> * server.cc (handle_general_set, handle_query): Update variable to bool and fix verification logic.
2021-03-30x86: drop seg_entryJan Beulich6-66/+63
Use struct reg_entry instead for most purposes, with a separate array holding just the respective opcode prefix bytes.
2021-03-30x86: drop REGNAM_{AL,AX,EAX}Jan Beulich5-8/+21
The former two are unused anyway. And having such constants isn't very helpful either, when they live in a place where updating the register table wouldn't even allow noticing the need to adjust these constants.
2021-03-30x86: adjust st(<N>) parsingJan Beulich6-18/+42
st(1) ... st(7) will never be looked up in the hash table, so there's no point inserting the entries. It's also not really necessary to do a 2nd hash lookup after parsing the register number, nor is there a real reason for having both st and st(0) entries. Plus we can easily do away with the need for st to be first in the table.
2021-03-30x86: integrate rc_op into struct _i386_insnJan Beulich2-43/+50
There's no need for the extra level of indirection and the extra storage needed for the pointer, pointing from one piece of static data to another. Key checking of rounding being in effect off of the type field of the structure instead.
2021-03-30x86: integrate broadcast_op into struct _i386_insnJan Beulich2-43/+52
There's no need for the extra level of indirection and the extra storage needed for the pointer, pointing from one piece of static data to another. Key checking of broadcast being in effect off of the type field of the structure instead.
2021-03-30x86: integrate mask_op into struct _i386_insnJan Beulich2-55/+69
There's no need for the extra level of indirection and the extra storage needed for the pointer, pointing from one piece of static data to another. Key checking of masking being in effect off of the register field of the structure instead.
2021-03-30x86: make swap_2_operands() have unsigned parametersJan Beulich2-12/+25
All callers pass unsigned values (in some cases by virtue of passing non-negative literal numbers). This in turn requires struct {Mask,RC,Broadcast}_Operation's "operand" fields to become unsigned, in turn allowing to reduce the amount of casting needed (the two new casts that are necessary cast _to_ "unsigned" instead of _from_, as that's the form that'll never case undefined behavior).
2021-03-30asan: linker.c:2294:8: runtime error: load of value 253Alan Modra2-3/+8
Seen after converting bfd_boolean to bool. mmix +FAIL: ld-mmix/zeroehmmo ./ld-new -L/home/alan/src/binutils-gdb/ld/testsuite/ld-mmix -m mmo -Ttext 0xa00 -T /home/alan/src/binutils-gdb/ld/testsuite/ld-mmix/zeroeh.ld -o tmpdir/dump tmpdir/x.o tmpdir/y.o /home/alan/src/binutils-gdb/bfd/linker.c:2294:8: runtime error: load of value 253, which is not a valid value for type '_Bool' * elflink.c (elf_link_add_object_symbols): Don't set h->indx unless is_elf_hash_table.
2021-03-30PR27625, powerpc64 gold __tls_get_addr callsAlan Modra2-53/+197
This patch supports linking powerpc64 glibc with gold, specifically the __tls_get_addr call in elf/dl-sym.c. That call lacks marker relocations tying it to the arg setup instructions, but the arg setup insns are also contructed lacking the usual relocations on a Global Dynamic TLS code sequence. So there is no chance that anything in that sequence might be wrongly edited by the linker. In fact, the aim of linking glibc could have been supported by simply omitting the error whenever TLS optimisation is disabled, as it is when linking a shared library. The patch goes further than that, disabling TLS GD and LD sequence optimisation on a per-object basis for object files lacking marker relocs. PR gold/27625 * powerpc.cc (Powerpc_relobj): Add no_tls_marker_, tls_marker_, and tls_opt_error_ variables and accessors. (Target_powerpc::Scan::local, global): Call set_tls_marker and set_no_tls_marker for GD and LD code sequence relocations. (Target_powerpc::Relocate::relocate): Downgrade the "lacks marker reloc" error to a warning when safe to do so, and omit the error entirely if not optimising TLS sequences. Do not optimise GD and LD sequences for objects lacking marker relocs. (Target_powerpc::relocate_relocs): Heed no_tls_marker here too.
2021-03-30Automatic date update in version.inGDB Administrator1-1/+1
2021-03-29Remove parameter from language_infoTom Tromey4-14/+15
I noticed that language_info is only ever called with a value of '1'. This patch removes the parameter. 2021-03-29 Tom Tromey <tromey@adacore.com> * top.c (check_frame_language_change): Update. * language.c (language_info): Remove parameter. * language.h (language_info): Remove parameter.
2021-03-29Don't pass empty options to GCCLuis Machado2-1/+11
On aarch64-linux, I noticed the compile command didn't work at all. It always gave the following error: aarch64-linux-gnu-g++: error: : No such file or directory Turns out we're passing an empty argv entry to GCC (because aarch64 doesn't have a -m64 option), and GCC's behavior is to think that is a file it needs to open. One can reproduce it like so: gcc "" "" "" "" gcc: error: : No such file or directory gcc: error: : No such file or directory gcc: error: : No such file or directory gcc: error: : No such file or directory gcc: fatal error: no input files compilation terminated. The solution is to check for an empty string and skip adding that to argv. Regression tested on aarch64-linux/Ubuntu 18.04/20.04. gdb/ChangeLog: 2021-03-29 Luis Machado <luis.machado@linaro.org> * compile/compile.c (get_args): Don't add empty argv entries.
2021-03-29Fix memory tagging section typeLuis Machado2-1/+6
It was reported to me that on Ubuntu 14.04 (fairly old) the documentation fails to build with the following: gdb/doc/gdb.texinfo:10888: warning: node `Memory' is up for `Memory Tagging' in sectioning but not in menu gdb/doc/gdb.texinfo:10693: node `Memory' lacks menu item for `Memory Tagging' despite being its Up target Makefile:491: recipe for target 'gdb.info' failed make[3]: *** [gdb.info] Error 1 This doesn't seem to happen on Ubuntu 18.04/20.04, but it does make sense. Fix this by turning @subsection into a @section and adding the "Memory Tagging" entry to the menu. gdb/doc/ChangeLog: 2021-03-29 Luis Machado <luis.machado@linaro.org> * gdb.textinfo (Memory Tagging): Make it a @section.
2021-03-29testsuite, mi: avoid a clang bug in 'user-selected-context-sync.exp'Tankut Baris Aktemur2-2/+13
This test causes several timeouts for Clang, taking too long time to finish. The reason is, for an infinite loop of the form while(1); /* suppose this is line 30. */ Clang generates code that looks like 0x00000000004004d4 <+4>: jmp 0x4004d9 <loop+9> 0x00000000004004d9 <+9>: jmp 0x4004d9 <loop+9> So, the real loop is the instruction at address 0x4004d9. But a breakpoint that's defined at the loop line (assume line 30 in this case) is inserted at address 0x4004d4. (gdb) break 30 Breakpoint 1 at 0x4004d4: file test.c, line 30. Therefore, continuing a thread that was spinning on the loop does not hit the breakpoint. The bug is reported at https://bugs.llvm.org/show_bug.cgi?id=49614 Tweak the infinite loop to spin on a variable to avoid this bug. The test is unrelated to the bug. gdb/testsuite/ChangeLog: 2021-03-29 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.mi/user-selected-context-sync.exp: Spin on a variable in the infinite loop to avoid a Clang bug.
2021-03-29Restore procfs.c compilationRainer Orth2-2/+11
Since c8fbd44a018a9923f906bfd2be5489caa87b602a (gdb: remove target_is_pushed free function), procfs.c compilation is broken, which went unnoticed for lack of functioning buildbots: /vol/src/gnu/gdb/hg/master/dist/gdb/procfs.c: In member function 'virtual void procfs_target::attach(const char*, int)': /vol/src/gnu/gdb/hg/master/dist/gdb/procfs.c:1772:8: error: 'inf' was not declared in this scope; did you mean 'info'? 1772 | if (!inf->target_is_pushed (this)) | ^~~ | info /vol/src/gnu/gdb/hg/master/dist/gdb/procfs.c: In member function 'virtual void procfs_target::create_inferior(const char*, const string&, char**, int)': /vol/src/gnu/gdb/hg/master/dist/gdb/procfs.c:2865:8: error: 'inf' was not declared in this scope; did you mean 'info'? 2865 | if (!inf->target_is_pushed (this)) | ^~~ | info Fixed by defining inf. Tested on amd64-pc-solaris2.11 and sparcv9-sun-solaris2.11. 2021-03-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> gdb: * procfs.c (procfs_target::attach): Define inf. Use it. (procfs_target::create_inferior): Likewise.
2021-03-29x86: move some opcode table entriesJan Beulich3-489/+500
For a long time there hasn't been a need anymore to keep together all templates with identical mnemonics. Move the MOVQ and MOVABS ones next to their MOV counterparts. Move the string forms of CMPSD and MOVSD next to their CMPS / MOVS counterparts. Re-arrange what so fgar was the SSE3 section. This makes reasonably obvious that MONITOR/MWAIT aren't suitable to cover by CpuSSE3, but adjusting this is left for another time.
2021-03-29x86: VPSADBW's source operands are also commutativeJan Beulich7-8/+22
In commit 79dec6b7baa2 ("x86-64: optimize certain commutative VEX-encoded insns") I missed the fact that there being subtraction involved here doesn't matter, as absolute differences get summed up.
2021-03-29x86: fold SSE2AVX and their base MMX/SSE templatesJan Beulich4-924/+645
This way not only the overall (source) table size shrinks by quite a bit and the risk of related templates going out of sync with one another gets lowered, but also (dis)similarities between neighboring templates become easier to spot. Note that for certain SSE2AVX templates this results in benign attribute changes: - LDMXCSR and STMXCSR: NoAVX gets set, - MOVMSKPS, PMOVMSKB, PEXTR{B,W} (register destination), and PINSR{B,W} (register source): IgnoreSize and NoRex64 get set, - CVT{DQ,PS}2PD, CVTSD2SS, MOVMSKPD, MOVDDUP, PMOV{S,Z}X{BW,WD,DQ}, and ROUNDSD: NoRex64 gets set, - CVTSS2SD, INSERTPS, PEXTRW (memory destination), PINSRW (memory source), and PMOV{S,Z}X{BD,WQ,BQ}: IgnoreSize gets set. Similarly the "normal" (non-SSE2AVX) - non-64-bit CVTS{I,S}2SD forms get NoRex64 set, - CMP{EQ,ORD,NEQ,UNORD}{P,S}{S,D} forms get C set, all again in a benign way. The remaining differences in the generated table are due to re-ordering of entries in the course of being folded into templates.
2021-03-29x86: undo Prefix_0X<nn> use in opcode tableJan Beulich3-375/+383
The table entries are more natural to read (and slightly shorter) when the prefixes, like is the case for VEX/XOP/EVEX-encoded entries, are specified as part of the opcode. This is particularly noticable for side-by-side legacy and SSE2AVX entries. An implication is that we now need to use "unsigned long long" for the initially parsed opcode in i386-gen. I don't expect this to be an issue.
2021-03-29x86: shrink some struct insn_template fieldsJan Beulich2-4/+10
Now that all base opcodes are only at most 2 bytes in size, shrink its template field to just as much. By also shrinking extension_opcode and operands to just what they really need, we can free up an entire 32-bit slot (plus 4 left bits past the bitfields themselves). At present this alters sizeof(struct insn_template) only for 32-bit builds. In 64-bit builds it instead leaves a padding hole that will allow to buffer future growth of other fields (opcode_modifier, cpu_flags, operand_types[]).
2021-03-29x86: derive opcode encoding space attribute from base opcodeJan Beulich6-1721/+1814
Just like is already done for VEX/XOP/EVEX encoded insns, record the encoding space information in the respective opcode modifier field. Do this again without changing the source table, but rather by deriving the values from their existing source representation.
2021-03-29TRUE/FALSE simplificationAlan Modra44-176/+203
There is really no need to write code like "foo != 0 ? TRUE : FALSE" unless we had stupidly defined FALSE as something other than 0 or TRUE as something other than 1. The simpler "foo != 0" does just as well. Similarly "(condition == TRUE)" or "(condition == FALSE) can be simplified to "(condition)" and "(!condition)" respectively. I'll note that there is reason to use "integer_expression != 0" when assigning a bfd_boolean rather than the simpler "integer_expression", if you expect the variable to have 0 or 1 value. It's probably even a good idea to not rely on implicit conversion if bfd_boolean were _Bool. bfd/ * aoutx.h (aout_link_write_symbols): Don't cast boolean expression to bfd_boolean. * elf32-or1k.c (or1k_set_got_and_rela_sizes): Dont compare booleans against FALSE. * elf32-arc.c (name_for_global_symbol): Don't compare boolean to TRUE. (is_reloc_PC_relative): Don't use "boolean_condition ? TRUE : FALSE". (is_reloc_SDA_relative, is_reloc_for_GOT): Likewise. (is_reloc_for_PLT, is_reloc_for_TLS): Likewise. * elf32-arm.c (stm32l4xx_need_create_replacing_stub): Likewise. * elf32-nds32.c (insert_nds32_elf_blank): Likewise. * elf32-rx.c (rx_set_section_contents): Likewise. * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Likewise. * elfxx-mips.c (_bfd_mips_elf_ignore_undef_symbol): Likewise. * mach-o.c (bfd_mach_o_read_command): Likewise. * targets.c (bfd_get_target_info): Likewise. binutils/ * dlltool.c (main): Don't use "boolean_condition ? TRUE : FALSE". * dwarf.c (read_and_display_attr_value): Likewise. (display_debug_str_offsets): Likewise. * objdump.c (dump_bfd): Likewise. * readelf.c (dump_section_as_strings): Likewise. (dump_section_as_bytes): Likewise. gas/ * atof-generic.c (FALSE, TRUE): Don't define. * config/obj-elf.h (FALSE, TRUE): Don't define. * config/obj-som.h (FALSE, TRUE): Don't define. * config/tc-hppa.h (FALSE, TRUE): Don't define. * config/tc-pdp11.c (FALSE, TRUE): Don't define. * config/tc-iq2000.h (obj_fix_adjustable): Delete. * config/tc-m32r.h (TC_FIX_ADJUSTABLE): Delete. * config/tc-mt.h (obj_fix_adjustable): Delete. * config/tc-nds32.h (TC_FIX_ADJUSTABLE): Delete. * config/tc-arc.c (parse_opcode_flags): Simplify boolean expression. (relaxable_flag, relaxable_operand, assemble_insn): Likewise. (tokenize_extregister): Likewise. * config/tc-csky.c (parse_opcode, get_operand_value): Likewise. (parse_operands_op, parse_operands, md_assemble): Likewise. * config/tc-d10v.c (build_insn): Likewise. * config/tc-score.c (s3_gen_insn_frag): Likewise. * config/tc-score7.c (s7_gen_insn_frag, s7_relax_frag): Likewise. * config/tc-tic6x.c (tic6x_update_features, md_assemble): Likewise. * config/tc-z80.c (emit_byte): Likewise. include/ * opcode/aarch64.h (alias_opcode_p): Simplify boolean expression. (opcode_has_alias, pseudo_opcode_p, optional_operand_p): Likewise. (opcode_has_special_coder): Likewise. ld/ * emultempl/aix.em (gld${EMULATION_NAME}_before_allocation): Simplify boolean expression. * lexsup.c (parse_args): Likewise. * pe-dll.c (pe_dll_id_target): Likewise. opcodes/ * aarch64-opc.c (vector_qualifier_p): Simplify boolean expression. (fp_qualifier_p, get_data_pattern): Likewise. (aarch64_get_operand_modifier_from_value): Likewise. (aarch64_extend_operator_p, aarch64_shift_operator_p): Likewise. (operand_variant_qualifier_p): Likewise. (qualifier_value_in_range_constraint_p): Likewise. (aarch64_get_qualifier_esize): Likewise. (aarch64_get_qualifier_nelem): Likewise. (aarch64_get_qualifier_standard_value): Likewise. (get_lower_bound, get_upper_bound): Likewise. (aarch64_find_best_match, match_operands_qualifier): Likewise. (aarch64_print_operand): Likewise. * aarch64-opc.h (operand_has_inserter, operand_has_extractor): Likewise. (operand_need_sign_extension, operand_need_shift_by_two): Likewise. (operand_need_shift_by_four, operand_maybe_stack_pointer): Likewise. * arm-dis.c (print_insn_mve, print_insn_thumb32): Likewise. * tic6x-dis.c (tic6x_check_fetch_packet_header): Likewise. (print_insn_tic6x): Likewise.
2021-03-29gas int vs bfd_boolean fixesAlan Modra7-65/+83
* config/tc-arm.c (struct arm_long_option_table <func>): Return bfd_boolean. * config/tc-arm.h (arm_optimize_expr, arm_data_in_code): Likewise. * config/tc-metag.c (parse_mov_port): Replace unsigned int variable with bfd_boolean. (parse_mmov, parse_mov_ct, parse_alu, parse_shift, parse_bitop), (parse_cmp, parse_fmmov, parse_fmov_data, parse_fearith), (parse_dget_set, parse_dalu): Likewise, ensuring assignment from logical expressions. (struct metag_long_option <func>): Return bfd_boolean. (metag_parse_cpu, metag_parse_fpu, metag_parse_dsp): Likewise. * config/tc-msp430.c (msp430_dstoperand): Correct dummy type. * config/tc-s12z.c (parse_operand_func): Return bfd_boolean. (no_operands, lex_force_match, lex_reg_list): Likewise. (size_from_suffix): Return int. (s12z_relax_frag, md_estimate_size_before_relax): Return 0. * config/tc-s12z.h (tc_s12z_fix_adjustable): Likewise.
2021-03-29binutils int vs bfd_boolean fixesAlan Modra6-6/+15
* objdump.c (process_links): Use type int. * readelf.c (request_dump): Don't increment do_dump, set it. * windint.h (target_is_bigendian): Use type bfd_boolean. * windmc.c (target_is_bigendian): Likewise. * windres.c (target_is_bigendian): Likewise.
2021-03-29opcodes int vs bfd_boolean fixesAlan Modra7-20/+35
cpu/ * frv.opc (frv_is_branch_major, frv_is_float_major), (frv_is_media_major, frv_is_branch_insn, frv_is_float_insn), (frv_is_media_insn, spr_valid): Correct prototypes. include/ * opcode/aarch64.h (aarch64_opcode_encode): Correct prototype. opcodes/ * arc-dis.c (extract_operand_value): Correct NULL cast. * frv-opc.h: Regenerate.
2021-03-29Miscellaneous BFD int vs bfd_boolean fixesAlan Modra6-8/+18
nds32 hyper_relax takes values of 0, 1 and 2. vms_write_data_block return TRUE/FALSE not positive/negative. * coff-z80.c (z80_is_local_label_name): Return bfd_boolean. * elf32-z80.c (z80_is_local_label_name): Likewise. * elf32-spu.c (spu_elf_modify_headers): Likewise. * elf32-nds32.h (struct elf_nds32_link_hash_table <hyper_relax>): Change type to int. * vms-lib.c (_bfd_vms_lib_write_archive_contents): Correct test for error return from vms_write_data_block.
2021-03-29hash table iterator callback functions int vs. bfd_booleanAlan Modra10-16/+35
Correct return type of callbacks invoked by htab_traverse and other hashtab.h functions to int, and one case of a callback invoked by elf_link_hash_traverse to bfd_boolean. * elf32-i386.c (elf_i386_finish_local_dynamic_symbol): Return int. * elf64-ia64-vms.c (elf64_ia64_local_dyn_info_free): Likewise. (elf64_ia64_local_dyn_sym_thunk): Likewise. * elf64-x86-64.c (elf_x86_64_finish_local_dynamic_symbol): Likewise. * elfnn-aarch64.c (elfNN_aarch64_allocate_local_ifunc_dynrelocs), (elfNN_aarch64_finish_local_dynamic_symbol): Likewise. * elfnn-ia64.c (elfNN_ia64_local_dyn_info_free): Likewise. (elfNN_ia64_local_dyn_sym_thunk): Likewise. * elfnn-riscv.c (allocate_local_ifunc_dynrelocs): Likewise. (riscv_pcrel_reloc_eq): Likewise. (riscv_elf_finish_local_dynamic_symbol): Likewise. * elfxx-sparc.c (allocate_local_dynrelocs): Likewise. (finish_local_dynamic_symbol): Likewise. * elfxx-x86.c (elf_x86_allocate_local_dynreloc): Likewise. * elfxx-mips.c (mips_elf_resolve_got_page_ref): Likewise. (mips_elf_count_got_symbols): Change return type to bfd_boolean.
2021-03-29ELF output symbol hooks int vs. bfd_booleanAlan Modra5-23/+29
elf_backend_link_output_symbol_hook and elf_link_output_symstrtab may return 2 when a symbol is to be discarded. Update places that use bfd_boolean rather than int for these functions. * elflink.c (elf_link_output_symstrtab): Make flinfo parameter a void pointer. (bfd_elf_final_link): Delete out_sym_func typedef and don't cast elf_link_output_symstrtab when calling output_arch_syms and output_arch_local_syms. * elf-bfd.h (struct elf_backend_data <elf_backend_output_arch_syms, elf_backend_output_arch_local_syms>): Change return type of func arg to match elf_link_output_symstrtab. * elf-vxworks.h (elf_vxworks_link_output_symbol_hook): Correct return type. * elf32-nds32.c (nds32_elf_output_symbol_hook): Correct return type. (nds32_elf_output_arch_syms): Correct func return type.
2021-03-29elf_backend_relocate_section int vs. bfd_booleanAlan Modra72-82/+159
This functions was changed to return an int in commit ece5ef60797f but since bfd_boolean was an int typedef I lazily left all the ELF relocate_section functions as returning bfd_boolean, except the SPU one. In order to use _Bool or bool in place of bfd_boolean we need to be fussy about the return types. * elf-m10200.c (mn10200_elf_relocate_section): Return int. * elf-m10300.c (mn10300_elf_relocate_section): Likewise. * elf32-arc.c (elf_arc_relocate_section): Likewise. * elf32-arm.c (elf32_arm_relocate_section): Likewise. * elf32-avr.c (elf32_avr_relocate_section): Likewise. * elf32-bfin.c (bfin_relocate_section): Likewise. (bfinfdpic_relocate_section): Likewise. * elf32-cr16.c (elf32_cr16_relocate_section): Likewise. * elf32-cris.c (cris_elf_relocate_section): Likewise. * elf32-crx.c (elf32_crx_relocate_section): Likewise. * elf32-csky.c (csky_elf_relocate_section): Likewise. * elf32-d10v.c (elf32_d10v_relocate_section): Likewise. * elf32-epiphany.c (epiphany_elf_relocate_section): Likewise. * elf32-fr30.c (fr30_elf_relocate_section): Likewise. * elf32-frv.c (elf32_frv_relocate_section): Likewise. * elf32-ft32.c (ft32_elf_relocate_section): Likewise. * elf32-h8300.c (elf32_h8_relocate_section): Likewise. * elf32-hppa.c (elf32_hppa_relocate_section): Likewise. * elf32-i386.c (elf_i386_relocate_section): Likewise. * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise. * elf32-iq2000.c (iq2000_elf_relocate_section): Likewise. * elf32-lm32.c (lm32_elf_relocate_section): Likewise. * elf32-m32c.c (m32c_elf_relocate_section): Likewise. * elf32-m32r.c (m32r_elf_relocate_section): Likewise. * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Likewise. * elf32-m68hc1x.h (elf32_m68hc11_relocate_section): Likewise. * elf32-m68k.c (elf_m68k_relocate_section): Likewise. * elf32-mcore.c (mcore_elf_relocate_section): Likewise. * elf32-mep.c (mep_elf_relocate_section): Likewise. * elf32-metag.c (elf_metag_relocate_section): Likewise. * elf32-microblaze.c (microblaze_elf_relocate_section): Likewise. * elf32-moxie.c (moxie_elf_relocate_section): Likewise. * elf32-msp430.c (elf32_msp430_relocate_section): Likewise. * elf32-mt.c (mt_elf_relocate_section): Likewise. * elf32-nds32.c (nds32_elf_relocate_section): Likewise. * elf32-nios2.c (nios2_elf32_relocate_section): Likewise. * elf32-or1k.c (or1k_elf_relocate_section): Likewise. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. * elf32-pru.c (pru_elf32_relocate_section): Likewise. * elf32-rl78.c (rl78_elf_relocate_section): Likewise. * elf32-rx.c (rx_elf_relocate_section): Likewise. * elf32-s390.c (elf_s390_relocate_section): Likewise. * elf32-score.c (s3_bfd_score_elf_relocate_section): Likewise. (_bfd_score_elf_relocate_section): Likewise. * elf32-score.h (s7_bfd_score_elf_relocate_section): Likewise. * elf32-score7.c (s7_bfd_score_elf_relocate_section): Likewise. * elf32-sh.c (sh_elf_relocate_section): Likewise. * elf32-tic6x.c (elf32_tic6x_relocate_section): Likewise. * elf32-tilepro.c (tilepro_elf_relocate_section): Likewise. * elf32-v850.c (v850_elf_relocate_section): Likewise. * elf32-vax.c (elf_vax_relocate_section): Likewise. * elf32-visium.c (visium_elf_relocate_section): Likewise. * elf32-xc16x.c (elf32_xc16x_relocate_section): Likewise. * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise. * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise. * elf32-z80.c (z80_elf_relocate_section): Likewise. * elf64-alpha.c (elf64_alpha_relocate_section_r): Likewise. (elf64_alpha_relocate_section): Likewise. * elf64-bpf.c (bpf_elf_relocate_section): Likewise. * elf64-hppa.c (elf64_hppa_relocate_section): Likewise. * elf64-ia64-vms.c (elf64_ia64_relocate_section): Likewise. * elf64-mmix.c (mmix_elf_relocate_section): Likewise. * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. * elf64-s390.c (elf_s390_relocate_section): Likewise. * elf64-x86-64.c (elf_x86_64_relocate_section): Likewise. * elfnn-aarch64.c (elfNN_aarch64_relocate_section): Likewise. * elfnn-ia64.c (elfNN_ia64_relocate_section): Likewise. * elfnn-riscv.c (riscv_elf_relocate_section): Likewise. * elfxx-mips.c (_bfd_mips_elf_relocate_section): Likewise. * elfxx-mips.h (_bfd_mips_elf_relocate_section): Likewise. * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise. * elfxx-sparc.h (_bfd_sparc_elf_relocate_section): Likewise. * elfxx-tilegx.c (tilegx_elf_relocate_section): Likewise. * elfxx-tilegx.h (tilegx_elf_relocate_section): Likewise.
2021-03-29Automatic date update in version.inGDB Administrator1-1/+1
2021-03-28Simplify DWARF reader initializationTom Tromey4-68/+66
Now that the quick functions are separate from the object file format, there's no need to have elfread.c push a new entry on the objfile 'qf' list. Instead, this detail can be pushed into the DWARF reader. That is what this patch implements. I wasn't sure whether lazy reading still makes sense or not. It's still only used by ELF, and only in certain situations (like vfork, I think). It may not be carrying its weight, so we may want to consider removing this in the future. Also, I'm unclear on why the various indices are only used for ELF. This seems sub-optimal. However, I haven't tried to address that here. gdb/ChangeLog 2021-03-28 Tom Tromey <tom@tromey.com> * elfread.c (can_lazily_read_symbols): Move to dwarf2/read.c. (elf_symfile_read): Simplify. * dwarf2/read.c (struct lazy_dwarf_reader): Move from elfread.c. (make_lazy_dwarf_reader): New function. (make_dwarf_gdb_index, make_dwarf_debug_names): Now static. (dwarf2_initialize_objfile): Return void. Remove index_kind parameter. Push on 'qf' list. * dwarf2/public.h (dwarf2_initialize_objfile): Change return type. Remove 'index_kind' parameter. (make_dwarf_gdb_index, make_dwarf_debug_names): Don't declare.
2021-03-28Automatic date update in version.inGDB Administrator1-1/+1
2021-03-27Don't declare elf_sym_fns_lazy_psymsTom Tromey2-2/+4
An earlier patch neglected to delete a forward declaration of elf_sym_fns_lazy_psyms. This is no longer defined. This patch removes it. gdb/ChangeLog 2021-03-27 Tom Tromey <tom@tromey.com> * elfread.c (elf_sym_fns_lazy_psyms): Don't declare.
2021-03-27Don't clear 'qf' in elf_symfile_readTom Tromey2-1/+4
I noticed that I forgot to make a change in my series to make it possible to attach multiple debug readers to an objfile. In one spot, elf_symfile_read still clears the 'qf' list. However, this should have been removed toward the end of that series. This patch fixes the offending spot. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-03-27 Tom Tromey <tom@tromey.com> * elfread.c (elf_symfile_read): Don't clear 'qf'.
2021-03-27gdb/testsuite: make some test names unique in gdb.arch/powerpc-*.expWill Schmidt3-4/+11
Resolve some duplicate test name warnings in gdb.arch/powerpc-*.exp tests by either extending the existing test names, or providing a new test name. gdb/testsuite/ChangeLog: * gdb.arch/powerpc-disassembler-options.exp: Extend some test names for uniqueness. * gdb.arch/powerpc-fpscr-gcore.exp: Add more test names for uniqueness.
2021-03-27Automatic date update in version.inGDB Administrator1-1/+1
2021-03-26gdb-add-index.sh: Remove use of non posix 'local'Lancelot SIX2-13/+17
While working on gdb-add-index.sh, it appeared that it uses the non POSIX 'local' keyword. Instead of using local to allow variable shadowing, I rename the local one to avoid name conflicts altogether. This commit gets rid of the following shellcheck warning: In gdb-add-index.sh line 63: local file="$1" ^--------^ SC2039: In POSIX sh, 'local' is undefined. gdb/ChangeLog: * contrib/gdb-add-index.sh: Avoid variable shadowing and get rid of 'local'.
2021-03-26Use function view in quick_symbol_functions::map_symbol_filenamesTom Tromey11-81/+100
This changes quick_symbol_functions::map_symbol_filenames to use a function_view, and updates all the uses. It also changes the final parameter to 'bool'. A couple of spots are further updated to use operator() rather than a lambda. gdb/ChangeLog 2021-03-26 Tom Tromey <tom@tromey.com> * symtab.c (struct output_source_filename_data): Add 'output' method and operator(). (output_source_filename_data::output): Rename from output_source_filename. (output_partial_symbol_filename): Remove. (info_sources_command): Update. (struct add_partial_filename_data): Add operator(). (add_partial_filename_data::operator()): Rename from maybe_add_partial_symtab_filename. (make_source_files_completion_list): Update. * symfile.c (quick_symbol_functions): Update. * symfile-debug.c (objfile::map_symbol_filenames): Update. * quick-symbol.h (symbol_filename_ftype): Change type of 'fun' and 'need_fullname'. Remove 'data' parameter. (struct quick_symbol_functions) <map_symbol_filenames>: Likewise. * psymtab.c (psymbol_functions::map_symbol_filenames): Update. * psympriv.h (struct psymbol_functions) <map_symbol_filenames>: Change type of 'fun' and 'need_fullname'. Remove 'data' parameter. * objfiles.h (struct objfile) <map_symbol_filenames>: Change type of 'fun' and 'need_fullname'. Remove 'data' parameter. * mi/mi-cmd-file.c (print_partial_file_name): Remove 'ignore' parameter. (mi_cmd_file_list_exec_source_files): Update. * dwarf2/read.c (dwarf2_base_index_functions::map_symbol_filenames): Update.
2021-03-26Simplify use of map_matching_symbols in ada-lang.cTom Tromey2-28/+24
I noticed that ada-lang.c creates a lambda to call aux_add_nonlocal_symbols. However, this code can be simplified a bit by changing match_data to implement operator(), and then simply passing the object as the callback. That is what this patch implements. gdb/ChangeLog 2021-03-26 Tom Tromey <tom@tromey.com> * ada-lang.c (struct match_data): Add operator(). (match_data::operator()): Rename from aux_add_nonlocal_symbols. (callback): Remove 'callback'.
2021-03-26Simplify psymbol_functions::expand_symtabs_matchingTom Tromey2-1/+10
I noticed that psymbol_functions::expand_symtabs_matching calls make_ignore_params once per psymtab that is matched. This seems possibly expensive, so this patch hoists the call out of the loop. gdb/ChangeLog 2021-03-26 Tom Tromey <tom@tromey.com> * psymtab.c (psymbol_functions::expand_symtabs_matching): Only call make_ignore_params once.
2021-03-26Allow expand_symtabs_matching to examine imported psymtabsTom Tromey2-5/+5
Currently the psymtab variant of expand_symtabs_matching has this check: /* We skip shared psymtabs because file-matching doesn't apply to them; but we search them later in the loop. */ if (ps->user != NULL) continue; In a larger series I'm working on, it's convenient to remove this check. And, I noticed that a similar check is not done for expand_symtabs_with_fullname. So, it made sense to me to remove the check here as well. gdb/ChangeLog 2021-03-26 Tom Tromey <tom@tromey.com> * psymtab.c (psymbol_functions::expand_symtabs_matching): Remove "user" check.
2021-03-26Save/restore file offset while reading notes in core fileKeith Seitz2-0/+12
A recent bug (RH BZ 1931344) has exposed a bug in the core file build-ID support that I introduced a while ago. It is pretty easy to demonstate the problem following a simplified procedure outlined in that bug: [shell1] shell1$ /usr/libexec/qemu-kvm [shell2] shell2$ pkill -SEGV -x qemu-kvm [shell1] Segmentation fault (core dumped) Load this core file into GDB without specifying an executable (an unfortunate Fedora/RHEL-ism), and GDB will inform the user to install debuginfo for the "missing" executable: $ gdb -nx -q core.12345 ... Missing separate debuginfo for the main executable file Try: dnf --enablerepo='*debug*' install /usr/lib/debug/.build-id/e2/e9c66d3117fb2bbb5b2be122f04f2664e5df54 Core was generated by `/usr/libexec/qemu-kvm'. Program terminated with signal SIGSEGV, Segmentation fault. ... The suggested build-ID is actaully for gmp not qemu-kvm. The problem lies in _bfd_elf_core_find_build_id, where we loop over program headers looking for note segments: /* Read in program headers and parse notes. */ for (i = 0; i < i_ehdr.e_phnum; ++i, ++i_phdr) { Elf_External_Phdr x_phdr; if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr)) goto fail; elf_swap_phdr_in (abfd, &x_phdr, i_phdr); if (i_phdr->p_type == PT_NOTE && i_phdr->p_filesz > 0) { elf_read_notes (abfd, offset + i_phdr->p_offset, i_phdr->p_filesz, i_phdr->p_align); if (abfd->build_id != NULL) return TRUE; } elf_read_notes uses bfd_seek to forward the stream to the location of the note segment. When control returns to _bfd_elf_core_fild_build_id, the stream is no longer in the location looking at program headers, and all subsequent reads will read from the wrong file offset. To fix this, this patch marks the stream location and ensures that it is restored after elf_read_notes is called. bfd/ChangeLog 2021-03-26 Keith Seitz <keiths@redhat.com> * elfcore.h (_bfd_elf_core_find_build_id): Seek file offset of program headers after calling elf_read_notes.
2021-03-26gdb/testsuite: more testing of pretty printer 'array' display_hintAndrew Burgess4-0/+45
This commit adds a couple of tests to the python pretty printer testing. I've added a test for the 'array' display hint. This display hint is tested by gdb.python/py-mi.exp, however, the MI testing is done via the varobj interface, and this code makes its own direct calls to the Python pretty printers from gdb/varobj.c. What this means is that the interface to the pretty printers in gdb/python/py-prettyprint.c is not tested for the 'array' display hint path. I also added a test for what happens when the display_hint method raises an exception. There wasn't a bug that inspired this test, just while adding the previous test I thought, I wonder what happens if... The current behaviour of GDB seems reasonable, GDB displays the Python exception, and then continues printing the value as if display_hint had returned None. I added a test to lock in this behaviour. gdb/testsuite/ChangeLog: * gdb.python/py-prettyprint.c (struct container): Add 'is_array_p' member. (make_container): Initialise is_array_p. * gdb.python/py-prettyprint.exp: Add new tests. * gdb.python/py-prettyprint.py (ContainerPrinter.display_hint): Check is_array_p and possibly return 'array'.
2021-03-26gdb: defer commit resume until all available events are consumedSimon Marchi8-0/+108
Rationale --------- Let's say you have multiple threads hitting a conditional breakpoint at the same time, and all of these are going to evaluate to false. All these threads will need to be resumed. Currently, GDB fetches one target event (one SIGTRAP representing the breakpoint hit) and decides that the thread should be resumed. It calls resume and commit_resume immediately. It then fetches the second target event, and does the same, until it went through all threads. The result is therefore something like: - consume event for thread A - resume thread A - commit resume (affects thread A) - consume event for thread B - resume thread B - commit resume (affects thread B) - consume event for thread C - resume thread C - commit resume (affects thread C) For targets where it's beneficial to group resumptions requests (most likely those that implement target_ops::commit_resume), it would be much better to have: - consume event for thread A - resume thread A - consume event for thread B - resume thread B - consume event for thread C - resume thread C - commit resume (affects threads A, B and C) Implementation details ---------------------- To achieve this, this patch adds another check in maybe_set_commit_resumed_all_targets to avoid setting the commit-resumed flag of targets that readily have events to provide to infrun. To determine if a target has events readily available to report, this patch adds an `has_pending_events` target_ops method. The method returns a simple bool to say whether or not it has pending events to report. Testing ======= To test this, I start GDBserver with a program that spawns multiple threads: $ ../gdbserver/gdbserver --once :1234 ~/src/many-threads-stepping-over-breakpoints/many-threads-stepping-over-breakpoints I then connect with GDB and install a conditional breakpoint that always evaluates to false (and force the evaluation to be done by GDB): $ ./gdb -nx --data-directory=data-directory \ /home/simark/src/many-threads-stepping-over-breakpoints/many-threads-stepping-over-breakpoints \ -ex "set breakpoint condition-evaluation host" \ -ex "set pag off" \ -ex "set confirm off" \ -ex "maint set target-non-stop on" \ -ex "tar rem :1234" \ -ex "tb main" \ -ex "b 13 if 0" \ -ex c \ -ex "set debug infrun" \ -ex "set debug remote 1" \ -ex "set debug displaced" I then do "continue" and look at the log. The remote target receives a bunch of stop notifications for all threads that have hit the breakpoint. infrun consumes and processes one event, decides it should not cause a stop, prepares a displaced step, after which we should see: [infrun] maybe_set_commit_resumed_all_process_targets: not requesting commit-resumed for target remote, target has pending events Same for a second thread (since we have 2 displaced step buffers). For the following threads, their displaced step is deferred since there are no more buffers available. After consuming the last event the remote target has to offer, we get: [infrun] maybe_set_commit_resumed_all_process_targets: enabling commit-resumed for target remote [infrun] maybe_call_commit_resumed_all_process_targets: calling commit_resumed for target remote [remote] Sending packet: $vCont;s:p14d16b.14d1b1;s:p14d16b.14d1b2#55 [remote] Packet received: OK Without the patch, there would have been one vCont;s just after each prepared displaced step. gdb/ChangeLog: yyyy-mm-dd Simon Marchi <simon.marchi@efficios.com> Pedro Alves <pedro@palves.net> * async-event.c (async_event_handler_marked): New. * async-event.h (async_event_handler_marked): Declare. * infrun.c (maybe_set_commit_resumed_all_targets): Switch to inferior before calling target method. Don't commit-resumed if target_has_pending_events is true. * remote.c (remote_target::has_pending_events): New. * target-delegates.c: Regenerate. * target.c (target_has_pending_events): New. * target.h (target_ops::has_pending_events): New target method. (target_has_pending_events): New. Change-Id: I18112ba19a1ff4986530c660f530d847bb4a1f1d
2021-03-26gdb: generalize commit_resume, avoid commit-resuming when threads have ↵Simon Marchi12-98/+575
pending statuses The rationale for this patch comes from the ROCm port [1], the goal being to reduce the number of back and forths between GDB and the target when doing successive operations. I'll start with explaining the rationale and then go over the implementation. In the ROCm / GPU world, the term "wave" is somewhat equivalent to a "thread" in GDB. So if you read if from a GPU stand point, just s/thread/wave/. ROCdbgapi, the library used by GDB [2] to communicate with the GPU target, gives the illusion that it's possible for the debugger to control (start and stop) individual threads. But in reality, this is not how it works. Under the hood, all threads of a queue are controlled as a group. To stop one thread in a group of running ones, the state of all threads is retrieved from the GPU, all threads are destroyed, and all threads but the one we want to stop are re-created from the saved state. The net result, from the point of view of GDB, is that the library stopped one thread. The same thing goes if we want to resume one thread while others are running: the state of all running threads is retrieved from the GPU, they are all destroyed, and they are all re-created, including the thread we want to resume. This leads to some inefficiencies when combined with how GDB works, here are two examples: - Stopping all threads: because the target operates in non-stop mode, when the user interface mode is all-stop, GDB must stop all threads individually when presenting a stop. Let's suppose we have 1000 threads and the user does ^C. GDB asks the target to stop one thread. Behind the scenes, the library retrieves 1000 thread states and restores the 999 others still running ones. GDB asks the target to stop another one. The target retrieves 999 thread states and restores the 998 remaining ones. That means that to stop 1000 threads, we did 1000 back and forths with the GPU. It would have been much better to just retrieve the states once and stop there. - Resuming with pending events: suppose the 1000 threads hit a breakpoint at the same time. The breakpoint is conditional and evaluates to true for the first thread, to false for all others. GDB pulls one event (for the first thread) from the target, decides that it should present a stop, so stops all threads using stop_all_threads. All these other threads have a breakpoint event to report, which is saved in `thread_info::suspend::waitstatus` for later. When the user does "continue", GDB resumes that one thread that did hit the breakpoint. It then processes the pending events one by one as if they just arrived. It picks one, evaluates the condition to false, and resumes the thread. It picks another one, evaluates the condition to false, and resumes the thread. And so on. In between each resumption, there is a full state retrieval and re-creation. It would be much nicer if we could wait a little bit before sending those threads on the GPU, until it processed all those pending events. To address this kind of performance issue, ROCdbgapi has a concept called "forward progress required", which is a boolean state that allows its user (i.e. GDB) to say "I'm doing a bunch of operations, you can hold off putting the threads on the GPU until I'm done" (the "forward progress not required" state). Turning forward progress back on indicates to the library that all threads that are supposed to be running should now be really running on the GPU. It turns out that GDB has a similar concept, though not as general, commit_resume. One difference is that commit_resume is not stateful: the target can't look up "does the core need me to schedule resumed threads for execution right now". It is also specifically linked to the resume method, it is not used in other contexts. The target accumulates resumption requests through target_ops::resume calls, and then commits those resumptions when target_ops::commit_resume is called. The target has no way to check if it's ok to leave resumed threads stopped in other target methods. To bridge the gap, this patch generalizes the commit_resume concept in GDB to match the forward progress concept of ROCdbgapi. The current name (commit_resume) can be interpreted as "commit the previous resume calls". I renamed the concept to "commit_resumed", as in "commit the threads that are resumed". In the new version, we have two things: - the commit_resumed_state field in process_stratum_target: indicates whether GDB requires target stacks using this target to have resumed threads committed to the execution target/device. If false, an execution target is allowed to leave resumed threads un-committed at the end of whatever method it is executing. - the commit_resumed target method: called when commit_resumed_state transitions from false to true. While commit_resumed_state was false, the target may have left some resumed threads un-committed. This method being called tells it that it should commit them back to the execution device. Let's take the "Stopping all threads" scenario from above and see how it would work with the ROCm target with this change. Before stopping all threads, GDB would set the target's commit_resumed_state field to false. It would then ask the target to stop the first thread. The target would retrieve all threads' state from the GPU and mark that one as stopped. Since commit_resumed_state is false, it leaves all the other threads (still resumed) stopped. GDB would then proceed to call target_stop for all the other threads. Since resumed threads are not committed, this doesn't do any back and forth with the GPU. To simplify the implementation of targets, this patch makes it so that when calling certain target methods, the contract between the core and the targets guarantees that commit_resumed_state is false. This way, the target doesn't need two paths, one for commit_resumed_state == true and one for commit_resumed_state == false. It can just assert that commit_resumed_state is false and work with that assumption. This also helps catch places where we forgot to disable commit_resumed_state before calling the method, which represents a probable optimization opportunity. The commit adds assertions in the target method wrappers (target_resume and friends) to have some confidence that this contract between the core and the targets is respected. The scoped_disable_commit_resumed type is used to disable the commit resumed state of all process targets on construction, and selectively re-enable it on destruction (see below for criteria). Note that it only sets the process_stratum_target::commit_resumed_state flag. A subsequent call to maybe_call_commit_resumed_all_targets is necessary to call the commit_resumed method on all target stacks with process targets that got their commit_resumed_state flag turned back on. This separation is because we don't want to call the commit_resumed methods in scoped_disable_commit_resumed's destructor, as they may throw. On destruction, commit-resumed is not re-enabled for a given target if: 1. this target has no threads resumed, or 2. this target has at least one resumed thread with a pending status known to the core (saved in thread_info::suspend::waitstatus). The first point is not technically necessary, because a proper commit_resumed implementation would be a no-op if the target has no resumed threads. But since we have a flag do to a quick check, it shouldn't hurt. The second point is more important: together with the scoped_disable_commit_resumed instance added in fetch_inferior_event, it makes it so the "Resuming with pending events" described above is handled efficiently. Here's what happens in that case: 1. The user types "continue". 2. Upon destruction, the scoped_disable_commit_resumed in the `proceed` function does not enable commit-resumed, as it sees some threads have pending statuses. 3. fetch_inferior_event is called to handle another event, the breakpoint hit evaluates to false, and that thread is resumed. Because there are still more threads with pending statuses, the destructor of scoped_disable_commit_resumed in fetch_inferior_event still doesn't enable commit-resumed. 4. Rinse and repeat step 3, until the last pending status is handled by fetch_inferior_event. In that case, scoped_disable_commit_resumed's destructor sees there are no more threads with pending statues, so it asks the target to commit resumed threads. This allows us to avoid all unnecessary back and forths, there is a single commit_resumed call once all pending statuses are processed. This change required remote_target::remote_stop_ns to learn how to handle stopping threads that were resumed but pending vCont. The simplest example where that happens is when using the remote target in all-stop, but with "maint set target-non-stop on", to force it to operate in non-stop mode under the hood. If two threads hit a breakpoint at the same time, GDB will receive two stop replies. It will present the stop for one thread and save the other one in thread_info::suspend::waitstatus. Before this patch, when doing "continue", GDB first resumes the thread without a pending status: Sending packet: $vCont;c:p172651.172676#f3 It then consumes the pending status in the next fetch_inferior_event call: [infrun] do_target_wait_1: Using pending wait status status->kind = stopped, signal = GDB_SIGNAL_TRAP for Thread 1517137.1517137. [infrun] target_wait (-1.0.0, status) = [infrun] 1517137.1517137.0 [Thread 1517137.1517137], [infrun] status->kind = stopped, signal = GDB_SIGNAL_TRAP It then realizes it needs to stop all threads to present the stop, so stops the thread it just resumed: [infrun] stop_all_threads: Thread 1517137.1517137 not executing [infrun] stop_all_threads: Thread 1517137.1517174 executing, need stop remote_stop called Sending packet: $vCont;t:p172651.172676#04 This is an unnecessary resume/stop. With this patch, we don't commit resumed threads after proceeding, because of the pending status: [infrun] maybe_commit_resumed_all_process_targets: not requesting commit-resumed for target extended-remote, a thread has a pending waitstatus When GDB handles the pending status and stop_all_threads runs, we stop a resumed but pending vCont thread: remote_stop_ns: Enqueueing phony stop reply for thread pending vCont-resume (1520940, 1520976, 0) That thread was never actually resumed on the remote stub / gdbserver, so we shouldn't send a packet to the remote side asking to stop the thread. Note that there are paths that resume the target and then do a synchronous blocking wait, in sort of nested event loop, via wait_sync_command_done. For example, inferior function calls, or any run control command issued from a breakpoint command list. We handle that making wait_sync_command_one a "sync" point -- force forward progress, or IOW, force-enable commit-resumed state. gdb/ChangeLog: yyyy-mm-dd Simon Marchi <simon.marchi@efficios.com> Pedro Alves <pedro@palves.net> * infcmd.c (run_command_1, attach_command, detach_command) (interrupt_target_1): Use scoped_disable_commit_resumed. * infrun.c (do_target_resume): Remove target_commit_resume call. (commit_resume_all_targets): Remove. (maybe_set_commit_resumed_all_targets): New. (maybe_call_commit_resumed_all_targets): New. (enable_commit_resumed): New. (scoped_disable_commit_resumed::scoped_disable_commit_resumed) (scoped_disable_commit_resumed::~scoped_disable_commit_resumed) (scoped_disable_commit_resumed::reset) (scoped_disable_commit_resumed::reset_and_commit) (scoped_enable_commit_resumed::scoped_enable_commit_resumed) (scoped_enable_commit_resumed::~scoped_enable_commit_resumed): New. (proceed): Use scoped_disable_commit_resumed and maybe_call_commit_resumed_all_targets. (fetch_inferior_event): Use scoped_disable_commit_resumed. * infrun.h (struct scoped_disable_commit_resumed): New. (maybe_call_commit_resumed_all_process_targets): New. (struct scoped_enable_commit_resumed): New. * mi/mi-main.c (exec_continue): Use scoped_disable_commit_resumed. * process-stratum-target.h (class process_stratum_target): <commit_resumed_state>: New. * record-full.c (record_full_wait_1): Change commit_resumed_state around calling commit_resumed. * remote.c (class remote_target) <commit_resume>: Rename to... <commit_resumed>: ... this. (struct stop_reply): Move up. (remote_target::commit_resume): Rename to... (remote_target::commit_resumed): ... this. Check if there is any thread pending vCont resume. (remote_target::remote_stop_ns): Generate stop replies for resumed but pending vCont threads. (remote_target::wait_ns): Add gdb_assert. * target-delegates.c: Regenerate. * target.c (target_wait, target_resume): Assert that the current process_stratum target isn't in commit-resumed state. (defer_target_commit_resume): Remove. (target_commit_resume): Remove. (target_commit_resumed): New. (make_scoped_defer_target_commit_resume): Remove. (target_stop): Assert that the current process_stratum target isn't in commit-resumed state. * target.h (struct target_ops) <commit_resume>: Rename to ... <commit_resumed>: ... this. (target_commit_resume): Remove. (target_commit_resumed): New. (make_scoped_defer_target_commit_resume): Remove. * top.c (wait_sync_command_done): Use scoped_enable_commit_resumed. [1] https://github.com/ROCm-Developer-Tools/ROCgdb/ [2] https://github.com/ROCm-Developer-Tools/ROCdbgapi Change-Id: I836135531a29214b21695736deb0a81acf8cf566