aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
11 hours[gdb/contrib] Avoid NotImplementedError in dwarf-to-dwarf-assembler.pyHEADmasterTom de Vries1-1/+1
The previous commit mentions: ... File "dwarf-to-dwarf-assembler.py", line 173, in _format_value raise NotImplementedError(f"Unknown data type: {type(self.value)}") NotImplementedError: Unknown data type: <class 'elftools.construct.lib.container.ListContainer'> ... While the NotImplementedError makes its point clear, it's unhelpful in two ways: - it's hard to find out what part of the input causes the error, and - it may be that the user is not interested at all in the bit triggering the error, but some part after it, and the error prevents the user from seeing it Fix this by returning an error string instead of raising an error, resulting in this output: ... DW_AT_upper_bound Unknown data type: <class 'elftools.construct.lib.container.ListContainer'>: \ [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255] DW_FORM_data16 ... Approved-By: Tom Tromey <tom@tromey.com>
11 hours[gdb/contrib] Handle DW_FORM_data16 in dwarf-to-dwarf-assembler.pyTom de Vries1-0/+3
I ran gdb/contrib/dwarf-to-dwarf-assembler.py on testsuite executable gdb.ada/task_bp/foo, and ran into: ... Traceback (most recent call last): File "dwarf-to-dwarf-assembler.py", line 660, in <module> main(sys.argv) ~~~~^^^^^^^^^^ File "dwarf-to-dwarf-assembler.py", line 656, in main generator.generate() ~~~~~~~~~~~~~~~~~~^^ File "dwarf-to-dwarf-assembler.py", line 628, in generate self.generate_die(die, indent_count) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^ File "dwarf-to-dwarf-assembler.py", line 607, in generate_die die_lines = die.format(self.dwarf_parser.offset_to_die, indent_count) File "dwarf-to-dwarf-assembler.py", line 297, in format return "\n".join(self.format_lines(offset_die_lookup, indent_count)) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "dwarf-to-dwarf-assembler.py", line 394, in format_lines inner_lines = super().format_lines(offset_die_lookup, indent_count + 1) File "dwarf-to-dwarf-assembler.py", line 285, in format_lines child_lines = child.format_lines( offset_die_lookup, indent_count=indent_count + 1 ) File "dwarf-to-dwarf-assembler.py", line 269, in format_lines attr_line = attr.format( offset_die_lookup, indent_count=indent_count + 1 ) File "dwarf-to-dwarf-assembler.py", line 219, in format s += self._format_value(offset_die_lookup) ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^ File "dwarf-to-dwarf-assembler.py", line 173, in _format_value raise NotImplementedError(f"Unknown data type: {type(self.value)}") NotImplementedError: Unknown data type: <class 'elftools.construct.lib.container.ListContainer'> ... when trying to print the DW_FORM_data16 constant for this upper bound: ... <1><3af88>: Abbrev Number: 47 (DW_TAG_subrange_type) <3af89> DW_AT_lower_bound : 0 <3af89> DW_AT_upper_bound : 0xffffffffffffffffffffffffffffffff <3af99> DW_AT_name : system__put_images__lll_integer_images__unsigned_typeXn ... Fix this by handling elftools.construct.lib.container.ListContainer. Approved-By: Tom Tromey <tom@tromey.com>
11 hours[gdb/contrib] Handle DW_LANG_Mips_Assembler in dwarf-to-dwarf-assembler.pyTom de Vries1-1/+7
I ran gdb/contrib/dwarf-to-dwarf-assembler.py on a hello world executable, and ran into: ... Traceback (most recent call last): File "dwarf-to-dwarf-assembler.py", line 654, in <module> main(sys.argv) ~~~~^^^^^^^^^^ File "dwarf-to-dwarf-assembler.py", line 650, in main generator.generate() ~~~~~~~~~~~~~~~~~~^^ File "dwarf-to-dwarf-assembler.py", line 622, in generate self.generate_die(die, indent_count) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^ File "dwarf-to-dwarf-assembler.py", line 601, in generate_die die_lines = die.format(self.dwarf_parser.offset_to_die, indent_count) File "dwarf-to-dwarf-assembler.py", line 291, in format return "\n".join(self.format_lines(offset_die_lookup, indent_count)) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "dwarf-to-dwarf-assembler.py", line 388, in format_lines inner_lines = super().format_lines(offset_die_lookup, indent_count + 1) File "dwarf-to-dwarf-assembler.py", line 263, in format_lines attr_line = attr.format( offset_die_lookup, indent_count=indent_count + 1 ) File "dwarf-to-dwarf-assembler.py", line 209, in format s += "@" + LANG_NAME[self.value] ~~~~~~~~~^^^^^^^^^^^^ KeyError: 32769 ... The problem is that the language 0x8001 (DW_LANG_lo_user + 1) is not listed in elftools.dwarf.enums.ENUM_DW_LANG. This is MIPS vendor extension DW_LANG_MIPS_assembler, commonly used for any assembly in DWARF versions that don't define a value for it (starting v6, there's DW_LANG_Assembly). Fix the generic case by emitting: ... DW_AT_language 32769 DW_FORM_sdata ... and this specific case by emitting: ... DW_AT_language @DW_LANG_Mips_Assembler ... Approved-By: Tom Tromey <tom@tromey.com>
12 hoursRemove minimal_symbol_reader::recordTom Tromey2-42/+0
After the various symbol reader removals, it seems that minimal_symbol_reader::record is no longer needed. Approved-By: Simon Marchi <simon.marchi@efficios.com>
13 hoursgdb/python: accept gdbpy_ref in init helpers and return boolMatthieu Longo2-26/+23
Passing 'gdbpy_ref<> &' instead of raw 'PyObject *' to init helpers makes ownership of PyObject clearer at call sites, and removes unnecessary '.get()' calls. Changing the return type from 'int' to 'bool' improves readability and better expresses the success/failure semantics. Approved-By: Tom Tromey <tom@tromey.com>
26 hoursAutomatic date update in version.inGDB Administrator1-1/+1
28 hoursz80: use signed char for relative offsetAlan Modra1-5/+2
A char is signed on some hosts, unsigned on others. * z80-dis.c (prt_e): Don't use plain char for offset.
28 hoursupdate libiberty changelogAlan Modra1-0/+29
The gcc project updates ChangeLog files daily from git commit logs. Update libiberty/Changelog so the binutils copy matches.
28 hourslibiberty: Copy over .ARM.attributes section into *.debug.temp.o files ↵Jakub Jelinek1-0/+4
[PR124365] If gcc is configured on aarch64-linux against new binutils, such as 2.46, it doesn't emit into assembly markings like .section .note.gnu.property,"a" .align 3 .word 4 .word 16 .word 5 .string "GNU" .word 0xc0000000 .word 4 .word 0x7 .align 3 but instead emits .aeabi_subsection aeabi_feature_and_bits, optional, ULEB128 .aeabi_attribute Tag_Feature_BTI, 1 .aeabi_attribute Tag_Feature_PAC, 1 .aeabi_attribute Tag_Feature_GCS, 1 The former goes into .note.gnu.propery section, the latter goes into .ARM.attributes section. Now, when linking without LTO or with LTO but without -g, all behaves for the linked binaries the same, say for test.c int main () {} $ gcc -g -mbranch-protection=standard test.c -o test; readelf -j .note.gnu.property test Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: AArch64 feature: BTI, PAC, GCS $ gcc -flto -mbranch-protection=standard test.c -o test; readelf -j .note.gnu.property test Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: AArch64 feature: BTI, PAC, GCS $ gcc -flto -g -mbranch-protection=standard test.c -o test; readelf -j .note.gnu.property test readelf: Warning: Section '.note.gnu.property' was not dumped because it does not exist The problem is that the *.debug.temp.o object files created by lto-wrapper don't have these markings. The function copies over .note.GNU-stack section (so that it doesn't similarly on most arches break PT_GNU_STACK segment flags), and .note.gnu.property (which used to hold this stuff e.g. on aarch64 or x86, added in PR93966). But it doesn't copy the new .ARM.attributes section. The following patch fixes it by copying that section too. The function unfortunately only works on names, doesn't know if it is copying ELF or some other format (PE, Mach-O) or if it is copying ELF, whether it is EM_AARCH64 or some other arch. The following patch just copies the section always, I think it is very unlikely people would use .ARM.attributes section for some random unrelated stuff. If we'd want to limit it to just EM_AARCH64, guess it would need to be done in libiberty/simple-object-elf.c (simple_object_elf_copy_lto_debug_sections) instead as an exception for the (*pfn) callback results (and there it could e.g. verify SHT_AARCH64_ATTRIBUTES type but even there dunno if it has access to the Ehdr stuff). No testcase from me, dunno if e.g. the linker can flag the lack of those during linking with some option rather than using readelf after link and what kind of effective targets we'd need for such a test. 2026-03-05 Jakub Jelinek <jakub@redhat.com> PR target/124365 * simple-object.c (handle_lto_debug_sections): Also copy over .ARM.attributes section.
28 hourslibiberty: fix resource exhaustion in rust demangler (PR demangler/106641)Ruslan Valiyev2-1/+14
demangle_binder() parses the bound_lifetimes count as a base-62 integer with no upper bound. A crafted symbol can encode a huge lifetime count in very few bytes, causing OOM or CPU hang. Cap bound_lifetimes at 1024 and check rdm->errored in the loop so it bails out early on errors during iteration. libiberty/ChangeLog: PR demangler/106641 * rust-demangle.c (demangle_binder): Reject bound_lifetimes above 1024 to prevent resource exhaustion from crafted symbols. Add rdm->errored check in the loop condition. * testsuite/rust-demangle-expected: Add regression test. Signed-off-by: Ruslan Valiyev <linuxoid@gmail.com>
28 hourslibiberty, Darwin: Fix handling of file offsets.Iain Sandoe1-1/+2
In the case where a Mach-O object is embedded inside some container (e.g. an archive) we must account the offset from the start of that container when reading. In most cases, this has been done correctly. However, we were missing the case for reading segment data. This only showed up once we tried using archives (since regular Mach-O objects start at the begining of the file). Fixed thus. libiberty/ChangeLog: * simple-object-mach-o.c (simple_object_mach_o_segment): Account for the offset of this Mach-O object from the start of any container. Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
28 hourslibiberty: Preserve `errno` across calls to `libiberty_vprintf_buffer_size()`LIU Hao1-2/+18
The MSVCRT `strtoul()` function resets `errno` to zero upon success. On such a system, `libiberty_vprintf_buffer_size()` could clobber `errno` like this: MINGW64 ~ $ ld nonexistent.file C:\MSYS64\mingw64\bin\ld.exe: cannot find nonexistent.file: No error libiberty/ChangeLog: * vprintf-support.c (do_strtoul): New function. (libiberty_vprintf_buffer_size): Replace `strtoul` with `do_strtoul`. Signed-off-by: LIU Hao <lh_mouse@126.com>
2 daysAutomatic date update in version.inGDB Administrator1-1/+1
2 daysRemove bfd_boolean definition from bfdAlan Modra2-28/+0
It has been almost 5 years since I started retiring bfd_boolean. Remove it entirely.
2 daysRemove bfd_boolean from simAlan Modra5-20/+20
Replace a few vestiges of bfd_boolean in sim with bool, and FALSE/TRUE with false/true where the type is clearly bool.
2 daysRemove bfd_boolean from gdbAlan Modra6-12/+12
Replace a few vestiges of bfd_boolean in gdb with bool. I haven't tried to replace FALSE/TRUE in gdb except when the type was clearly bool. There may well be other occurrences of FALSE or TRUE that ought to be tidied. Source that uses BOOL or a typedef enum boolean in particular isn't changed.
3 days[pre-commit] Bump black to 26.3.0Tom de Vries1-1/+1
Ran "pre-commit autoupdate". No changes in formatting.
3 daysgas/doc: clarify internal symbol vs local symbol terminologyFangrui Song1-47/+50
In ELF, "local symbols" refer to symbols of STB_LOCAL binding. The doc is inconsistent: while it uses "local symbol" in places like .local, "local symbols" are also used for .L-prefixed symbols (as determined by bfd_is_local_label). Rename "Local Symbol Names" to "Internal Symbol Names" for .L-prefixed symbols, and rename "Local Labels" to "Numeric Local Labels" for N:/Nb/Nf numeric labels. This avoids confusion with ELF STB_LOCAL "local symbols". The term "internal symbol" is chosen over alternatives like "temporary symbol" because it describes the purpose of these symbols: they are for internal use by compilers and assemblers, not meant to be visible externally (albeit they can become visible in certain situations). While ELF defines STV_INTERNAL as a symbol visibility, it is rarely used in practice and unlikely to cause confusion (only used by SGI for their link-time interprocedural optimization; useless on other OSes).
3 daysRemove bfd_boolean from gas and gprofngAlan Modra5-43/+43
A few uses have crept back in, replace with bool. Also replace FALSE/TRUE with false/true.
3 daysppc-opc.c non-ascii stringAlan Modra1-1/+1
Fix a gettext complaint. * ppc-opc.c (insert_sr): Don't use non-ascii dash.
3 daysAutomatic date update in version.inGDB Administrator1-1/+1
3 daysFix debug_names function visibilityTom Tromey5-0/+5
A few test cases that emit custom DWARF with debug_names had a discrepancy between the debug info and the debug names. In particular a function would be marked private in the info: subprogram { DW_AT_name _start DW_AT_low_pc $_start_start DW_FORM_addr DW_AT_high_pc $_start_end DW_FORM_addr } (Note there's no DW_AT_external) ... but be marked public in the names: debug_names {} { ... name _start subprogram CU-1 0xEDDB6232 (Note there's no DW_IDX_GNU_internal) I believe these test cases worked by accident; that is, taking an unusual path through the code to still get the right output. This patch fixes these tests to be self-consistent.
3 daysgas: pru: Add TSEN and MVI instructionsDimitar Dimitrov8-5/+236
Add support for TSEN and MVI instructions to GAS and libopcodes. TSEN is available in newer PRU core revisions, and can be used to implement multitasking. MVI allows indirectly addressing CPU registers using a pointer in R1 register. References: - https://www.ti.com/lit/ug/spruij2/spruij2.pdf Chapter "Move Register File Indirect (MVIx)" - https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1426480/am2431-pru-assembly-instruction-user-guide Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
4 daysld: clarify comments on /DISCARD/ output section behaviorMatthieu Longo2-6/+25
The previous comments made it difficult to understand how the /DISCARD/ output section interacts with non-contiguous regions. In summary, the general rule is that the first (top-most) clause takes precedence over subsequent ones: - If /DISCARD/ appears first, the section is dropped. There is no need to warn about potential behavior changes with non-contiguous regions when the section is already discarded. - If /DISCARD/ follows clauses that assign the input section to an output section, /DISCARD/ is ignored. If the input section can't be assigned to the output section for a later reason, an error will be raised. Otherwise the input section will be assigned as intended to an output section specified by one of the matching clauses previous to /DISCARD/.
4 daysaarch64: add tests for non-contiguous memory regionsMatthieu Longo28-0/+940
This patch adds AArch64 test cases for all non-contiguous memory scenarios. Those tests were copy-pasted from AArch32, and adapted for AArch64. It also adds a new test case inspired from a real case where several sections containing interrupt vector tables, declared in different compilation units, and all aligned on 2KB, are supposed to be merged into one output section fitting on 2KB memory.
4 daysld: fix segfault on discarded input sections not fitting in memory regionsMatthieu Longo3-26/+37
In the case of non-contiguous memory regions, if an input section did not fit in any of the designated memory regions, the linker marked it as discarded, and warn_non_contiguous_discards() would only issue warning on it, relying on later unresolved symbol errors to terminate the process before a crash occur. This approach was insufficient, and crashes did occur on AArch64. This patch renames warn_non_contiguous_discards () to a name that does not contain "discard" as it created some confusion with the /DISCARD/ output section. It also promotes the warnings to errors, and ensures that the link process terminates cleanly if any input section is not allocated to an output section. It also updates an AArch32 test's expectations to match the corrected behavior. Tests for the crash cases are added in a subsequent patch. Finally, it adds some patterns to /DISCARD/ in ld-elf/non-contiguous.ld. Before this patch, a section which was not assigned to an output section because no pattern matched, did not raise any error. Approved-By: Jan Beulich <jbeulich@suse.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31412
4 daysexplicitly state code assumptions on output section in AArch64 ld handlersMatthieu Longo1-0/+2
When support for non-contiguous memory was added, some corner cases when sections were removed from the output object, did not emit fatal error and reached code paths that correctly assumed every input section had a valid output section, and this led to crashes due to segfault. This patch adds BFD_ASSERTs in the previously segfaulting code, to explicitly state code assumptions.
4 daysld: fix segfault caused by untagged stub sectionsMatthieu Longo9-10/+34
In the case of non-contiguous memory regions, a far-call stub section must be assigned to the memory of the section it was originally emitted for. If the stub section does not fit, the section is marked as dropped, and removed later. To emit a useful message to the user, however, a stub section needs to be discernible from sections originating from input objects. Previously [1], this distinction was made using the SEC_LINKER_CREATED flag only in the AArch32 backend handler <arch>_add_stub_section. Other backends that didn't set this flag on their stub sections skipped required checks in ld/ldlang.c:size_input_section(). On AArch64, this caused the linker to proceed into code paths that assumed output sections were set, instead of reporting fatal errors, and ultimately led to a segmentation fault. However, the SEC_LINKER_CREATED flag does not solely indicate that a section was created by the linker. Its original meaning also meant that the section should not be handled by the generic relocation code. Reusing this flag to identify stub sections, while it appeared to fix the issue, introduced unintended side effects. On PowerPC, for instance, it skipped relocations present in the stubs and interpreted them as absolute addresses. This patch proposes a new attribute 'veneer', indicating that a section contains branch veneers. The attribute is set on AArch32, AArch64 and PowerPC immediately after the creation of the stub section. Others architectures are left unchanged, as they do not appear to support non-contiguous memory regions (no tests were found to verify the fix). Additionally, the diagnostic message was improved when a stub cannot be placed in the same memory region as its referencing code. Approved-By: Jan Beulich <jbeulich@suse.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31412 [1]: abf874a, Add support for non-contiguous memory regions.
4 days[pre-commit] Bump codespell to 2.4.2Tom de Vries2-9/+3
Ran "pre-commit autoupdate". Doing "pre-commit run --all-files codespell" still passes. Now that ignore-multiline-regex is fixed, enable ignoring blocks of code using codespell:ignore-begin/codespell:ignore-end.
4 daysAutomatic date update in version.inGDB Administrator1-1/+1
4 daysgdb: rename blockvec to rangevec in dwarf2_record_block_rangesJan Vrany1-3/+3
This commit just renames local variable blockvec to rangevec. It seems to me that rangevec is better name since it holds on struct blockrange. Approved-By: Tom Tromey <tom@tromey.com>
4 days[gdb/symtab] Replace per-BFD lock with global BFD lockTom de Vries1-19/+4
Our current BFD locking scheme is as follows [1]: ... There is one global mutex, gdb_bfd_mutex, which BFD can lock and unlock via the callbacks we pass it. This appears to lock the internal global data structures of BFD (like its global cache or some global counter), but not data in individual `bfd *`instances. If the user of BFD wishes to call functions on a given `bfd *` from multiple threads, it must provide the synchronization itself. For this, we have gdb_bfd_data::per_bfd_mutex. ... PR33811 reports the following data race: ... Read of size 1 at 0x72440010c608 by thread T5 (mutexes: write M0): #0 bfd_get_section_limit_octets bfd.h:2433 #1 bfd_get_section_contents bfd/section.c:1612 #2 bfd_is_section_compressed_info bfd/compress.c:901 #3 bfd_is_section_compressed bfd/compress.c:959 #4 gdb_bfd_map_section(bfd_section*, unsigned long*) gdb/gdb_bfd.c:779 ... vs: ... Previous write of size 4 at 0x72440010c608 by main thread (mutexes: write M1): #0 bfd_cache_delete bfd/cache.c:180 #1 _bfd_cache_close_unlocked bfd/cache.c:607 #2 bfd_cache_close_all bfd/cache.c:664 #3 notify_before_prompt gdb/event-top.c:524 ... In more detail, this read in bfd_get_section_limit_octets in bfd/bfd-in2.h: ... if (abfd->direction != write_direction && sec->rawsize != 0) ... vs. this write in bfd_cache_delete in bfd/cache.c: ... abfd->last_io = bfd_io_force; ... There is already locking used for both the read and write. In gdb_bfd_map_section, we use the per-BFD lock: ... gdb_bfd_data *gdata = (gdb_bfd_data *) bfd_usrdata (abfd); gdb::lock_guard<gdb::mutex> guard (gdata->per_bfd_mutex); ... And in bfd_cache_close_all, we use the global BFD lock: ... bool bfd_cache_close_all (void) { ... if (!bfd_lock ()) return false; ... if (!bfd_unlock ()) return false; return ret; } ... The problem is that the locking is not sufficient. Since bfd_cache_close_all accesses individual BFDs, it needs to lock the corresponding per-BFD locks as well. A naive way to implement this using the existing scheme of wrappers, would be to add a gdb_bfd_cache_close_all that locks all per-BFD locks, calls bfd_cache_close_all, and unlocks all per-BFD locks, like this: ... bool gdb_bfd_cache_close_all () { bool res; for (auto abfd : all_bfds) { auto gdata = static_cast<gdb_bfd_data *> (bfd_usrdata (abfd)); gdata->per_bfd_mutex.lock (); } res = bfd_cache_close_all (); for (auto abfd : all_bfds) { auto gdata = static_cast<gdb_bfd_data *> (bfd_usrdata (abfd)); gdata->per_bfd_mutex.unlock (); } return res; } ... Apart from the fact that trying to hold all those locks at the same time increases the changes of deadlock, it also accesses all_bfds without locking the required global BFD lock (reported by TSAN). It's easy enough to fix that by adding: ... gdb_bfd_cache_close_all () { + gdb::lock_guard<gdb::recursive_mutex> guard (gdb_bfd_mutex); ... but that brings us to the problem of lock-order-inversion (also reported by TSAN), and indeed timeouts do occur. I came up with a complicated scheme [2] that: - doesn't try to lock all the per-BFD locks at the same time, and - addresses the lock-order-inversion problem by releasing the global BFD lock before acquiring the per-BFD lock and then re-acquiring the global BFD lock However, this approach was seen as too convoluted. So instead, revert to a simple locking scheme with only the global BFD lock, dropping the per-BFD lock. This changes the per-BFD locking in gdb_bfd_map_section to global BFD locking, which means that the read in bfd_get_section_limit_octets is now guarded by the global BFD lock, which is the same lock guarding the write in bfd_cache_delete. So, the race is fixed. Approved-By: Tom Tromey <tom@tromey.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33811 [1] https://sourceware.org/pipermail/gdb-patches/2026-January/224291.html [2] https://sourceware.org/pipermail/gdb-patches/2026-January/224426.html
4 days[gdb/testsuite] Fix gdb.opt/inline-entry.exp with clangTom de Vries1-0/+18
I ran test-case gdb.opt/inline-entry.exp with clang, more specifically: ... get_compiler_info: clang-17-0-6 ... and ran into: ... (gdb) continue^M Continuing.^M ^M Breakpoint 2.1, bar (val=<optimized out>) at inline-entry.c:29^M 29 if (global == val)^M (gdb) PASS: gdb.opt/inline-entry.exp: continue to bar continue^M Continuing.^M ^M Breakpoint 2.3, bar (val=2) at inline-entry.c:29^M 29 if (global == val)^M (gdb) FAIL: gdb.opt/inline-entry.exp: continue to foo continue^M Continuing.^M ^M Breakpoint 3, foo (arg=arg@entry=1) at inline-entry.c:23^M 23 global += arg;^M (gdb) FAIL: gdb.opt/inline-entry.exp: continue until exit ... The problem is that the test-case expects two breakpoint locations for function bar, and to hit one of them, but there are three and it hits two of them. This is due to the debug info, which for function bar: ... <1><25d>: Abbrev Number: 7 (DW_TAG_subprogram) <25e> DW_AT_name : bar <25f> DW_AT_decl_file : 1 <260> DW_AT_decl_line : 27 <261> DW_AT_prototyped : 1 <261> DW_AT_type : <0x243> <265> DW_AT_external : 1 <265> DW_AT_inline : 1 (inlined) <2><265>: Abbrev Number: 8 (DW_TAG_formal_parameter) <266> DW_AT_name : val <267> DW_AT_decl_file : 1 <268> DW_AT_decl_line : 27 <269> DW_AT_type : <0x243> ... has three corresponding DW_TAG_inlined_subroutine DIEs: ... <2><27d>: Abbrev Number: 10 (DW_TAG_inlined_subroutine) <27e> DW_AT_abstract_origin: <0x25d> <282> DW_AT_ranges : 0x31 <283> DW_AT_call_file : 1 <284> DW_AT_call_line : 38 <2><285>: Abbrev Number: 11 (DW_TAG_inlined_subroutine) <286> DW_AT_abstract_origin: <0x25d> <28a> DW_AT_low_pc : 0x114f <28b> DW_AT_high_pc : 0x5 <28f> DW_AT_call_file : 1 <290> DW_AT_call_line : 38 <291> DW_AT_call_column : 18 <3><292>: Abbrev Number: 12 (DW_TAG_formal_parameter) <293> DW_AT_const_value : 1 <294> DW_AT_abstract_origin: <0x265> <2><299>: Abbrev Number: 11 (DW_TAG_inlined_subroutine) <29a> DW_AT_abstract_origin: <0x25d> <29e> DW_AT_low_pc : 0x1166 <29f> DW_AT_high_pc : 0x7 <2a3> DW_AT_call_file : 1 <2a4> DW_AT_call_line : 38 <2a5> DW_AT_call_column : 30 <3><2a6>: Abbrev Number: 12 (DW_TAG_formal_parameter) <2a7> DW_AT_const_value : 2 <2a8> DW_AT_abstract_origin: <0x265> ... while the source contains just two calls: ... 35 int 36 main (void) 37 { 38 if ((global && bar (1)) || bar (2)) 39 return 0; 40 return 1; 41 } ... This is a bug in the debug info. I don't see a way to work around this in gdb, so work around this in the test-case by bailing out if there are more or less than two breakpoint locations for function bar. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33953
4 daysgdb/python: fix gdb.FinishBreakpoint returning to a tail call frameAndrew Burgess2-5/+27
I noticed that gdb.FinishBreakpoint doesn't work if the parent function is a tail call function. In bpfinishpy_init we use get_frame_pc to find the address at which the finish breakpoint should be placed within the previous frame. However, if the previous frame is a tail call frame, then get_frame_pc will return an address outside of the tail call function, an address which will not be reached on the return path. Unlike other recent tail call fixes I've made, we cannot switch to using something like get_frame_address_in_block here as in the tail call case this will return an address within the function, but not an address that will be executed when we return. What we need to do in the tail call case is create the finish breakpoint in the frame that called the tail call function. Or if that frame is itself a tail call, then we should walk back up the call stack until we find a non-tail call function. This can be achieved by adding a call to skip_tailcall_frames into bpfinishpy_init after our existing call to get_prev_frame. I've extended the existing test case to cover this additional situation. Approved-By: Tom Tromey <tom@tromey.com>
4 daysgdb/python: don't allow FinishBreakpoints for inline framesAndrew Burgess5-1/+242
Creating a Python gdb.FinishBreakpoint for an inline frame doesn't work. If we look at the 'finish' command, in the finish_command function (infcmd.c) then we see that GDB handles inline frames very different to non-inline frames. For non-inline frames GDB creates a temporary breakpoint and then resumes the inferior until the breakpoint is hit. But for inline frames, GDB steps forward until we have left the inline frame. When it comes to gdb.FinishBreakpoint we only have the "create a temporary breakpoint" mechanism; that is, after all, what the FinishBreakpoint is, it's a temporary breakpoint placed at the return address in the caller. Currently, when a FinishBreakpoint is created within an inline frame, GDB ends up creating the breakpoint at the current $pc. As a result the breakpoint will not be hit before the current function exits (unless there's a loop going on, but that's not the point). We could imagine what a solution to this problem would look like, GDB would need to figure out the set of addresses for all possible exit points from the inline function, and place a breakpoint at each of these locations. I don't propose doing that in this commit. Instead, I plan to update the docs to note that creating a FinishBreakpoint within an inline frame is not allowed, and I will catch this case within bpfinishpy_init (python/py-finishbreakpoint.c) and throw an error. Though the error is new, all I'm doing is raising an error for a case that never worked. There's a new test to cover this case. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=18339 Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
4 daysgdb/python: fix FinishBreakpoint.return_value for tail call functionsAndrew Burgess3-4/+11
The FinishBreakpoint.return_value attribute will not be populated correctly for tail call functions. In bpfinishpy_init (python/py-finishbreakpoint.c) we use the function get_frame_pc_if_available to return an address, and then use this address to lookup a function symbol. The problem is that, for tail call functions, the address returned by get_frame_pc_if_available can be outside the bounds of the function, as a result GDB might find no function symbol at all, or might find the wrong function symbol, if the tail call function is immediately adjacent to the next function. Fix this by using get_frame_address_in_block_if_available instead. For tail call functions this will return an address within the bounds of the function, which means that GDB should find the correct function symbol, and from this the correct return type. I've extended the existing FinishBreakpoint with tail call test case to include printing the return value, this test fails without this patch, but now works. Approved-By: Tom Tromey <tom@tromey.com>
4 daysgdb: fix frame_unwind_caller_WHAT functions for inline and tail callsAndrew Burgess6-11/+349
The 3 frame_unwind_caller_WHAT functions: + frame_unwind_caller_id + frame_unwind_caller_pc + frame_unwind_caller_arch Are, I believe, currently all broken with respect to inline and tail call functions. The Python FinishBreakpoint type creates a breakpoint in the caller function which, when triggered, indicates that the FinishBreakpoint has gone out of scope. I was writing a test for the FinishBreakpoint type which included a tail call function, and the FinishBreakpoint was being created for the tail call function frame. What I observed is that the out of scope breakpoint was never being hit. The call stack in my new test looked like this: main -> tailcall_function -> normal_function I would stop in normal_function, and then create a FinishBreakpoint for the parent (tailcall_function) frame. The FinishBreakpoint's out of scope breakpoint was being correctly placed in the 'main' function, but would never trigger. The problem is that the breakpoint placed in 'main' holds a frame-id. This frame-id is the frame in which the breakpoint should trigger. This frame-id exists to prevent premature stops due to recursion. But in this case, when the breakpoint in 'main' was hit, despite no recursion having occurred, the frame-id didn't match, and so the breakpoint was ignored. The problem is that in bpfinishpy_init we call frame_unwind_caller_id to compute the frame-id of the frame in which we should stop, and frame_unwind_caller_id was returning the wrong frame-id. As far as I can tell frame_unwind_caller_id has been broken since it was updated for inline functions in commit edb3359dff90ef8a. The frame_unwind_caller_id function, and all the frame_unwind_caller_WHAT functions, are intended to return the previous frame, but should skip over any inline, or tail call frames. Let's look at an example call stack: #0 A // A normal function. #1 B // An inline function. #2 C // An inline function. #3 D // A normal function. #4 E // A normal function. Starting from #0, a normal function, frame_unwind_caller_id, should return the frame-id for #3, and this is what happens. But if we start in #1 and call frame_unwind_caller_id, then we should still return the frame-id for #3, but this is not what happens. Instead we return the frame-id for #4, skipping a frame. The problem is that frame_unwind_caller_id starts by calling skip_artificial_frames, which calls get_prev_frame_always until we reach a non-inline (or non-tail call) frame, this moves us from #1 to Then, back in frame_unwind_caller_id we call get_prev_frame_always, which moves us to #4. Then frame_unwind_caller_id finishes with a call to skip_artificial_frames, this could potentially result in additional frames being skipped, but in my example above this isn't the case. The problem here is that if skip_artificial_frames skips anything, then we have already unwound to the caller frame, and the get_prev_frame_always call in frame_unwind_caller_id is unnecessary. I propose to add a new helper function frame_unwind_caller_frame, which should do the correct thing; it unwinds one frame and then calls skip_artificial_frames. This should do exactly what is needed. Then all the frame_unwind_caller_WHAT functions will be updated to use this helper function, and just extract the required property from the resulting frame. With this fix in place I could then write the FinishBreakpoint test, which now works. I took a look for other places where frame_unwind_caller_id is used and spotted that the 'until' command does much the same thing, placing a breakpoint in the caller frame. As predicted, the 'until' command is also broken when used within a tail call frame. This patch fixes that issue too. There's also a test for the until command. The bug PR gdb/28683 seems to describe this exact problem with a specific AArch64 case given. I haven't actually setup the environment needed to test this bug, but I'm reasonably sure that this patch will fix the bug. Even if it doesn't then it's certainly related and worth linking into the bug report. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28683 Approved-By: Tom Tromey <tom@tromey.com>
4 days[gdb/testsuite] Fix flake8 error in gdb.python/py-selected-context.pyTom de Vries1-2/+0
We currently are running into a flake8 error: ... $ pre-commit run --all-files flake8 flake8..................................................................Failed - hook id: flake8 - exit code: 1 gdb/testsuite/gdb.python/py-selected-context.py:24:5: \ F824 `global event_throws_error` is unused: name is never assigned in scope ... Fix this by dropping the unnecessary "global event_throws_error". Tested on x86_64-linux.
4 days[gdb/testsuite] Fix gdb.python/py-selected-context.exp with glibc debuginfoTom de Vries1-1/+2
With test-case gdb.python/py-selected-context.exp, I run into: ... (gdb) thread 1 [Switching to thread 1.1 (Thread 0x7ffff7cc0080 (LWP 1793477))] 57 return INTERNAL_SYSCALL_CANCEL (... Python Exception <class 'gdb.GdbError'>: error from gdb_selected_context_handler (gdb) FAIL: $exp: switch thread, handler raises an error ... The regexp doesn't expect the source line, which indeed is not printed if I de-install glibc debuginfo. Fix this by updating the regexp. Tested on x86_64-linux.
4 daysgdb: remove last_examine_addressTankut Baris Aktemur1-8/+5
Remove the global variable `last_examine_address`. It can be obtained from another global variable, `last_examine_value`. Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Tom Tromey <tom@tromey.com>
4 daysgdb: use builtin_func_ptr for `$_` set by "x/i"Tankut Baris Aktemur2-7/+21
The 'x' command with the 'i' format specifier is for displaying instructions. The "last address examined" convenience var, that is '$_', is set to a single byte pointer by "x/i": (gdb) p $pc $1 = (void (*)()) 0x5555555551d4 <main+15> (gdb) x/i $pc => 0x5555555551d4 <main+15>: movl $0x2a,-0x4(%rbp) (gdb) p $_ $2 = (int8_t *) 0x5555555551d4 <main+15> (gdb) However, because "x/i" is for displaying instructions, it makes more sense to give '$_' a code pointer type, which is done by this patch: (gdb) p $pc $1 = (void (*)()) 0x5555555551d4 <main+15> (gdb) x/i $pc => 0x5555555551d4 <main+15>: movl $0x2a,-0x4(%rbp) (gdb) p $_ $2 = (void (*)()) 0x5555555551d4 <main+15> (gdb) This is a minor user experience improvement and should not change functionality. Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Tom Tromey <tom@tromey.com>
4 daysgdb: use builtin_func_ptr for `$_` set by "info breakpoints" and "info line"Tankut Baris Aktemur4-4/+22
The `$_` convenience var, as set by the "info breakpoints" and "info line" commands, has the type builtin_data_ptr (i.e. `void *`). However, both of the aforementioned commands deal with code addresses. Hence, it makes more sense to use builtin_func_ptr (i.e. `void (*)()`). With this change: (gdb) b main Breakpoint 2 at 0x402547: file test.cpp, line 20. (gdb) info breakpoints Num Type Disp Enb Address What 2 breakpoint keep y 0x0000000000402547 in main(int, char**) at test.cpp:20 (gdb) p $_ $2 = (void (*)(void)) 0x402547 <main(int, char**)+39> (gdb) ptype $_ type = void (*)(void) (gdb) ptype &main type = int (*)(int, char **) (gdb) info line 22 Line 22 of "test.cpp" starts at address 0x40256d <main(int, char**)+77> and ends at 0x4025bd <main(int, char**)+157>. (gdb) p $_ $3 = (void (*)(void)) 0x40256d <main(int, char**)+77> (gdb) ptype $_ type = void (*)(void) (gdb) This also matches the type of PC: (gdb) ptype $pc type = void (*)(void) Also add test cases to check that "info breakpoints" and "info line" set the `$_` var. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Tom Tromey <tom@tromey.com>
4 daysgdb: update doc for the $_ variable and search commandsTankut Baris Aktemur1-5/+13
I noticed that forward-search and reverse-search commands set the $_ convenience variable. This is mentioned in the help menu (see below) but is not stated in the documentation. Add related text to the doc. (gdb) help search forward-search, fo, search Search for regular expression (see regex(3)) from last line listed. The matching line number is also stored as the value of "$_". (gdb) help rev reverse-search, rev Search backward for regular expression (see regex(3)) from last line listed. The matching line number is also stored as the value of "$_". (gdb) Reviewed-By: Eli Zaretskii <eliz@gnu.org> Reviewed-By: Keith Seitz <keiths@redhat.com> Approved-By: Tom Tromey <tom@tromey.com>
4 daysgdbserver: require_running_or_break for the 'z' and 'vCont' packetsTankut Baris Aktemur2-0/+74
Similar to several other packages that access/modify process state, the 'z'/'Z' and 'vCont' packets need to access the process. Hence, add a `require_running_or_break` as a pre-check. Also add a test to check that gdbserver does not crash when certain packets are received while there does not exist a process. Approved-By: Tom Tromey <tom@tromey.com>
5 daysgdb/python: introduce gdb.Symtab.source_lines methodAndrew Burgess8-5/+454
This commit adds a new method gdb.Symtab.source_lines. This method can be used to read the lines from a symtab's source file. This is similar to GDB's internal source_cache::get_source_lines function. Currently using the Python API, if a user wants to display source lines then they need to use Symtab.fullname() to get the source file name, then open this file and parse out the lines themselves. This isn't too much effort, but the problem is that these lines will not be styled. The user could style the source content themselves, but will this be styled exactly as GDB would style it? The new Symtab.source_lines() method returns source lines with styling included (as ANSI terminal escape sequences), assuming of course, that styling is currently enabled. Of course, in some cases, a user of the Python API might want source code without styling. That's supported too, the new method has an 'unstyled' argument. If this is True then the output is forced to be unstyled. The argument is named 'unstyled' rather than 'styled' because the API call cannot force styling on. If 'set style enabled off' is in effect then making the API call will never return styled source lines. The new API call allows for a range of lines to be requested if desired. As part of this commit I've updated the host_string_to_python_string utility function to take a std::string_view. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
5 daysgdb: return optional from last_symtab_line, and use this moreAndrew Burgess4-20/+23
I noticed that last_symtab_line is defined as returning an int, but if the file associated with the symtab cannot be read then the function returns false! This commit updates last_symtab_line to return std::optional<int> and replaces 'return false' with 'return {}'. I then realised that last_symtab_line isn't actually used very often, but we do use source_cache::get_line_charpos to perform the same job. So I went through all uses of ::get_line_charpos and replaced them with last_symtab_line where appropriate. I think this makes it clearer what we're actually trying to do. There should be no user visible changes after this commit. Approved-By: Tom Tromey <tom@tromey.com>
5 daysgdb/python: new selected_context eventAndrew Burgess8-0/+347
This commit introduces a new Python event, selected_context. This event is attached to the user_selected_context_changed observer, which triggers when the user changes the currently selected inferior, thread, or frame. Adding this event allows a Python extension to update in response to user driven changes without having to poll the state from a before_prompt hook, which is what I currently do to achieve the same results. I did consider splitting the user_selected_context_changed observer into 3 separate Python events, inferior_changed, thread_changed, and frame_changed, but I couldn't see any significant advantage to doing this, so in the end I went with just a single event, and the event object contains the inferior, thread, and frame. Additionally, the user isn't informed about which aspect of the context changed. That is, every event carries the inferior, thread, and frame, so an event triggered when switching frames will looks identical to an event triggered when switching inferiors. If the user wants to know what changed then they will have to track the current state themselves, and then compare the event state to the stored current state. In many cases though I suspect that just being told something changed, and then updating everything will be sufficient, which is why I've not bothered trying to inform the user what changed. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24482 Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
5 daysPowerPC: Fix dmxxshake128pad test case for big-endian targetsAbhay Kandpal1-1/+1
The encoding pattern for dmxxshake128pad in future.d was incorrect for big-endian targets, causing the gas testsuite to fail with a regexp_diff mismatch. The expected byte order did not match the objdump output on big-endian systems. Update the expected encoding to match the correct byte order. gas/ * gas/testsuite/gas/ppc/future.d: Fix Encoding
5 daysAutomatic date update in version.inGDB Administrator1-1/+1
5 daysDon't lose actual error in _bfd_generic_read_minisymbolsAlan Modra4-4/+9
Setting bfd_error_no_symbols in the error return loses the underlying reason why the function failed. Also fix a few places where functions called by _bfd_generic_read_minisymbols didn't set bfd_error on failure. * syms.c (_bfd_generic_read_minisymbols): Don't bfd_set_error here. * aoutx.h (aout_get_external_symbols): Call bfd_set_error on error return. * pdp11.c (aout_get_external_symbols): Likewise. * ecoff.c (_bfd_ecoff_slurp_symbolic_info): Likewise.