Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Building an arc target:
$ configulre --target=arc-elf32 \
--enable-targets=arc-linux-uclibc \
...
On a system with gcc-4.8 (CentOS 7.x), fails with:
--------8<---------
../../gdb/arch/arc.c:117:43: required from here
/usr/include/c++/4.8.2/bits/hashtable_policy.h:195:39: error: no matching
function for call to 'std::pair<const arc_arch_features, const
std::unique_ptr<target_desc, target_desc_deleter> >::pair(const
arc_arch_features&, target_desc*&)'
: _M_v(std::forward<_Args>(__args)...) { }
^
/usr/include/c++/4.8.2/bits/hashtable_policy.h:195:39: note: candidates are:
In file included from /usr/include/c++/4.8.2/utility:70:0,
from /usr/include/c++/4.8.2/tuple:38,
from /usr/include/c++/4.8.2/functional:55,
from ../../gdb/../gdbsupport/ptid.h:35,
from ../../gdb/../gdbsupport/common-defs.h:123,
from ../../gdb/arch/arc.c:19:
/usr/include/c++/4.8.2/bits/stl_pair.h:206:9: note: template<class ...
_Args1, long unsigned int ..._Indexes1, class ... _Args2, long unsigned int
..._Indexes2> std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&,
std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>,
std::_Index_tuple<_Indexes2 ...>)
pair(tuple<_Args1...>&, tuple<_Args2...>&,
^
-------->8---------
The corresponding line in arc.c must use an explicit ctor:
--------8<---------
arc_lookup_target_description (...)
{
/* Add the newly created target description to the repertoire. */
- arc_tdesc_cache.emplace (features, tdesc);
+ arc_tdesc_cache.emplace (features, target_desc_up (tdesc));
return tdesc;
}
-------->8---------
See "PR gcc/96537" for more details.
Last but not least, this problem has originally been investigated
by Tom de Vries for RISCV targets (see 38f8aa06d9).
gdb/ChangeLog:
PR build/27385
* arch/arc.c (arc_lookup_target_description): Use
target_desc_up() ctor explicitly.
|
|
|
|
When stepping over thread-lock related codes (in uClibc), the inferior process
gets stuck and never manages to enter the critical section:
------8<-------
1 size_t fwrite(const void * __restrict ptr, size_t size,
2 size_t nmemb, register FILE * __restrict stream)
3 {
4 size_t retval;
5 __STDIO_AUTO_THREADLOCK_VAR;
6
7 > __STDIO_AUTO_THREADLOCK(stream);
8
9 retval = fwrite_unlocked(ptr, size, nmemb, stream);
10
11 __STDIO_AUTO_THREADUNLOCK(stream);
12
13 return retval;
14 }
------>8-------
Here, we are at line 7. Using the "next" command leads no where.
However, setting a breakpoint on line 9 and issuing "continue" works.
Looking at the assembly instructions reveals that we're dealing with the
critical section entry code [1] that should never be interrupted, in this
case by the debugger's implicit breakpoints:
------8<-------
...
1 add_s r0,r13,0x38
2 mov_s r3,1
3 llock r2,[r0] <-.
4 brne.nt r2,0,14 --. |
5 scond r3,[r0] | |
6 bne -10 --|--'
7 brne_s r2,0,84 <-'
...
------>8-------
Lines 3 until 5 (inclusive) are supposed to be executed atomically.
Therefore, GDB should never (implicitly) insert a breakpoint on lines
4 and 5, else the program will try to acquire the lock again by jumping
back to line 3 and gets stuck in an infinite loop.
The solution is to make GDB aware of these patterns so it inserts
breakpoints after the sequence -- line 6 in this example.
[1]
https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/libc/sysdeps/linux/arc/bits/atomic.h#n46
------8<-------
({ \
__typeof(oldval) prev; \
\
__asm__ __volatile__( \
"1: llock %0, [%1] \n" \
" brne %0, %2, 2f \n" \
" scond %3, [%1] \n" \
" bnz 1b \n" \
"2: \n" \
: "=&r"(prev) \
: "r"(mem), "ir"(oldval), \
"r"(newval) /* can't be "ir". scond can't take limm for "b" */\
: "cc", "memory"); \
\
prev; \
})
------>8-------
"llock" (Load Locked) loads the 32-bit word pointed by the source
operand. If the load is completed without any interruption or
exception, the physical address is remembered, in Lock Physical Address
(LPA), and the Lock Flag (LF) is set to 1. LF is a non-architecturally
visible flag and is cleared whenever an interrupt or exception takes
place. LF is also cleared (atomically) whenever another process writes
to the LPA.
"scond" (Store Conditional) will write to the destination address if
and only if the LF is set to 1. When finished, with or without a write,
it atomically copies the LF value to ZF (Zero Flag).
These two instructions together provide the mechanism for entering a
critical section. The code snippet above comes from uClibc:
-----------------------
v3 (after Tom's remarks[2]):
handle_atomic_sequence()
- no need to initialize the std::vector with "{}"
- fix typo in comments: "conditial" -> "conditional"
- add braces to the body of "if" condition because of the comment line
arc_linux_software_single_step()
- make the performance slightly more efficient by moving a few
variables after the likely "return" point.
v2 (after Simon's remarks[3]):
- handle_atomic_sequence() gets a copy of an instruction instead of
a reference.
- handle_atomic_sequence() asserts if the given instruction is an llock.
[2]
https://sourceware.org/pipermail/gdb-patches/2021-February/175805.html
[3]
https://sourceware.org/pipermail/gdb-patches/2021-January/175487.html
gdb/ChangeLog:
PR tdep/27369
* arc-linux-tdep.c (handle_atomic_sequence): New.
(arc_linux_software_single_step): Call handle_atomic_sequence().
|
|
|
|
|
|
|
|
create_exception_master_breakpoint
The test-case nextoverthrow.exp is failing on targets with unstripped libc.
This is a regression since commit 1940319c0ef "[gdb] Fix internal-error in
process_event_stop_test".
The problem is that this code in create_exception_master_breakpoint:
...
for (objfile *sepdebug = obj->separate_debug_objfile;
sepdebug != nullptr; sepdebug = sepdebug->separate_debug_objfile)
if (create_exception_master_breakpoint_hook (sepdebug))
...
iterates over all the separate debug object files, but fails to handle the
case that obj itself has the debug info we're looking for.
Fix this by using the separate_debug_objfiles () range instead, which does
iterate both over obj and the obj->separate_debug_objfile chain.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-05 Tom de Vries <tdevries@suse.de>
PR breakpoints/27330
* breakpoint.c (create_exception_master_breakpoint): Handle case that
glibc object file has debug info.
|
|
|
|
|
|
It is possible for the tables in the .debug_{rng,loc}lists sections to
not have an array of offsets. In that case, the offset_entry_count
field of the header is 0. The forms DW_FORM_{rng,loc}listx (reference
by index) can't be used with that table. Instead, the
DW_FORM_sec_offset form, which references a {rng,loc}list by direct
offset in the section, must be used. From what I saw, this is what GCC
currently produces.
Add tests for this case. I didn't see any bug related to this, I just
think that it would be nice to have coverage for this. A new
`-with-offset-array` option is added to the `table` procs, used when
generating {rng,loc}lists, to decide whether to generate the offset
array.
gdb/testsuite/ChangeLog:
* lib/dwarf.exp (rnglists): Add -no-offset-array option to
table proc.
* gdb.dwarf2/rnglists-sec-offset.exp: Add test for
.debug_rnglists table without offset array.
* gdb.dwarf2/loclists-sec-offset.exp: Add test for
.debug_loclists table without offset array.
Change-Id: I8e34a7bf68c9682215ffbbf66600da5b7db91ef7
|
|
Add tests for the various issues fixed in the previous patches.
Add a new "loclists" procedure to the DWARF assembler, to allow
generating .debug_loclists sections.
gdb/testsuite/ChangeLog:
PR gdb/26813
* lib/dwarf.exp (_handle_DW_FORM): Handle DW_FORM_loclistx.
(loclists): New proc.
* gdb.dwarf2/loclists-multiple-cus.c: New.
* gdb.dwarf2/loclists-multiple-cus.exp: New.
* gdb.dwarf2/loclists-sec-offset.c: New.
* gdb.dwarf2/loclists-sec-offset.exp: New.
Change-Id: I209bcb2a9482762ae943e518998d1f7761f76928
|
|
The _location proc is used to assemble a location description. It needs
to know some contextual information:
- size of an address
- size of an offset (into another DWARF section)
- DWARF version
It currently get all this directly from global variables holding the
compilation unit information. This is fine because as of now, all
location descriptions are generated in the context of creating a
compilation unit. However, a subsequent patch will generate location
descriptions while generating a .debug_loclists section. _location
should therefore no longer rely on the current compilation unit's
properties.
Change it to accept these values as parameters instead of accessing the
values for the CU.
No functional changes intended.
gdb/testsuite/ChangeLog:
* lib/dwarf.exp (_location): Add parameters.
(_handle_DW_FORM): Adjust.
Change-Id: Ib94981979c83ffbebac838081d645ad71c221637
|
|
Add tests for the various issues fixed in the previous patches.
Add a new "rnglists" procedure to the DWARF assembler, to allow
generating .debug_rnglists sections. A trivial change is required to
support the DWARF 5 CU header layout.
gdb/testsuite/ChangeLog:
PR gdb/26813
* lib/dwarf.exp (_handle_DW_FORM): Handle DW_FORM_rnglistx.
(cu): Generate header for DWARF 5.
(rnglists): New proc.
* gdb.dwarf2/rnglists-multiple-cus.exp: New.
* gdb.dwarf2/rnglists-sec-offset.exp: New.
Change-Id: I5b297e59c370c60cf671dec19796a6c3b9a9f632
|
|
When loading the binary from PR 26813 in GDB, we get:
DW_FORM_rnglistx index pointing outside of .debug_rnglists offset array [in module /home/simark/build/binutils-gdb/gdb/MagicPurse]
... and the symbols fail to load.
In read_rnglist_index and read_loclist_index, we read the header
(documented in sections 7.28 and 7.29 of DWARF 5) of the CU's
contribution to the .debug_rnglists / .debug_loclists sections to
validate that the index we want to read makes sense. However, we always
read the header at the beginning of the section, rather than the header
for the contribution from which we want to read the index.
To illustrate, here's what the binary from PR 26813 contains. There are
two compile units:
0x0000000c: DW_TAG_compile_unit 1
DW_AT_ranges [DW_FORM_rnglistx]: 0x0
DW_AT_rnglists_base [DW_FORM_sec_offset]: 0xC
0x00003ec9: DW_TAG_compile_unit 2
DW_AT_ranges [DW_FORM_rnglistx]: 0xB
DW_AT_rnglists_base [DW_FORM_sec_offset]: 0x85
The layout of the .debug_rnglists is the following:
[0x00, 0x0B]: header for CU 1's contribution
[0x0C, 0x0F]: list of offsets for CU 1 (1 element)
[0x10, 0x78]: range lists data for CU 1
[0x79, 0x84]: header for CU 2's contribution
[0x85, 0xB4]: list of offsets for CU 2 (12 elements)
[0xB5, 0xBD7]: range lists data for CU 2
The DW_AT_rnglists_base attrbute points to the beginning of the list of
offsets for that CU, relative to the start of the .debug_rnglists
section. That's right after the header for that contribution.
When we try to read the DW_AT_ranges attribute for CU 2,
read_rnglist_index reads the header for CU 1 instead of the one for CU
2. Since there's only one element in CU 1's offset list, it believes
(wrongfully) that the index 0xB is out of range.
Fix it by reading the header just before where DW_AT_rnglists_base
points to. With this patch, I am able to load GDB built with clang-11
and -gdwarf-5 in itself, with and without -readnow.
gdb/ChangeLog:
PR gdb/26813
* dwarf2/read.c (read_loclists_rnglists_header): Add
header_offset parameter and use it.
(read_loclist_index): Read header of the current contribution,
not the one at the beginning of the section.
(read_rnglist_index): Likewise.
Change-Id: Ie53ff8251af8c1556f0a83a31aa8572044b79e3d
|
|
read_rnglist_index has a bound check to make sure that we don't go past
the end of the section while reading the offset, but read_loclist_index
doesn't. Add it to read_loclist_index.
gdb/ChangeLog:
* dwarf2/read.c (read_loclist_index): Add bound check for the end
of the offset.
Change-Id: Ic4b55c88860fdc3e007740949c78ec84cdb4da60
|
|
I think this check in read_rnglist_index is wrong:
/* Validate that reading won't go beyond the end of the section. */
if (start_offset + cu->header.offset_size > rnglist_base + section->size)
error (_("Reading DW_FORM_rnglistx index beyond end of"
".debug_rnglists section [in module %s]"),
objfile_name (objfile));
The addition `rnglist_base + section->size` doesn't make sense.
rnglist_base is an offset into `section`, so it doesn't make sense to
add it to `section`'s size. `start_offset` also is an offset into
`section`, so we should just compare it to just `section->size`.
gdb/ChangeLog:
* dwarf2/read.c (read_rnglist_index): Fix bound check.
Change-Id: If0ff7c73f4f80f79aac447518f4e8f131f2db8f2
|
|
Unlike read_rnglists_index, read_loclist_index uses complaints when it
detects an inconsistency (a DW_FORM_loclistx value without a
.debug_loclists section or an offset outside of the section). I really
think they should be errors, since there's no point in continuing if
this situation happens, we will likely segfault or read garbage.
gdb/ChangeLog:
* dwarf2/read.c (read_loclist_index): Change complaints into
errors.
Change-Id: Ic3a1cf6e682d47cb6e739dd76fd7ca5be2637e10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This is the libiberty (mainly for binutils/gdb) counterpart of
https://github.com/alexcrichton/rustc-demangle/pull/23.
Relevant links for the new Rust mangling scheme (aka "v0"):
* Rust RFC: https://github.com/rust-lang/rfcs/pull/2603
* tracking issue: https://github.com/rust-lang/rust/issues/60705
* implementation: https://github.com/rust-lang/rust/pull/57967
This implementation includes full support for UTF-8 identifiers
via punycode, so I've included a testcase for that as well.
libiberty/ChangeLog
2021-01-16 Eduard-Mihai Burtescu <eddyb@lyken.rs>
* rust-demangle.c (struct rust_demangler): Add
skipping_printing and bound_lifetime_depth fields.
(eat): Add (v0-only).
(parse_integer_62): Add (v0-only).
(parse_opt_integer_62): Add (v0-only).
(parse_disambiguator): Add (v0-only).
(struct rust_mangled_ident): Add punycode{,_len} fields.
(parse_ident): Support v0 identifiers.
(print_str): Respect skipping_printing.
(print_uint64): Add (v0-only).
(print_uint64_hex): Add (v0-only).
(print_ident): Respect skipping_printing,
Support v0 identifiers.
(print_lifetime_from_index): Add (v0-only).
(demangle_binder): Add (v0-only).
(demangle_path): Add (v0-only).
(demangle_generic_arg): Add (v0-only).
(demangle_type): Add (v0-only).
(demangle_path_maybe_open_generics): Add (v0-only).
(demangle_dyn_trait): Add (v0-only).
(demangle_const): Add (v0-only).
(demangle_const_uint): Add (v0-only).
(basic_type): Add (v0-only).
(rust_demangle_callback): Support v0 symbols.
* testsuite/rust-demangle-expected: Add v0 testcases.
|
|
|
|
|