]> git.ipfire.org Git - thirdparty/binutils-gdb.git/log
thirdparty/binutils-gdb.git
5 months agolibctf: make ctf_dynamic_type() the inverse of ctf_static_type()
Nick Alcock [Wed, 29 Jan 2025 12:35:47 +0000 (12:35 +0000)] 
libctf: make ctf_dynamic_type() the inverse of ctf_static_type()

They're meant to be inverses, which makes it unfortunate that
they check different bounds.  No visible effect yet, since
ctf_typemax and ctf_stypes currently cover the entire type ID
space, but will have an effect shortly.

5 months agolibctf: drop LCTF_TYPE_ISPARENT/LCTF_TYPE_ISCHILD
Nick Alcock [Wed, 29 Jan 2025 12:30:58 +0000 (12:30 +0000)] 
libctf: drop LCTF_TYPE_ISPARENT/LCTF_TYPE_ISCHILD

Parent/child determination is about to become rather more complex, making a
macro impractical.  Use the ctf_type_isparent/ischild function calls
everywhere and remove the macro.  Make them more const-correct too, to
make them more widely usable.

While we're about it, change several places that hand-implemented
ctf_get_dict() to call it instead, and armour several functions against
the null returns that were always possible in this case (but previously
unprotected-against).

5 months agolibctf: generalize the ref system
Nick Alcock [Mon, 13 Jan 2025 15:04:17 +0000 (15:04 +0000)] 
libctf: generalize the ref system

Despite the removal of the separate movable ref list, the ref system as
a whole is more than complex enough to be worth generalizing now that
we are adding different kinds of ref.

Refs now are lists of uint32_t * which can be updated through the
pointer for all entries in the list and moved to new sites for all
pointers in a given range: they are no longer references to string
offsets in particular and can be references to other uint32_t-sized
things instead (note that ctf_id_t is a typedef to a uint32_t).

ctf-string.c has been adjusted accordingly (the adjustments are tiny,
more or less just turning a bunch of references to atom into
&atom->csa_refs).

5 months agolibctf, string: remove movable refs properly
Nick Alcock [Mon, 13 Jan 2025 14:49:14 +0000 (14:49 +0000)] 
libctf, string: remove movable refs properly

Ever since pending refs were replaced with movable refs, we were failing
to remove movable ref backpointers properly on ctf_remove_ref.  I don't
see how this could cause any problem but a memory leak, but since we
do ultimately write down refs, leaking references to refs is still
risky: best to fix this.

5 months agolibctf, string: delete separate movable ref storage again
Nick Alcock [Mon, 13 Jan 2025 12:04:40 +0000 (12:04 +0000)] 
libctf, string: delete separate movable ref storage again

This was added last year to let us maintain a backpointer to the movable
refs dynhash in movable ref atoms without spending space for the
backpointer on the majority of (non-movable) refs and also without
causing an atom which had some refs movable and some refs not movable to
dereference unallocated storage when freed.

The backpointer's only purpose was to let us locate the
ctf_str_movable_refs dynhash during item freeing, when we had nothing
but a pointer to the atom being freed.  Now we have a proper freeing
arg, we don't need the backpointer at all: we can just pass a pointer to
the dict in to the atoms dynhash as a freeing arg for the atom freeing
functions, and throw the whole backpointer and separate movable ref list
complexity away.

5 months agolibctf, hash: add support for freeing functions taking an arg
Nick Alcock [Mon, 13 Jan 2025 11:34:56 +0000 (11:34 +0000)] 
libctf, hash: add support for freeing functions taking an arg

There are a bunch of places in libctf where the code is complicated
by the fact that freeing a hash key or value requires access to the
dict: more generally, they want an arg pointer to *something*.

But for the sake of being able to use free() as a freeing function,
we can't do this at all times.  We also don't want to bloat up the
hash itself with an arg value unless necessary (in the same way we
already avoid storing the key or value freeing functions unless at
least one of them is specified).

So from the outside this change is simple: add a new
ctf_dynhash_create_arg which takes a new sort of freeing function
which takes an argument.  Internally, we store the arg only when
the key or owner is set, and cast from the one freeing function
to the other iff the arg is non-NULL.  This means it's impossible
to pass a value that may or may not be NULL to the freeing
function, but that's harmless for all current uses, and allows
significant simplifications elsewhere.

5 months agolibctf: move ctf_elf*_to_link_sym to ctf-link.c
Nick Alcock [Mon, 13 Jan 2025 11:31:56 +0000 (11:31 +0000)] 
libctf: move ctf_elf*_to_link_sym to ctf-link.c

Everything in ctf-util.c is in some way associated with data
structures in general in some way, except for the ctf_*_to_link_sym
functions, which are straight translators between the Elf*_Sym
type and the ctf_link_sym_t type used by ctf-link.c.

Move them into ctf-link.c where they belong.

5 months agolibctf: split up ctf-subr.c
Nick Alcock [Mon, 13 Jan 2025 11:29:26 +0000 (11:29 +0000)] 
libctf: split up ctf-subr.c

This file is a bit of a grab-bag of dict-wide API functions like
ctf_set_open_errno or ctf_errwarning_next and portabilty functions and
wrappers like ctf_mmap or ctf_pread.

Split the latter out, and move other dict-wide functions that got
stuck in ctf-util.c (because it was so hard to tell the two files
apart) into ctf-api.c where they belong.

5 months agolibctf: dedup: describe 'citer'
Nick Alcock [Tue, 1 Oct 2024 14:34:12 +0000 (15:34 +0100)] 
libctf: dedup: describe 'citer'

The distinction between the citer and citers variables in
ctf_dedup_rhash_type is somewhat opaque (it's a micro-optimization to avoid
having to allocate entire sets when we know in advance that we'll only have
to store one value).  Add a comment.

libctf/
* ctf-dedup.c (ctf_dedup_rhash_type): Comment on citers variables.

5 months agolibctf: fix obsolete comment
Nick Alcock [Mon, 5 Aug 2024 13:40:05 +0000 (14:40 +0100)] 
libctf: fix obsolete comment

Pending refs haven't been a thing for a while now.

libctf/
* ctf-create.c (ctf_add_member_offset): Fix comment.

5 months agolibctf: a little string sharing test
Nick Alcock [Tue, 16 Jul 2024 12:01:36 +0000 (13:01 +0100)] 
libctf: a little string sharing test

It's actually quite hard to come up with simple tests that do *not* share
all their strings, but with enough ingenuity suitable cycles can be
concocted.

This test verifies that only and precisely those strings that are only used
in one child dict actually end up in its strtab.

ld/
* testsuite/ld-ctf/unshared-strings*: New test.

5 months agolibctf: actually deduplicate the strtab
Nick Alcock [Mon, 15 Jul 2024 22:29:02 +0000 (23:29 +0100)] 
libctf: actually deduplicate the strtab

This commit finally implements strtab deduplication, putting together all
the pieces assembled in the earlier commits.

The magic is entirely localized to ctf_link_write, which preserializes all
the dicts (parent first), and calls ctf_dedup_strings on the parent.

(The error paths get tweaked a bit too.)

Calling ctf_dedup_strings has implications elsewhere: the lifetime rules for
the inputs versus outputs change a bit now that the child output dicts
contain references to the parent dict's atoms table.  We also pre-purge
movable refs from all the deduplicated strings before freeing any of this
because movable refs contain backreferences into the dict they came from,
which means the parent contains references to all the children!  Purging
the refs first makes those references go away so we can free the children
without creating any wild pointers, even temporarily.

There's a new testcase that identifies a regression whereby offset 0 (the
null string) and index 0 (in children now often the parent dict name,
".ctf") got mixed up, leading to anonymous structs and unions getting the
not entirely C-valid name ".ctf" instead.

May other testcases get adjusted to no longer depend on the precise layout
of the strtab.

TODO: add new tests to verify that strings are actually being deduplicated.

libctf/
* ctf-link.c (ctf_link_write): Deduplicate strings.
* ctf-open.c (ctf_dict_close): Free refs, then the link outputs,
        then the out cu_mapping, then the inputs, in that order.
        * ctf-string.c (ctf_str_purge_refs): Not static any more.
* ctf-impl.h: Declare it.

ld/
* testsuite/ld-ctf/conflicting-cycle-2.A-1.d: Don't depend on
        strtab contents.
* testsuite/ld-ctf/conflicting-cycle-2.A-2.d: Likewise.
* testsuite/ld-ctf/conflicting-cycle-2.parent.d: Likewise.
* testsuite/ld-ctf/conflicting-cycle-3.C-1.d: Likewise.
* testsuite/ld-ctf/conflicting-cycle-3.C-2.d: Likewise.
* testsuite/ld-ctf/anonymous-conflicts*: New test.

5 months agolibctf: dedup: add strtab deduplicator
Nick Alcock [Mon, 15 Jul 2024 22:21:20 +0000 (23:21 +0100)] 
libctf: dedup: add strtab deduplicator

This is a pretty simple two-phase process (count duplicates that are
actually going to end up in the strtab and aren't e.g. strings without refs,
strings with external refs etc, and move them into the parent) with one
wrinkle: we sorta-abuse the csa_external_offset field in the deduplicated
child atom (normally used to indicate that this string is located in the ELF
strtab) to indicate that this atom is in the *parent*.  If you think of
"external" as meaning simply "is in some other strtab, we don't care which
one", this still makes enough sense to not need to change the name, I hope.

This is still not called from anywhere, so strings are (still!) not
deduplicated, and none of the dedup machinery added in earlier commits does
anything yet.

libctf/
* ctf-dedup.c (ctf_dedup_emit_struct_members): Note that strtab
dedup happens (well) after struct member emission.
(ctf_dedup_strings): New.
* ctf-impl.h (ctf_dedup_strings): Declare.

5 months agolibctf: do not deduplicate strings in the header
Nick Alcock [Mon, 15 Jul 2024 21:08:10 +0000 (22:08 +0100)] 
libctf: do not deduplicate strings in the header

It is unreasonable to expect users to ctf_import the parent before being
able to understand the header -- doubly so because the only string in the
header which is likely to be deduplicable is the parent name, which is the
same in every child, yet without the parent name being *available* in the
child's strtab you cannot call ctf_parent_name to figure out which parent
to import!

libctf/
* ctf-serialize.c (ctf_preserialize): Prevent deduplication of header string
        fields.
* ctf-open.c (ctf_set_base): Note this.
* ctf-string.c (ctf_str_free_atom): Likewise.

5 months agoinclude, libctf: string lookup and writeout of a parent-shared strtab
Nick Alcock [Mon, 15 Jul 2024 20:56:15 +0000 (21:56 +0100)] 
include, libctf: string lookup and writeout of a parent-shared strtab

The next stage of strtab sharing is actual lookup of strings in such
strtabs, interning of strings in such strtabs and writing out of
such strtabs (but not actually figuring out which strings should
be shared: that's next).

We introduce several new internal ctf_str_* API functions to augment the
existing rather large set: ctf_str_add_copy, which adds a string and always
makes a copy of it (used when deduplicating to stop dedupped strings holding
permanent references on the input dicts), and ctf_str_no_dedup_ref (which
adds a ref to a string while preventing it from ever being deduplicated,
used for header fields like the parent name, which is the same for almost
all child dicts but had still better not be stored in the parent!).

ctf_strraw_explicit, the ultimate underlying "look up a string" function
that backs ctf_strptr et al, gains the ability to automatically find strings
in the parent if the offset is < cth_parent_strlen, and generally make all
offsets parent-relative (so something at offset 1 in the child strlen will
need to be looked up at offset 257 if cth_parent_strlen is 256).  This
suffices to paste together the parent and child from the perspective
of lookup.

We do quite a lot of new checks in here, simply because it's called all over
the place and it's preferable to emit a nice error into the ctf_err_warning
stream if things go wrong.  Among other things this traps cases where you
accidentally added a string to the parent, throwing off all the offsets.
Completely invalid offsets also now add a message to the err_warning
stream.

Insertion of new atoms (the deduplicated entities underlying strings in a
given dict), already a flag-heavy operation, gains more flags, corresponding
to the new ctf_str_add_copy and ctf_str_no_dedup_ref functions: atom
addition also checks the ctf_max_children set by ctf_import and prevents
addition of new atoms to any dicts with ctf_imported children and an
already-serialized strtab.

strtab writeout gains more checks as well: you can't write out a strtab for
a child dict whose parent hasn't been serialized yet (and thus doesn't have
a serialized strtab itself); you can't write it out if the child already
depended on a shared parent strtab and that strtab has changed length.  The
null atom at offset 0 is only written to the parent strtab; and ref updating
changes to look up offsets in the parent's atoms table iff a new
CTF_STR_ATOM_IN_PARENT flag is set on the atom (this will be set by
deduplication to ensure that serializing a dict will update all its refs
properly even though a bunch of them have moved to the parent dict).

None of this actually has any *effect* yet because no string deduplication
is being carried out, and the cth_parent_strlen is still locked at 0.

include/
* ctf-api.h (_CTF_ERRORS) [ECTF_NOTSERIALIZED]: New.
        (ECTF_NERR): Updated.

libctf/
* ctf-impl.h (CTF_STR_ATOM_IN_PARENT): New.
(CTF_STR_ATOM_NO_DEDUP): Likewise.
(ctf_str_add_no_dedup_ref): New.
(ctf_str_add_copy): New.
* ctf-string.c (ctf_strraw_explicit): Look in parents if necessary:
        use parent-relative offsets.
(ctf_strptr_validate): Avoid duplicating errors.
(ctf_str_create_atoms): Update comment.
(CTF_STR_COPY): New.
(CTF_STR_NO_DEDUP): Likewise.
(ctf_str_add_ref_internal): Use them, setting the corresponding
        csa_flags, prohibiting addition to serialized parents, and copying
        strings if so requested.
(ctf_str_add): Turn into a wrapper around...
(ctf_str_add_flagged): ... this new function.  The offset is now
        parent-relative.
(ctf_str_add_ref): Likewise.
(ctf_str_add_movable_ref): Likewise.
(ctf_str_add_copy): New.
(ctf_str_add_no_dedup_ref): New.
(ctf_str_write_strtab): Prohibit writes when the parent has
        changed length or is not serialized.  Only write the null atom
        to parent strtabs.  Chase refs to the parent if necessary.

5 months agolibctf: tear opening and serialization in two
Nick Alcock [Mon, 15 Jul 2024 20:11:40 +0000 (21:11 +0100)] 
libctf: tear opening and serialization in two

The next stage in sharing the strtab involves tearing two core parts
of libctf into two pieces.

Large parts of init_static_types, called at open time, involve traversing
the types table and initializing the hashtabs used by the type name lookup
functions and the enumerator conflicting checks.  If the string table is
partly located in the parent dict, this is obviously not going to work: so
split out that code into a new init_static_types_names function (which
also means moving the wrapper around init_static_types that was used
to simplify the enumerator code into being a wrapper around
init_static_types_names instead) and call that from init_static_types
(for parent dicts, and < v4 dicts), and from ctf_import (for v4 dicts).

At the same time as doing this we arrange to set LCTF_NO_STR (recently
introduced) iff this is a v4 child dict with a nonzero cth_parent_strlen:
this then blocks more or less everything that involves string operations
until a ctf_import has actually imported the strtab it depends on.  (No
string oeprations that actually use this have been introduced yet, but
since no string deduplication is happening yet either this is harmless.)

For v4 dicts, at import time we also validate that the cth_parent_strlen has
the same value as the parent's strlen (zero is also a valid value,
indicating a non-shared strtab, as is commonplace in older dicts, dicts
emitted by the compiler, parent dicts etc).  This makes ctf_import more
complex, so we simplify things again by dropping all the repeated code in
the obscure used-only-by-ctf_link ctf_import_unref and turning both into
wrappers around an internal function.  We prohibit repeated ctf_imports
(except of NULL or the same dict repeatedly), and set up some new fields
which will be used later to prevent people from adding strings to parent
dicts with pre-existing serialized strtabs once they have children imported
into them (which would change their string length and corrupt all those
strtabs).

Serialization also needs to be torn in two.  The problem here is that
currently serialization does too much: it emits everything including the
strtab, does things that depend on the strtab being finalized (notably
variable table sorting), and then writes it out.  Much of this emission
itself involves strtab writes, so the strtab is not actually complete until
halfway through ctf_serialize.  But when deduplicating, we want to use
machinery in ctf-link and ctf-dedup to deduplicate the strtab after it is
complete, and only then write it out.

We could do this via having ctf_serialize call some sort of horrible
callback, but it seems much simpler to just cut ctf_serialize in two,
and introduce a new ctf_preserialize which can optionally be called to do
all this "everything but the strtab" work.  (If it's not called,
ctf_serialize calls it itself.)

This means pulling some internal variables out of ctf_serialize into the
ctf_dict_t, and slightly abusing LCTF_NO_STR to mean (in addition to its
"no, you can't do much between opening a child dict and importing its
parent" semantics), "no, you can't do much between calling ctf_preserialize
and ctf_serialize". The requirements of both are not quite identical -- you
definitely can do things that involve string lookups after ctf_preserialize
-- but it serves to stop callers from accidentally adding more types after
the types table has been written out, and that's good enough.
ctf_preserialize isn't public API anyway.

libctf/
* ctf-impl.h (struct ctf_dict) [ctf_serializing_buf]: New.
        [ctf_serializing_buf_size]: Likewise.
        [ctf_serializing_vars]: Likewise.
        [ctf_serializing_nvars]: Likewise.
        [ctf_max_children]: Likewise.
(LCTF_PRESERIALIZED): New.
(ctf_preserialize): New.
(ctf_depreserialize): New.
* ctf-open.c (init_static_types): Rename to...
(init_static_types_names): ... this, wrapping a different
        function.
        (init_static_types_internal): Rename to...
        (init_static_types): ... this, and set LCTF_NO_STR if neecessary.
        Tear out the name-lookup guts into...
(init_static_types_names_internal): ... this new function. Fix a few
        comment typos.
(ctf_bufopen): Emphasise that you cannot rely on looking up strings
        at any point in ctf_bufopen any more.
(ctf_dict_close): Free ctf_serializing_buf.
(ctf_import): Turn into a wrapper, calling...
(ctf_import_internal): ... this.  Prohibit repeated ctf_imports of
        different parent dicts, or "unimporting" by setting it back to NULL
        again.  Validate the parent we do import using cth_parent_strlen.
        Call init_static_types_names if the strtab is shared with the
        parent.
(ctf_import_unref): Turn into a wrapper.
* ctf-serialize.c (ctf_serialize): Split out everything before
        strtab serialization into...
(ctf_preserialize): ... this new function.
(ctf_depreserialize): New, undo preserialization on error.

5 months agoinclude, libctf: add cth_parent_strlen CTFv4 header field
Nick Alcock [Mon, 15 Jul 2024 20:01:40 +0000 (21:01 +0100)] 
include, libctf: add cth_parent_strlen CTFv4 header field

The first format difference between v3 and v4 is a cth_parent_strlen header
field.  This field (obviously not present in BTF) is populated from the
string table length of the parent at serialization time (protection against
being serialized before the parent is will be added in a later commit in
this series), and will be used at open time to prohibit opening of dicts
with a different strlen (which would corrupt the child's string table
if it was shared with the parent).

For now, just add the field, populate it at serialization time when linking
(when not linking, no deduplication is done and the correct value remains
unchanged), and dump it.

include/
* ctf.h (ctf_header) [cth_parent_strlen]: New.

libctf/
* ctf-dump.c (ctf_dump_header_sizefield): New.
(ctf_dump_header): Use to dump the cth_parent_strlen.
* ctf-open.c (upgrade_header_v2): Populate cth_parent_strlen.
(upgrade_header_v3): Likewise.
(ctf_flip_header): Flip it.
(ctf_bufopen): Drop unnecessary initialization.
* ctf-serialize.c (ctf_serialize): Write it out when linking.

ld/
* testsuite/ld-ctf/data-func-conflicted-vars.d: Skip the nwe dump output.
* testsuite/ld-ctf/data-func-conflicted.d: Likewise.

5 months agolibctf: add mechanism to prohibit most operations without a strtab
Nick Alcock [Mon, 15 Jul 2024 19:43:51 +0000 (20:43 +0100)] 
libctf: add mechanism to prohibit most operations without a strtab

We are about to add machinery that deduplicates a child dict's strtab
against its parent.  Obviously if you open such a dict but do not import its
parent, all strtab lookups must fail: so add an LCTF_NO_STR flag that is set
in that window and make most operations fail if it's not set.  (Two more
that will be set in future commits are serialization and string lookup
itself.)

Notably, not all symbol lookup is impossible in this window: you can still
look up by symbol index, as long as this dict is not using an indexed
strtypetab (which obviously requires string lookups to get the symbol name).

include/
* ctf-api.h (_CTF_ERRORS) [ECTF_HASPARENT]: New.
        [ECTF_WRONGPARENT]: Likewise.
(ECTF_NERR): Update.
        Update comments to note the new limitations on ctf_import et al.

libctf/
* ctf-impl.h (LCTF_NO_STR): New.
* ctf-create.c (ctf_rollback): Error out when LCTF_NO_STR.
(ctf_add_generic): Likewise.
(ctf_add_struct_sized): Likewise.
(ctf_add_union_sized): Likewise.
(ctf_add_enum): Likewise.
(ctf_add_forward): Likewise.
(ctf_add_unknown): Likewise.
(ctf_add_enumerator): Likewise.
(ctf_add_member_offset): Likewise.
(ctf_add_variable): Likewise.
(ctf_add_funcobjt_sym_forced): Likewise.
(ctf_add_type): Likewise (on either dict).
* ctf-dump.c (ctf_dump): Likewise.
* ctf-lookup.c (ctf_lookup_by_name): Likewise.
(ctf_lookup_variable): Likewise. Likewise.
(ctf_lookup_enumerator): Likewise.
(ctf_lookup_enumerator_next): Likewise.
(ctf_symbol_next): Likewise.
(ctf_lookup_by_sym_or_name): Likewise, if doing indexed lookups.
* ctf-types.c (ctf_member_next): Likewise.
(ctf_enum_next): Likewise.
(ctf_type_aname): Likewise.
(ctf_type_name_raw): Likewise.
(ctf_type_compat): Likewise, for either dict.
(ctf_member_info): Likewise.
(ctf_enum_name): Likewise.
(ctf_enum_value): Likewise.
(ctf_type_rvisit): Likewise.
(ctf_variable_next): Note that we don't need to test LCTF_NO_STR.

5 months agolibctf, archive, link: fix parent importing
Nick Alcock [Mon, 15 Jul 2024 19:33:24 +0000 (20:33 +0100)] 
libctf, archive, link: fix parent importing

We are about to move to a regime where there are very few things you can do
with most dicts before you ctf_import them.  So emit a warning if
ctf_archive_next()'s convenience ctf_import of parents fails.  Rip out the
buggy code in ctf_link_deduplicating_open_inputs which opened the parent by
hand (with a hardwired name), and instead rely on ctf_archive_next to do it
for us (which also means we don't end up opening it twice, once in
ctf_archive_next, once in ctf_link_deduplicating_open_inputs).

While we're there, arrange to close the inputs we already opened if opening
of some inputs fails, rather than leaking them.  (There are still some leaks
here, so add a comment to remind us to clean them up later.)

libctf/
* ctf-archive.c (ctf_arc_import_parent): Emit a warning if importing
fails.
* ctf-link.c (ctf_link_deduplicating_open_inputs): Rely on the
        ctf_archive_next to open parent dicts.

5 months agoinclude, libctf: start work on libctf v4
Nick Alcock [Mon, 15 Jul 2024 19:21:36 +0000 (20:21 +0100)] 
include, libctf: start work on libctf v4

This format is a superset of BTF, but for now we just do the minimum to
declare a new file format version, without actually introducing any format
changes.

From now on, we refuse to reserialize CTFv1 dicts: these have a distinct
parent/child boundary which obviously cannot change upon reserialization
(that would change the type IDs): instead, we encoded this by stuffing in
a unique CTF version for such dicts.  We can't do that now we have one
version for all CTFv4 dicts, and testing such old dicts is very hard these
days anyway, and is not automated: so just drop support for writing them out
entirely. (You still *can* write them out, but you have to do a full-blown
ctf_link, which generates an all-new fresh dict and recomputes type IDs as
part of deduplication.)

To prevent this extremely-not-ready format escaping into the wild, add a
new mechanism whereby any format version higher than the new #define
CTF_STABLE_VERSION cannot be serialized unless I_KNOW_LIBCTF_IS_UNSTABLE is
set in the environment.

include/
* ctf-api.h (_CTF_ERRORS) [ECTF_CTFVERS_NO_SERIALIZE]: New.
        [ECTF_UNSTABLE]: New.
         (ECTF_NERR): Update.
* ctf.h: Small comment improvements..
        (ctf_header_v3): New, copy of ctf_header.
(CTF_VERSION_4): New.
(CTF_VERSION): Now CTF_VERSION_4.
(CTF_STABLE_VERSION): Still 4, CTF_VERSION_3.

ld/
* testsuite/ld-ctf/*.d: Update to CTF_VERSION_4.

libctf/
* ctf-impl.h (LCTF_NO_SERIALIZE): New.
* ctf-dump.c (ctf_dump_header): Add CTF_VERSION_4.
* ctf-open.c (ctf_dictops): Likewise.
        (upgrade_header): Rename to...
(upgrade_header_v2): ... this.
(upgrade_header_v3): New.
(upgrade_types): Support upgrading from CTF_VERSION_3.
        Turn on LCTF_NO_SERIALIZE for CTFv1.
(init_static_types_internal): Upgrade all types tables older than
* CTF_VERSION_4.
(ctf_bufopen): Support CTF_VERSION_4: error out if we forget to
update this switch in future.  Add header upgrading from v3 and
below.  Improve comments slightly.
* ctf-serialize.c (ctf_serialize): Block serialization of unstable
file formats, and of file formats for which LCTF_NO_SERIALIZE is
turned on (v1).

5 months ago[gdb/testsuite] Fix gdb.base/nostdlib.exp on aarch64
Tom de Vries [Fri, 28 Feb 2025 13:13:02 +0000 (14:13 +0100)] 
[gdb/testsuite] Fix gdb.base/nostdlib.exp on aarch64

On aarch64-linux, in test-case gdb.base/nostdlib.exp I run into:
...
(gdb) continue^M
Continuing.^M
warning: Temporarily disabling breakpoints for unloaded shared library \
  "/lib/ld-linux-aarch64.so.1"^M
^M
Breakpoint 2, _start () at nostdlib.c:20^M
20      {^M
(gdb) FAIL: $exp: pie=pie: continue to marker
...

This happens as follows:
- the test-case sets a breakpoint on *_start,
- the breakpoint resolves to *_start in the executable,
- the executable is started, and the breakpoint resolves to *_start in the
  dynamic linker,
- execution stops at *_start in the dynamic linker,
- the test-case issues a continue, expecting to continue to the breakpoint on
  marker,
- while continuing, the dynamic linker is reported as unloaded,
- the breakpoint again resolves to *_start in the executable,
- execution stops at *_start in the executable, and
- the test-case concludes that it failed to "continue to marker".

This doesn't happen on x86_64-linux.  There, after the executable is started,
the breakpoint again resolves to *_start in the exec.

This is similar to what happens when printing _start.

On aarch64-linux, we print the _start in the dynamic linker:
...
$ gdb -q -batch outputs/gdb.base/nostdlib/nostdlib-pie \
    -ex "b _start" \
    -ex run \
    -ex "print _start" \
    -ex "info break"
Breakpoint 1 at 0x2bc: file nostdlib.c, line 23.

Breakpoint 1.2, _start () at ../sysdeps/aarch64/dl-start.S:22
22      ENTRY (_start)
$1 = {void (void)} 0xfffff7fd6ac0 <_start>
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>
        breakpoint already hit 1 time
1.1                         y   0x0000aaaaaaaa02bc in _start at nostdlib.c:23
1.2                         y   0x0000fffff7fd6ac0 in _start at dl-start.S:22
...

On x86_64-linux, we print the _start in the exec:
...
Breakpoint 1 at 0x2c5: file nostdlib.c, line 23.

Breakpoint 1.2, 0x00007ffff7fe4f00 in _start () from \
  /lib64/ld-linux-x86-64.so.2
$1 = {void (void)} 0x5555555542c1 <_start>
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>
breakpoint already hit 1 time
1.1                         y   0x00005555555542c5 in _start at nostdlib.c:23
1.2                         y   0x00007ffff7fe4f00 <_start>
...

The difference may be down to the availability of debug info for the _start in
the dynamic linker.

Finally, the described scenario on aarch64-linux is not deterministic.  The
behavior depends on the dynamic linker being reported as unloaded, which has
been classified as a GLIBC bug, so that might get fixed.

Ideally this test-case would stop at both *_start in the executable and the
dynamic linker, but in absense of a way to specify this reliably (see PR32748),
fix this by making this a temporary breakpoint, ensuring that the breakpoint
will only trigger once.

Approved-by: Kevin Buettner <kevinb@redhat.com>
PR testsuite/32743
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32743

5 months agogdb, gdbserver, gdbsupport: fix some namespace comment formatting
Simon Marchi [Fri, 28 Feb 2025 02:29:39 +0000 (21:29 -0500)] 
gdb, gdbserver, gdbsupport: fix some namespace comment formatting

I noticed a

  // namespace selftests

comment, which doesn't follow our comment formatting convention.  I did
a find & replace to fix all the offenders.

Change-Id: Idf8fe9833caf1c3d99e15330db000e4bab4ec66c

5 months agoAutomatic date update in version.in
GDB Administrator [Fri, 28 Feb 2025 00:00:12 +0000 (00:00 +0000)] 
Automatic date update in version.in

5 months agogdb/dwarf: fix failed assertion in dwarf2_find_containing_comp_unit selftest
Simon Marchi [Wed, 26 Feb 2025 16:52:32 +0000 (11:52 -0500)] 
gdb/dwarf: fix failed assertion in dwarf2_find_containing_comp_unit selftest

Commit 2f0521c0d6f6 ("gdb/dwarf: fix signature_type created with nullptr
section") added some asserts in the dwarf2_per_cu_data constructor to
verify that the passed dwarf2_per_bfd and dwarf2_section_info are not
nullptr.  However, the dummy dwarf2_per_cu_data objects created in the
dwarf2_find_containing_comp_unit selftests are passed nullptr for those
parameters.

I prefer to keep the asserts in place, as protection for the non-test
code and as self documentation, so fix this by passing some dummy
pointers in the test.

Change-Id: Ic7cdc1b976f7506041b651222234eefc998e473a
Reviewed-By: Tom de Vries <tdevries@suse.de>
5 months agogdb/dwarf: pass unit length to dwarf2_per_cu_data constructor
Simon Marchi [Wed, 26 Feb 2025 16:52:31 +0000 (11:52 -0500)] 
gdb/dwarf: pass unit length to dwarf2_per_cu_data constructor

Most of the time, the length of a unit is known when constructing a
dwarf2_per_cu_data or signatured_type.  Add a construtor parameter for
it.  In the few cases where it isn't, pass 0, which leaves it unset.

Change-Id: I0c8b9683164d3e3f3823ed995f71689a4d17fd96
Reviewed-By: Tom de Vries <tdevries@suse.de>
5 months agoUpdated translations for bfd and gold
Nick Clifton [Thu, 27 Feb 2025 12:16:26 +0000 (12:16 +0000)] 
Updated translations for bfd and gold

5 months agox86-64: Pass -z separate-code to ld for -z mark-plt tests
H.J. Lu [Thu, 27 Feb 2025 00:19:29 +0000 (08:19 +0800)] 
x86-64: Pass -z separate-code to ld for -z mark-plt tests

Pass -z separate-code to ld for -z mark-plt tests to fix:

FAIL: ld-x86-64/mark-plt-1a
FAIL: ld-x86-64/mark-plt-1b
FAIL: ld-x86-64/mark-plt-1c
FAIL: ld-x86-64/mark-plt-1d
FAIL: ld-x86-64/mark-plt-1a-x32
FAIL: ld-x86-64/mark-plt-1b-x32
FAIL: ld-x86-64/mark-plt-1c-x32
FAIL: ld-x86-64/mark-plt-1d-x32

when binutils is configured with --disable-separate-code.

* ld-x86-64/mark-plt-1a-x32.d: Pass -z separate-code to ld.
* ld-x86-64/mark-plt-1a.d: Likewise.
* ld-x86-64/mark-plt-1b-x32.d: Likewise.
* ld-x86-64/mark-plt-1b.d: Likewise.
* ld-x86-64/mark-plt-1c-x32.d: Likewise.
* ld-x86-64/mark-plt-1c.d: Likewise.
* ld-x86-64/mark-plt-1d-x32.d: Likewise.
* ld-x86-64/mark-plt-1d.d: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
5 months agoAutomatic date update in version.in
GDB Administrator [Thu, 27 Feb 2025 00:00:31 +0000 (00:00 +0000)] 
Automatic date update in version.in

5 months agogas: sframe: partially process DWARF unwind info in CFI_escape
Indu Bhagat [Wed, 26 Feb 2025 21:50:49 +0000 (13:50 -0800)] 
gas: sframe: partially process DWARF unwind info in CFI_escape

CFI_escape is most commonly used to include DWARF expressions in the
unwind information.  One may also use CFI_escape to add OS-specific CFI
opcodes.  Up until now, SFrame generation process would skip generating
SFrame FDE at the mere sight of a CFI_escape opcode.

Fine tune the handling of CFI_escape for SFrame generation by explicitly
checking for few "harmless" (in context of SFrame generation)
CFI_escape DWARF info:
  - DW_CFA_expression affecting registers of no significance to SFrame
    stack trace info
  - DW_CFA_value_offset affecting registers of no significance to SFrame
    stack trace info

Expose the current cfi_escape_data structure in dw2gencfi.c to the
relevant header file to allow SFrame generation APIs to use it too.

Valid unwind info may be split across multiple .cfi_escape directives.
Conversely, it is also allowed to simply put multiple DWARF expressions
and/or operations in a single .cfi_escape directive.  Handling all of
these cases correctly will need parsing/processing that is not deemed
worth the effort in context of SFrame generation; We continue to skip
generating SFrame FDE for these cases and warn the user.

In future, SFrame stack trace format may support non-SP/FP as base
register (albeit in limited form).  Add an explicit check in
sframe_xlate_do_escape_expr (to test against the current CFA register)
to ensure the functionality continues to work.

Use differentiated warning text in sframe_xlate_do_val_offset to avoid
confusion to the user as the same function is used for handling
.cfi_val_offset and .cfi_escape DW_CFA_val_offset,...

Also, add a common test with DWARF reg 12 which is non SP / FP on x86_64
and aarch64 (and s390x too).

gas/
* gas/dw2gencfi.c (struct cfi_escape_data): Move from ...
* gas/dw2gencfi.h (struct cfi_escape_data): ... to.
* gas/gen-sframe.c (sframe_xlate_do_val_offset): Include string
for .cfi_escape conditionally.
(sframe_xlate_do_escape_expr): New definition.
(sframe_xlate_do_escape_val_offset): Likewise.
(sframe_xlate_do_cfi_escape): Likewise.
(sframe_do_cfi_insn): Handle CFI_escape explicitly.

gas/testsuite/
* gas/cfi-sframe/cfi-sframe.exp: Add new tests.
* gas/cfi-sframe/cfi-sframe-common-9.d: New test.
* gas/cfi-sframe/cfi-sframe-common-9.s: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-1.s: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-2.s: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d: New test.
* gas/cfi-sframe/cfi-sframe-x86_64-empty-3.s: New test.

5 months agoRISC-V: Fix abort when displaying data and partial instructions
Charlie Jenkins [Wed, 19 Feb 2025 21:20:18 +0000 (13:20 -0800)] 
RISC-V: Fix abort when displaying data and partial instructions

If data is encountered that is not a power of two, dump all of the data with
a .<N>byte directive.  The current largest support risc-v instruction length
is 22, so the data over 22 bytes will be displayed by,
.insn, 22, ... + .<N-22>byte.

Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
5 months agold/testsuite: add -z separate-code to sframe x86_64 tests
Clément Chigot [Mon, 24 Feb 2025 14:00:24 +0000 (15:00 +0100)] 
ld/testsuite: add -z separate-code to sframe x86_64 tests

Those tests were generated by a linker having "-z separate-code" on by
default. However, being controlled by a configure option, it can be off
by default. Forcing the option as part of the tests ensures clean
results in both cases.

5 months ago[gdb/build] Fix unused var in dwarf2/read.c
Tom de Vries [Wed, 26 Feb 2025 06:46:40 +0000 (07:46 +0100)] 
[gdb/build] Fix unused var in dwarf2/read.c

On x86_64-linux, with gcc 7.5.0 I ran into a build breaker:
...
gdb/dwarf2/read.c: In function ‘void read_comp_units_from_section()’:
gdb/dwarf2/read.c:4297:31: error: unused variable ‘sig_type_it’ \
  [-Werror=unused-variable]
    auto [sig_type_it, inserted] = sig_types.emplace (sig_ptr);
                               ^
...

Fix this by dropping the unused variable.

Tested on x86_64-linux, by completing a build.

5 months agogdb/dwarf: fix signature_type created with nullptr section
Simon Marchi [Tue, 25 Feb 2025 20:54:56 +0000 (15:54 -0500)] 
gdb/dwarf: fix signature_type created with nullptr section

Commit c44ab627b02 ("gdb/dwarf: pass section to dwarf2_per_cu_data
constructor") introduced a regression when using dwp.  It can be
reproduced with:

    $ make check TESTS="gdb.base/ptype-offsets.exp" RUNTESTFLAGS="--target_board=fission-dwp"

Then, to investigate:

    $ ./gdb  -nx -q --data-directory=data-directory testsuite/outputs/gdb.base/ptype-offsets/ptype-offsets -ex 'ptype int'
    Reading symbols from testsuite/outputs/gdb.base/ptype-offsets/ptype-offsets...
    /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:3195:38: runtime error: member call on null pointer of type 'struct dwarf2_section_info'

Commit c44ab627b02 removed the assignment of signatured_type::section
(dwarf2_per_cu_data::section, really) in
fill_in_sig_entry_from_dwo_entry with the justification that the section
was already set when constructing the signatured_type.  Well, that was
true except for one spot in lookup_dwp_signatured_type which passes a
nullptr section to add_type_unit.

Fix that by passing the section to add_type_unit in that one spot.  This
is the same section that would have been set by
fill_in_sig_entry_from_dwo_entry before.

Add some asserts in the dwarf2_per_cu_data constructor to verity that
the passed dwarf2_per_bfd and dwarf2_section_info are non-nullptr.

Change-Id: If27dae6b4727957c96defc058c7e4be31472005b
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32739
Co-Authored-By: Tom de Vries <tdevries@suse.de>
Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb/dwarf: convert dwarf2_per_bfd::signatured_types to a gdb::unordered_set
Simon Marchi [Tue, 25 Feb 2025 20:54:55 +0000 (15:54 -0500)] 
gdb/dwarf: convert dwarf2_per_bfd::signatured_types to a gdb::unordered_set

I'd like to add these asserts in dwarf2_per_cu_data's constructor:

    gdb_assert (per_bfd != nullptr);
    gdb_assert (section != nullptr);

However, these dummy instances of signatured_type, used as hash table
lookup keys, are in the way:

    signatured_type find_sig_entry (nullptr, nullptr, sect_offset {}, sig);

This motivated me to convert the dwarf2_per_bfd::signatured_types hash
table to a gdb::unordered_set.  This allows finding an entry by simply
passing the signature (an integer) and removes the need to create dummy
signatured_type objects.

There is one small unfortunate pessimization:
lookup_dwo_signatured_type, for instance, does a lookup by signature to
find an existing signatured_type.  If not found, it adds a new one by
calling add_type_unit.  The current code passes down the slot where to
put the new element, avoiding an extra hash when inserting the new
signatured_type.  With the new code, I don't see a way to do that.  This
is probably negligible, but it bugs me.  If we used a map of signature
-> signatured_type, I would see a way, but then it would waste space.

I see one change in behavior, that is not really important IMO.  In
read_comp_units_from_section, if duplicate signature type entries are
detected, the code prior to this patch overwrites the existing
signatured_type in the hash table with the new one.  With this patch,
the existing signatured_type is kept: the call to emplace does not
insert the value if an existing equal value exists.

Other than that, no behavior change expected.

Change-Id: I0bef1b49cc63dbdf4e32fa9d4ea37f83025efc3e
Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb/dwarf: change some per-objfile functions to be per-bfd
Simon Marchi [Tue, 25 Feb 2025 21:25:18 +0000 (16:25 -0500)] 
gdb/dwarf: change some per-objfile functions to be per-bfd

I identified the following functions that currently take a
dwarf2_per_objfile, but could take a less specific dwarf2_per_bfd.

 - try_open_dwop_file
 - open_dwo_file
 - open_dwp_file

The uses of the per-objfile object in try_open_dwop_file can be replaced
with equivalent per-bfd ones.

Change-Id: Ia31fa0b988375e86a715ee863d4ec3c572ce89c0
Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb/dwarf: use dwz_file::filename in a few spots
Simon Marchi [Tue, 25 Feb 2025 21:26:07 +0000 (16:26 -0500)] 
gdb/dwarf: use dwz_file::filename in a few spots

I found a few spots where the existing dwz_file::filename method could
be used.

Change-Id: I0522b1e3abbfac2f392f9ec777c37b242ee236d8
Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb: move "gdb:function_view" into quick-symbol.h typedefs
Simon Marchi [Tue, 25 Feb 2025 21:28:38 +0000 (16:28 -0500)] 
gdb: move "gdb:function_view" into quick-symbol.h typedefs

All users of these typedefs use them inside a gdb::function_view.  Move
the gdb::function_view in the typedefs themselves.  This shortens the
types in function signatures and helps with readability, IMO.

Rename them to remove the `_ftype` suffix: this suffix is not as
relevant in C++ as it was in C.  With function_view, the caller can pass
more than just a simple "function".  Anyway, I think it's clearer to
name them after the role the callback has (listener, matcher, etc).

Adjust some related comments.

Change-Id: Iaf9f8ede68b51ea9e4d954792e8eb90def8659a6
Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb/dwarf: initialize tu_stats fields
Simon Marchi [Tue, 25 Feb 2025 21:29:06 +0000 (16:29 -0500)] 
gdb/dwarf: initialize tu_stats fields

Initialize fields of tu_stats to 0, remove the explicit default
initialization of dwarf2_per_bfd::tu_stats.

Change-Id: I98b2d5c4171291a3df2569466559174fb7cf32b6
Approved-By: Tom Tromey <tom@tromey.com>
5 months agoAutomatic date update in version.in
GDB Administrator [Wed, 26 Feb 2025 00:00:12 +0000 (00:00 +0000)] 
Automatic date update in version.in

5 months agoRemove struct print_one_inferior_data
Tom Tromey [Tue, 25 Feb 2025 04:06:27 +0000 (21:06 -0700)] 
Remove struct print_one_inferior_data

struct print_one_inferior_data is not used, so remove it.

5 months agogdb/dwarf: remove unused include in read.c
Simon Marchi [Tue, 25 Feb 2025 20:23:13 +0000 (15:23 -0500)] 
gdb/dwarf: remove unused include in read.c

This include is reported as unused by clangd.

Change-Id: I95b73f85607537551ef54e46551197d1371d621b

5 months agogdb/amd-dbgapi: add displaced stepping support
Simon Marchi [Tue, 14 Jan 2025 19:16:23 +0000 (14:16 -0500)] 
gdb/amd-dbgapi: add displaced stepping support

Implement the target_ops displaced stepping methods to add displaced
stepping support when debugging AMD GPU programs.  The knowledge of how
to prepare and finish displaced steps is provided by the amd-dbgapi
library, so the code here is relatively straightforward.  No need to
parse instructions or handle fixups, that is done by the lib  We just
need to remember, for each thread doing a displaced step, the displaced
stepping id given by the library.

Add a test to exercise the new functionality.  The compiler generates
DWARF that GDB doesn't understand yet [1], so trying to step over a
breakpoint with DWARF present gives:

    (gdb) si
    Unhandled dwarf expression opcode 0xe9

The test purposefully builds the binary without DWARF info to circumvent
this.

[1] https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html

Change-Id: I53f459221a42d4b02a6041eadb8cf554500e2162
Approved-By: Lancelot Six <lancelot.six@amd.com> (amdgpu)
5 months agogdb: add target displaced stepping support
Simon Marchi [Tue, 14 Jan 2025 19:16:22 +0000 (14:16 -0500)] 
gdb: add target displaced stepping support

The amd-dbgapi library, used in the AMD GPU port, has the capability to
prepare and cleanup displaced step operations.  In order to use it, add
the following target_ops methods:

 - supports_displaced_step
 - displaced_step_prepare
 - displaced_step_finish
 - displaced_step_restore_all_in_ptid

Prior to this patch, displaced stepping preparation and cleanup is done
solely by gdbarches.  Update infrun to use these new target methods
instead of gdbarch hooks.  To keep the behavior for other architectures
unchanged, make the default implementations of the new target_ops method
forward to the thread's gdbarch.

displaced_step_restore_all_in_ptid won't be needed for the AMD GPU port,
but was added for completeness.  It would be weird for infrun displaced
stepping code to call target methods except for that one thing where it
calls a gdbarch method.

Since this patch only adds infrastructure, no behavior change is
expected.

Change-Id: I07c68dddb5759a55cd137a711d2679eedc0d9285

5 months agogdb/amd-dbgapi: use gdb::unordered_map
Simon Marchi [Tue, 14 Jan 2025 19:16:21 +0000 (14:16 -0500)] 
gdb/amd-dbgapi: use gdb::unordered_map

Since we have gdb::unordered_map, swap std::unordered_map for that.

Change-Id: If2ef652fe18c1a440a25cff6131d29e37091bdbe
Approved-By: Lancelot Six <lancelot.six@amd.com> (amdgpu)
5 months agoFix mkdir_recursive on windows when CWD is root
Ciaran Woodward [Wed, 12 Feb 2025 17:57:32 +0000 (17:57 +0000)] 
Fix mkdir_recursive on windows when CWD is root

On windows, when creating a directory with an absolute path,
mkdir_recursive would start by trying to make 'C:'.

On windows, this has a special meaning, which is "the current
directory on the C drive". So the first thing it tries to do
is create the current directory.

Most of the time, this fails with EEXIST, so the function
continues as expected. However if the current directory is
C:/, trying to create that causes EPERM, which causes the
function to prematurely terminate.

(The same applies for any drive letter.)

This patch resolves this issue, by skipping the drive letter
so that it is never sent to the mkdir call.

Approved-By: Tom Tromey <tom@tromey.com>
5 months agox86: SFrame FDE for PLT0 does not use repetition block size
Jens Remus [Fri, 21 Feb 2025 10:28:23 +0000 (11:28 +0100)] 
x86: SFrame FDE for PLT0 does not use repetition block size

The SFrame FDE for the PLT0 entry is of type PCINC, which does does not
make use of the type PCMASK repetition block size.  Therefore generate
the FDE with a repetition block size of zero.

bfd/
* elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Use FDE
repetition block size of zero for PLT0.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
5 months agogdb/remote: Set the thread of the remote before sending qRcmd.
Ciaran Woodward [Tue, 19 Jul 2022 15:23:53 +0000 (16:23 +0100)] 
gdb/remote: Set the thread of the remote before sending qRcmd.

GDB allows remotes to implement extension commands which can
be accessed using the 'monitor' command.

This allows remotes to implement functionality which does not
exist in GDB for whatever reason (doesn't make sense, too
specific to one target, etc.)

However, before this change, the remote would not necessarily know
which thread/inferior was currently selected on the GDB client.
This prevents the implementation of any 'monitor' commands which are
specific to a single inferior/thread on the remote.

This is because GDB informs the remote of the current thread
lazily - only when it is relevant to the RSP command next being
sent.

qRcmd is the underlying RSP command used for monitor commands, so
this change ensures that GDB will update the remote with the
'current' thread if it has changed since the remote was last
informed.

Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb/windows: remove disable_breakpoints_in_shlibs call
Andrew Burgess [Mon, 24 Feb 2025 13:51:29 +0000 (13:51 +0000)] 
gdb/windows: remove disable_breakpoints_in_shlibs call

I noticed that the disable_breakpoints_in_shlibs function disables
breakpoints without calling notify_breakpoint_modified.  This commit
is one step towards fixing this issue.

There are currently only two uses of disable_breakpoints_in_shlibs,
one in clear_solib (in solib.c), and the other in
windows_nat_target::do_initial_windows_stuff (in windows-nat.c).

I believe that the call in windows-nat.c can be shown to be redundant,
and therefore can be removed.

windows_nat_target::do_initial_windows_stuff is called from two
places: windows_nat_target::attach and
windows_nat_target::create_inferior, these are the target_ops
functions used to attach to a running process, or for creating a new
process, and are only called from attach_command or run_command_1,
both in infcmd.c.

Both attach_command and run_command_1 call target_pre_inferior before
calling the relevant target_ops function.

In target_pre_inferior, so long as the target doesn't have a global
solist (and windows doesn't), we always call no_shared_libraries (from
solib.c), which calls clear_solib (also in solib.c), which in turn
calls disable_breakpoints_in_shlibs.

My claim then, is that, any time we reach the
disable_breakpoints_in_shlibs call in
windows_nat_target::do_initial_windows_stuff, we will have always have
called disable_breakpoints_in_shlibs already via clear_solib.

I think it should be safe to remove the disable_breakpoints_in_shlibs
call from windows_nat_target::do_initial_windows_stuff.  There should
be no user visible changes.

My ultimate goal, which I'll address in follow on commits, is to
delete disable_breakpoints_in_shlibs completely.  Removing this call
means that we only have one disable_breakpoints_in_shlibs call
remaining in GDB.

Testing for this change has been minimal.  My only Windows build
machine is not great, and I've never managed to get DejaGNU running in
that environment.  This commit builds, and a few basic, manual tests
seem fine, but beyond that, this change is untested.

Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb: don't show incorrect source file in source window
Tom de Vries [Wed, 29 Jan 2025 10:21:02 +0000 (11:21 +0100)] 
gdb: don't show incorrect source file in source window

Consider the test-case sources main.c and foo.c:

  $ cat main.c
  extern int foo (void);

  int
  main (void)
  {
    return foo ();
  }
  $ cat foo.c
  extern int foo (void);

  int
  foo (void)
  {
    return 0;
  }

and main.c compiled with debug info, and foo.c without:

  $ gcc -g main.c -c
  $ gcc foo.c -c
  $ gcc -g main.o foo.o

In TUI mode, if we run to foo:

  $ gdb -q a.out -tui -ex "b foo" -ex run

it gets us "[ No Source Available ]":

  ┌─main.c─────────────────────────────────────────┐
  │                                                │
  │                                                │
  │                                                │
  │            [ No Source Available ]             │
  │                                                │
  │                                                │
  └────────────────────────────────────────────────┘
  (src) In: foo                  L??   PC: 0x400566
  ...
  Breakpoint 1, 0x0000000000400566 in foo ()
  (gdb)

But after resizing (pressing ctrl-<minus> in the gnome-terminal), we
get instead the source for main.c:

  ┌─main.c─────────────────────────────────────────┐
  │        3 int                                   │
  │        4 main (void)                           │
  │        5 {                                     │
  │        6   return foo ();                      │
  │        7 }                                     │
  │                                                │
  │                                                │
  └────────────────────────────────────────────────┘
  (src) In: foo                   L??   PC: 0x400566
  ...
  Breakpoint 1, 0x0000000000400566 in foo ()
  (gdb)

which is inappropriate because we're stopped in function foo, which is
not in main.c.

The problem is that, when the window is resized, GDB ends up calling
tui_source_window_base::rerender.  The rerender function has three
cases, one for when the window already has some source code
content (which is not the case here), a case for when the inferior is
active, and we have a selected frame (which is the case that applies
here), and a final case for when the inferior is not running.

For the case which we end up in, the source code window has no
content, but the inferior is running, so we have a selected frame, GDB
calls the get_current_source_symtab_and_line() function to get the
symtab_and_line for the current location.

The get_current_source_symtab_and_line() will actually return the last
recorded symtab and line location, not the current symtab and line
location.

What this means, is that, if the current location has no debug
information, get_current_source_symtab_and_line() will return any
previously recorded location, or failing that, the default (main)
location.

This behaviour of get_current_source_symtab_and_line() also causes
problems for the 'list' command.  Consider this pure CLI session:

  (gdb) break foo
  Breakpoint 1 at 0x40110a
  (gdb) run
  Starting program: /tmp/a.out

  Breakpoint 1, 0x000000000040110a in foo ()
  (gdb) list
  1 extern int foo (void);
  2
  3 int
  4 main (void)
  5 {
  6   return foo ();
  7 }
  (gdb) list .
  Insufficient debug info for showing source lines at current PC (0x40110a).
  (gdb)

However, if we look at how GDB's TUI updates the source window during
a normal stop, we see that GDB does a better job of displaying the
expected contents.  Going back to our original example, when we start
GDB with:

  $ gdb -q a.out -tui -ex "b foo" -ex run

we do get the "[ No Source Available ]" message as expected.  Why is
that?

The answer is that, in this case GDB uses tui_show_frame_info to
update the source window, tui_show_frame_info is called each time a
prompt is displayed, like this:

  #0  tui_show_frame_info (fi=...) at ../../src/gdb/tui/tui-status.c:269
  #1  0x0000000000f55975 in tui_refresh_frame_and_register_information () at ../../src/gdb/tui/tui-hooks.c:118
  #2  0x0000000000f55ae8 in tui_before_prompt (current_gdb_prompt=0x31ef930 <top_prompt+16> "(gdb) ") at ../../src/gdb/tui/tui-hooks.c:165
  #3  0x000000000090ea45 in std::_Function_handler<void(char const*), void (*)(char const*)>::_M_invoke (__functor=..., __args#0=@0x7ffc955106b0: 0x31ef930 <top_prompt+16> "(gdb) ") at /usr/include/c++/9/bits/std_function.h:300
  #4  0x00000000009020df in std::function<void(char const*)>::operator() (this=0x5281260, __args#0=0x31ef930 <top_prompt+16> "(gdb) ") at /usr/include/c++/9/bits/std_function.h:688
  #5  0x0000000000901c35 in gdb::observers::observable<char const*>::notify (this=0x31dda00 <gdb::observers::before_prompt>, args#0=0x31ef930 <top_prompt+16> "(gdb) ") at ../../src/gdb/../gdbsupport/observable.h:166
  #6  0x00000000008ffed8 in notify_before_prompt (prompt=0x31ef930 <top_prompt+16> "(gdb) ") at ../../src/gdb/event-top.c:518
  #7  0x00000000008fff08 in top_level_prompt () at ../../src/gdb/event-top.c:534
  #8  0x00000000008ffdeb in display_gdb_prompt (new_prompt=0x0) at ../../src/gdb/event-top.c:487

If we look at how tui_show_frame_info figures out what source to
display, it doesn't use get_current_source_symtab_and_line(), instead,
it finds a symtab_and_line directly from a frame_info_pt.  This means
we are not dependent on get_current_source_symtab_and_line() returning
the current location (which it does not).

I propose that we change tui_source_window_base::rerender() so that,
for the case we are discussing here (the inferior has a selected
frame, but the source window has no contents), we move away from using
get_current_source_symtab_and_line(), and instead use find_frame_sal
instead, like tui_show_frame_info does.

This means that we will always use the inferior's current location.

Tested on x86_64-linux.

Reviewed-By: Tom de Vries <tdevries@suse.de>
Reported-By: Andrew Burgess <aburgess@redhat.com>
Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32614

5 months ago[libctf] Fix warning: @xref should not appear on @multitable line
Tom de Vries [Tue, 25 Feb 2025 07:29:19 +0000 (08:29 +0100)] 
[libctf] Fix warning: @xref should not appear on @multitable line

When building gdb, I run into:
...
ctf-spec.texi:809: warning: @xref should not appear on @multitable line
...

The line in question is:
...
@multitable {Kind} {@code{CTF_K_VOLATILE}} {Indicates a type that cannot be represented in CTF, or that} {@xref{Pointers typedefs and cvr-quals}}
...
which defines a prototype row with 4 columns.

However, the table only has 3 colums:
...
@headitem Kind @tab Macro @tab Purpose
...

Fix the warning by removing the item in the prototype row representing a fourth column.

Tested on aarch64-linux.

PR libctf/32044
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32044

5 months agoAutomatic date update in version.in
GDB Administrator [Tue, 25 Feb 2025 00:00:28 +0000 (00:00 +0000)] 
Automatic date update in version.in

5 months ago[gdb/testsuite] Exit left-over gdb in gdb.mi/mi-break.exp
Tom de Vries [Mon, 24 Feb 2025 20:44:15 +0000 (21:44 +0100)] 
[gdb/testsuite] Exit left-over gdb in gdb.mi/mi-break.exp

After test-case gdb.mi/mi-break.exp, a gdb instance is left running.

The test-case starts two instances using mi_clean_restart, one using
separate-mi-tty.

For each instance, gdb_exit is called once, from two different locations:
- mi_clean_restart, and
- gdb_finish.

But this doesn't seem to be effective for the separate-mi-tty case.

Fix this by calling gdb_mi_exit at the end of proc test_break.

Likewise in a few more more test-case.

Tested on x86_64-linux.

Approved-By: Tom Tromey <tom@tromey.com>
PR testsuite/32709
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32709

5 months agoUse ui_out for "info checkpoints"
Kevin Buettner [Mon, 24 Feb 2025 20:04:00 +0000 (13:04 -0700)] 
Use ui_out for "info checkpoints"

In his review of my recent checkpoint work (commit e5501dd4321),
Andrew Burgess suggested that I use GDB's structured table generation
mechanism for the "info checkpoints" command.  This patch does
that.

Andrew also recommended using print_stack_frame() for the "Frame"
column.  I tried this, but ran into some problems, which are described
in a comment in the code.  I got it to mostly work, except for the
case when the current/active fork is running.  Switching context away
from and then back to a running fork doesn't work.  It could, perhaps,
be made to work, but I'm not convinced that the checkpoint facility is
important enough to expend the effort for this case.  So, instead,
I simply adapted the existing checkpoint frame printing code to
use the ui_out machinery instead of gdb_printf.

Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb/styling: only check TERM environment once, during initialisation
Andrew Burgess [Mon, 17 Feb 2025 10:21:12 +0000 (10:21 +0000)] 
gdb/styling: only check TERM environment once, during initialisation

We currently check the TERM environment variable any time we call one
of the ui_file::can_emit_style_escape() functions.  This seems
excessive.

During GDB's startup we also check for the NO_COLOR environment
variable and disable styling if this is set.

I propose that we combine these two checks, and perform them just once
during startup (as the current NO_COLOR check is currently done).  As
with the NO_COLOR check, if the TERM variable is set to "dumb"
indicating that styling is not supported then we should just set
cli_styling to false.

This does mean that the user can then 'set style enabled on', even for
a dumb terminal, which was not possible previously.  Before this
commit the "dumb" terminal check was separate and would prevent
styling even if 'set style enabled on' was in effect.

Of course, trying to turn on styling in a dumb terminal might not give
the results that a user hope for.  And so, I have implemented a check
in `set_style_enabled`, so in a dumb terminal a user will see this:

  (gdb) set style enabled on
  warning: The current terminal doesn't support styling.  Styled output might not appear as expected.

After which GDB will try to emit styling.  We could, potentially,
prevent styling being enabled instead of emitting a warning, but I'm
inclined to let the user turn on styling if they really want to.

Approved-By: Kevin Buettner <kevinb@redhat.com>
Acked-By: Tom Tromey <tom@tromey.com>
5 months agogdb/tui: use correct setting to control asm window styling
Andrew Burgess [Mon, 17 Feb 2025 10:51:30 +0000 (10:51 +0000)] 
gdb/tui: use correct setting to control asm window styling

Currently the TUI's asm window uses `source_styling` to control
styling.  This setting is supposed to be for styling of source files
though, and the asm window displays disassembler output.

We have a different setting for this `disassemble_styling`, which is
controlled with 'set style disassembler enabled on|off'.

Switch to use the correct control variable.

I've written a new test for this, but this required some additions to
the tuiterm library in order to grab character attributes for a screen
region.

Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb/doc: fix help text for 'set style disassembler enabled'
Andrew Burgess [Mon, 17 Feb 2025 10:51:10 +0000 (10:51 +0000)] 
gdb/doc: fix help text for 'set style disassembler enabled'

The help text for 'set/show style disassembler enable' was output of
date.  It talks about GDB requiring the Python Pygments library, but
for many common architectures this is no longer the case, libopcode is
used for styling.

The Python Pygments library is still used as a fallback for those
architectures that libopcode doesn't currently style.

I've updated the help text to try and explain all this.  The manual
was already updated.

Approved-By: Eli Zaretskii <eliz@gnu.org>
5 months ago[gdb/doc] Fix documentation of handle SIGKILL
Tom de Vries [Mon, 24 Feb 2025 15:51:10 +0000 (16:51 +0100)] 
[gdb/doc] Fix documentation of handle SIGKILL

Here ( https://sourceware.org/gdb/current/onlinedocs/gdb.html/Signals.html ) I
read:
...
GDB has the ability to detect any occurrence of a signal in your program.  You
can tell GDB in advance what to do for each kind of signal.
...

However, here ( https://man7.org/linux/man-pages/man2/ptrace.2.html ) I read:
...
While being traced, the tracee will stop each time a signal is
delivered, even if the signal is being ignored.  (An exception is
SIGKILL, which has its usual effect.)
...

So, it seems to be that for SIGKILL we can't tell GDB in advance what to do.

Fix the documentation to reflect this.

Approved-By: Eli Zaretskii <eliz@gnu.org>
PR gdb/32714
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32714

5 months agogdb, testsuite, rust: fix for empty array
Rudnicki, Piotr [Wed, 12 Feb 2025 09:50:37 +0000 (10:50 +0100)] 
gdb, testsuite, rust: fix for empty array

For the Rust language, to avoid segmentation fault in case of an empty
array, do not try to copy any elements, but allocate and return
the empty array immediately.

With the command before the change, gdb crashes with message:

(gdb) set lang rust
(gdb) p [1;0]
Fatal signal: Segmentation fault

After the fix in this commit, gdb shows following message:
(gdb) set lang rust
(gdb) p [1;0]
$1 = []

Update the existing test case gdb.rust/expr.exp to verify the change.

Approved-By: Tom Tromey <tom@tromey.com>
5 months agoobjdump: Inform users if RELR relocs are present in a file when using the -r or ...
Nick Clifton [Mon, 24 Feb 2025 13:44:45 +0000 (13:44 +0000)] 
objdump: Inform users if RELR relocs are present in a file when using the -r or -R options and no regular relocs are present.

PR 32459

5 months agogdb/testsuite/lib/rocm.exp: Fix a typo in a comment
Shahab Vahedi [Mon, 24 Feb 2025 12:54:50 +0000 (13:54 +0100)] 
gdb/testsuite/lib/rocm.exp: Fix a typo in a comment

"Check we have ..." --> "Check if we have ..."

This is for consistency with the previous comment and
the code downstream.

5 months agogdb: handle empty locspec when printing breakpoints
Andrew Burgess [Thu, 5 Dec 2024 17:18:13 +0000 (17:18 +0000)] 
gdb: handle empty locspec when printing breakpoints

For background reading, please see the previous patch, and the patch
before that!

After the last two patches, internal breakpoints can now be marked as
shlib_disabled if the library in which they are placed is unloaded.

The patch before last discusses a situation related to the
gdb.base/nostdlib.exp test, when run on a GNU/Linux glibc based system
where executables are compiled as PIE by default.

In this case it is observed that the dynamic linker will actually
report itself as unloaded (i.e. remove itself from the list of
currently loaded shared libraries).  This behaviour is likely a bug in
the dynamic linker, but this behaviour exists in released versions of
the dynamic linker, so GDB should (if the cost is not too great) be
changed to handle this situation.

This commit handles a problem with the 'maint info breakpoints'
command.

When the dynamic linker is unloaded the 'shlib event' breakpoint is
marked as shlib_disabled (i.e. placed into the pending state).  When
displaying the breakpoint in the 'maint info breakpoints' output, GDB
will try to print the locspec (location_spec *) as a string

Unfortunately, the locspec will be nullptr as the internal breakpoints
are not created via a location_spec, this means that GDB ends up
trying to call location_sepc::to_string() on a nullptr, resulting in
undefined behaviour (and a crash).

For most internal breakpoint types this is not a problem.  If we
consider bp_longjmp_master for example, if the shared library
containing a breakpoint of this type is unloaded then first GDB marks
the breakpoint as shlib_disabled, then after unloading the shared
library breakpoint_re_set is called, which will delete the internal
breakpoint, and then try to re-create it (if needed).  As a result,
the user never gets a change to run 'maint info breakpoints' on a
bp_longjmp_master breakpoint in the shlib_disabled state.

But bp_shlib_event and bp_thread_event breakpoints are not deleted and
recreated like this (see internal_breakpoint::re_set), so it is
possible, in rare cases, that we could end up trying to view one of
these breakpoint in a shlib_disabled state, and it would be nice if
GDB didn't crash as a result.

I've updated the printing code to check for and handle this case, and
I've updated the docs to mention this (rare) case.

For testing, I've extended gdb.base/nostdlib.exp to compile as
pie and nopie, and then run 'maint info breakpoints'.  If we're
running on a buggy glibc then this will trigger the crash.  I don't
know how I can trigger this problem without a buggy glibc as this
would require forcing the dynamic linker to be unloaded.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb: disable internal b/p when a solib is unloaded
Andrew Burgess [Wed, 28 Aug 2024 16:00:37 +0000 (17:00 +0100)] 
gdb: disable internal b/p when a solib is unloaded

Bug PR gdb/32079 highlights an issue where GDB will try to remove a
breakpoint for a shared library that has been unloaded.  This will
trigger an error from GDB like:

  (gdb) next
  61            dlclose (handle[dl]);
  (gdb) next
  warning: error removing breakpoint 0 at 0x7ffff78169b9
  warning: error removing breakpoint 0 at 0x7ffff7730b57
  warning: error removing breakpoint 0 at 0x7ffff7730ad3
  54        for (dl = 0; dl < 4; ++dl)
  (gdb)

What happens is that as the inferior steps over the dlclose() call,
GDB notices that the library has been unloaded and calls
disable_breakpoints_in_unloaded_shlib.  However, this function only
operates on user breakpoints and tracepoints.

In the example above what is happening is that the test loads multiple
copies of libc into different linker namespsaces.  When we 'next' over
the dlclose call one of the copies of libc is unloaded.  As GDB placed
longjmp master breakpoints within the copy of libc that was just
unloaded, the warnings we see are GDB trying (and failing) to remove
these breakpoints.

I think the solution is for disable_breakpoints_in_unloaded_shlib to
handle all breakpoints, even internal ones like the longjmp master
breakpoints.

If we do this then the breakpoint will be marked as shlib_disabled and
also will be marked as not inserted.  Later when we call
breakpoint_re_set() and the longjmp breakpoints are deleted we will no
longer try to remove them.

This solution is inspired by a patch suggested in the bug report:

  https://sourceware.org/bugzilla/show_bug.cgi?id=32079#c3

There are some differences with my approach compared to the patch
suggested in the bug.  First I have no need to delete the breakpoint
inside disable_breakpoints_in_unloaded_shlib as an earlier patch in
this series arranged for breakpoint_re_set to be called when shared
libraries are removed.  Calling breakpoint_re_set will take care of
deleting the breakpoint for us.  For details see the earlier commit
titled:

  gdb: fixes for code_breakpoint::disabled_by_cond logic

Next, rather than only handling bp_longjmp and bp_longjmp_master, I
allow all breakpoints to be handled.  I also only give the warning
about disabling breakpoints for user breakpoints, I don't see the
point of warning the user about internal b/p changes.

With this done the issues in PR gdb/32079 are resolved.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32079

Tested-By: Hannes Domani <ssbssa@yahoo.de>
Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb: don't clear inserted flag in disable_breakpoints_in_unloaded_shlib
Andrew Burgess [Thu, 5 Dec 2024 17:17:38 +0000 (17:17 +0000)] 
gdb: don't clear inserted flag in disable_breakpoints_in_unloaded_shlib

This commit removes the clearing of bp_location::inserted from
disable_breakpoints_in_unloaded_shlib, my claim is that this call is
not needed (any more), and with the next commit, this line actually
causes some problems.

The disable_breakpoints_in_unloaded_shlib function was added back in
2004 with commit 84acb35a5a97c, and from this first version the
function cleared the bp_location::inserted flag.  The motivation for
this is that the shared library might have already been unmapped, in
which case, a later attempt to remove the location could fail.

In 2013 a similar function disable_breakpoints_in_freed_objfile was
added.  This function also cleared bp_location::inserted for similar
reasons.  This code was added in commit:

  commit 63644780babdca3f40e1978a236b6cd78473c91b
  Date:   Tue Mar 12 11:10:18 2013 +0100

      New remove-symbol-file command.

Then in 2014 the clearing of bp_location::inserted was removed from
disable_breakpoints_in_freed_objfile in the commit:

  commit 08351840eabb44799e3d01026610420758f4fa40
  Date:   Tue Apr 22 23:19:19 2014 +0100

      Stale breakpoint instructions, spurious SIGTRAPS.

The reason that clearing the ::inserted flag was removed in this
commit is that if the disable_breakpoints_in_freed_objfile function
was called when the b/p were actually inserted, and the memory for the
associated objfile wasn't actually unmapped, then we could end up
leaving breakpoints inserted into the inferior, which leads to
spurious SIGTRAPs.

In the next commit I'll change disable_breakpoints_in_unloaded_shlib
so that all breakpoints, not just user breakpoints, will be
disabled (via shlib_disabled) when a shared library is unloaded.  This
addresses PR gdb/32079, see the next commit for a fuller justification
for this change.

The problem is that when I tested the next commit I ran into some
regressions from the gdb.base/nostdlib.exp test when run on an AArch64
GNU/Linux system where executables are compiled as PIE by default.
This test compiles a simple binary with the -nostdlib flag.

What happens is this:

  - The executable is compiled as PIE, this means that we get a
    dynamically linked executable, the dynamic linker is used to
    perform the PIE relocation, but the executable uses no other
    shared libraries.

  - When GDB starts the inferior, initially the dynamic linker is
    discovered as a shared library being used by the application, GDB
    loads in the library and its debug symbols, placing the internal
    "shlib event" breakpoints so that future shared library events can
    be tracked.

  - For the target I tested on systemtap probes were not used, instead
    GDB fell back to the old style even breakpoint.

  - As the inferior progresses, after the PIE relocation has been
    performed, the dynamic linker performs some house keeping on the
    list of shared libraries being used by the application.  During
    this process the dynamic linker is removed from the list of shared
    libraries being used by the inferior, this causes GDB see a shared
    library event, which GDB understands to mean that it should unload
    the dynamic linker from the inferior.

    I spoke with the glibc engineers at RH, and the feeling is that
    this is likely a bug (it's still being investigated).  But I don't
    think it really matters if this is a bug or not.  There are
    versions of glibc in the wild that have this behaviour, so GDB
    should (if the cost is not too great) be updated to handle this.

    Obviously after removing the dynamic linker from the list of
    shared libraries, the dynamic linker is not actually unmapped,
    that would not be possible, it's the dynamic linker that does the
    unmapping, so the dynamic linker is left mapped into the
    inferior's address space.

  - With the next patch in place all breakpoints (user and internal)
    within the dynamic linker are disabled (shlib_disabled) and
    currently marked as not inserted (bp_location::inserted flag is
    cleared).

  - Having processed the shared library event GDB then resumes the
    inferior.  As the shared library event is not a full stop of the
    inferior (i.e. we don't remove all breakpoints before handling the
    event), all of the breakpoints in the dynamic linker are still
    inserted, but are now marked as not-inserted.

  - GDB then resumes the inferior and immediately hits the breakpoint
    that is still inserted.  As GDB thinks this breakpoint is not
    inserted, this is reported to the user as a SIGTRAP.

The fix I think is just to not clear the bp_location::inserted flag in
disable_breakpoints_in_unloaded_shlib.  This will leave the breakpoint
as inserted in the case above.  GDB will now be able to successfully
resume the inferior after the shared library event (knowing there is a
breakpoint inserted GDB will step over it and continue as expected).
The next time the inferior performs a full stop the now shlib_disabled
breakpoint will be removed from the inferior we would want.

For the usual case, where a shared library is being unloaded due to
say a dlclose, the breakpoints in the library will be marked as
disabled, but will be left inserted.  The next time remove_breakpoints
is called GDB will try to remove those breakpoint locations.  If the
removal fails, as the breakpoint is marked shlib_disabled, GDB will
hide the error message from the user and just assume that the shared
library has been unmapped.  This functionality was first added in 2008
in commit 879d1e6b4674bc8.

There are two aspects to testing this change.  First whether no
clearing the ::inserted flag causes general problems.  That is tested
by running the full testsuite (I see no regressions).

Then there is the specific problem that caused me to make this
change.  That issue only occurs on AArch64, with GNU/Linux using
glibc, when the executable is compiled as PIE, and doesn't use any
shared libraries other than the dynamic linker (which can be the
gdb.base/nostdlib.exp test if run on the right system).  What I don't
know is how to recreate this setup in a more general form.

We can't use add-symbol-file/remove-symbol-file as that passes through
disable_breakpoints_in_freed_objfile instead, which the ::installed
flag is already not adjusted.

Also the bug doesn't trigger on x86 targets due to code in
handle_signal_stop which sees the inserted breakpoint, and decides
this must be a breakpoint that actually exists in the program, and
then because gdbarch_decr_pc_after_break returns non-zero for x86, GDB
steps the inferior past the breakpoint.  This is the big difference
from AArch64 where gdbarch_decr_pc_after_break returns zero, and so
the inferior gets stuck hitting the unexpectedly inserted breakpoint.

Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb: handle dprintf breakpoints when unloading a shared library
Andrew Burgess [Thu, 29 Aug 2024 11:34:15 +0000 (12:34 +0100)] 
gdb: handle dprintf breakpoints when unloading a shared library

While working on the previous commit I realised that GDB would not
handle dprintf breakpoints correctly when a shared library was
unloaded.

Consider this example using the test binary from shlib-unload.exp.  In
the function 'foo' we create a dprintf is in a shared library:

  (gdb) b 59
  Breakpoint 1 at 0x401215: file /tmp/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/shlib-unload.c, line 59.
  (gdb) r
  Starting program: /tmp/projects/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/shlib-unload/shlib-unload

  Breakpoint 1, main () at /tmp/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/shlib-unload.c:59
  59   res = dlclose (handle); /* Break here.  */
  (gdb) dprintf foo,"In foo"
  Dprintf 2 at 0x7ffff7fc50fd: file /tmp/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/shlib-unload-lib.c, line 23.
  (gdb) n
  Error in re-setting breakpoint 2: Function "foo" not defined.
  warning: error removing breakpoint 2 at 0x7ffff7fc50fd
  warning: error removing breakpoint 2 at 0x7ffff7fc50fd
  warning: error removing breakpoint 2 at 0x7ffff7fc50fd
  warning: error removing breakpoint 2 at 0x7ffff7fc50fd
  warning: error removing breakpoint 2 at 0x7ffff7fc50fd
  warning: error removing breakpoint 2 at 0x7ffff7fc50fd
  warning: error removing breakpoint 2 at 0x7ffff7fc50fd
  warning: error removing breakpoint 2 at 0x7ffff7fc50fd
  Cannot remove breakpoints because program is no longer writable.
  Further execution is probably impossible.
  60   assert (res == 0);
  (gdb)

What happens here is that as the inferior steps over the dlclose call
the shared library containing 'foo' is unloaded and
disable_breakpoints_in_unloaded_shlib is called.  However in
disable_breakpoints_in_unloaded_shlib we have this check:

  if (b.type != bp_breakpoint
     && b.type != bp_jit_event
     && b.type != bp_hardware_breakpoint
     && !is_tracepoint (&b))
   continue;

As the dprintf has type bp_dprintf then this check triggers and we
ignore the dprintf, meaning the dprintf is not disabled.  When the
inferior stops after the 'next' GDB tries to remove all breakpoints
but the dprintf can no longer be removed, the memory in which it was
placed has been unmapped from the inferior.

The fix is to start using is_breakpoint() in
disable_breakpoints_in_unloaded_shlib instead of the bp_breakpoint and
bp_hardware_breakpoint checks.  The is_breakpoint() function also
checks for bp_dprintf.

With this fix in place GDB now correctly disables the breakpoint and
we no longer see the warning about removing the breakpoint.

During review it was pointed out that PR gdb/23149 and PR gdb/20208
both describe something similar, though for these bugs, the inferior
is restarted (which unloads all currently loaded shlib) rather than
passing over the dlclose.  But the consequences are pretty similar.
I've included a test which covers this case.

One additional thing that these two bugs did show though is that
disable_breakpoints_in_shlibs also needs to start using is_breakpoint
for the same reason.  Without this change, when an inferior is
restarted we get a warning like this for dprintf breakpoints:

  warning: Temporarily disabling breakpoints for unloaded shared library "..."

but we don't get a similar warning for "normal" breakpoints.  This is
because disable_breakpoints_in_shlibs is called from clear_solib,
which is called when an inferior is restarted.

It is best not to think too hard about disable_breakpoints_in_shlibs,
as this function is pretty broken, e.g. it doesn't call
notify_breakpoint_modified, despite modifying the breakpoints.  But
for now I'm ignoring that, but fixing this is definitely on my list
for my next set of breakpoint related fixes, it's just that a lot of
these breakpoint fixes end up being depending on one another, but I
want to avoid making this series too long.  So for now, I'm ignoring
the existing bug (missing breakpoint modified events), and fixing
disable_breakpoints_in_shlibs to cover dprintf.

With these fixes in place, the two bugs mentioned above should be
fixed.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23149
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20208

Tested-By: Hannes Domani <ssbssa@yahoo.de>
Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb: restructure disable_breakpoints_in_unloaded_shlib
Andrew Burgess [Wed, 28 Aug 2024 16:21:53 +0000 (17:21 +0100)] 
gdb: restructure disable_breakpoints_in_unloaded_shlib

This commit rewrites disable_breakpoints_in_unloaded_shlib to be more
like disable_breakpoints_in_freed_objfile.  Instead of looping over
all b/p locations, we instead loop over all b/p and then over all
locations for each b/p.

The advantage of doing this is that we can fix the small bug that was
documented in a comment in the code:

  /* This may cause duplicate notifications for the same breakpoint.  */
  notify_breakpoint_modified (b);

By calling notify_breakpoint_modified() as we modify each location we
can potentially send multiple notifications for a single b/p.

Is this a bug?  Maybe not.  After all, at each notification one of the
locations will have changed, so its probably fine.  But it's not
ideal, and we can easily do better, so lets do that.

There's a new test which checks that we only get a single notification
when the shared library is unloaded.  Note that the test is written as
if there are multiple related but different tests within the same test
file ... but there aren't currently!  The next commit will add another
test proc to this test script at which point the comments will make
sense.  I've done this to avoid unnecessary churn in the next commit.

Tested-By: Hannes Domani <ssbssa@yahoo.de>
Approved-By: Tom Tromey <tom@tromey.com>
5 months agogdb: fixes for code_breakpoint::disabled_by_cond logic
Andrew Burgess [Thu, 15 Aug 2024 16:43:18 +0000 (17:43 +0100)] 
gdb: fixes for code_breakpoint::disabled_by_cond logic

I spotted that the code_breakpoint::disabled_by_cond flag doesn't work
how I'd expect it too.  The flag appears to be "sticky" in some
situations; once a code_breakpoint::disabled_by_cond flag is marked
true, then, in some cases the flag wont automatically become false
again, even when you'd think it should.

The problem is in update_breakpoint_locations.  In this function,
which is called as a worker of code_breakpoint::re_set, GDB computes a
new set of locations for a breakpoint, the new locations are then
installed into the breakpoint.

However, before installing the new locations GDB attempts to copy the
bp_location::enabled and bp_location::disabled_by_cond flag from the
old locations into the new locations.

The reason for copying the ::enabled flag makes sense.  This flag is
controlled by the user.  When we create the new locations if GDB can
see that a new location is equivalent to one of the old locations, and
if the old location was disabled by the user, then the new location
should also be disabled.

However, I think the logic behind copying the ::disabled_by_cond flag
is wrong.  The disabled_by_cond flag is controlled by GDB and should
toggle automatically.  If the condition string can be parsed then the
flag should be false (b/p enabled), if the condition string can't be
parsed then the flag should be true (b/p disabled).

As we always parse the condition string in update_breakpoint_locations
before we try to copy the ::enabled flag value then the
::disabled_by_cond flag should already be correct, there's no need to
copy over the ::disabled_by_cond value from the old location.

As a concrete example, consider a b/p placed within the main
executable, but with a condition that depends on a variable within a
shared library.

When the b/p is initially created the b/p will be disabled as the
condition string will be invalid (the shared library variable isn't
available yet).

When the inferior starts the shared library is loaded and the
condition variable becomes available to GDB.  When the shared library
is loaded breakpoint_re_set is called which (eventually) calls
update_breakpoint_locations.

A new location is computed for the breakpoint and the condition string
is parsed.  As the shared library variable is now know the expression
parses correctly and ::disabled_by_cond is left false for the new
location.

But currently GDB spots that the new location is at the same address
as the old location and copies disabled_by_cond over from the old
location, which marks the b/p location as disabled.  This is not what
I would expect.

The solution is simple, don't copy over disabled_by_cond.

While writing a test I found another problem though.  The
disabled_by_cond flag doesn't get set true when it should!  This is
the exact opposite of the above.

The problem here is in solib_add which is (despite the name) called
whenever the shared library set changes, including when a shared
library is unloaded.

Imagine an executable that uses dlopen/dlclose to load a shared
library.  Given an example of a b/p in the main executable that has a
condition that uses a variable from our shared library, a library
which might be unloaded with dlclose.

My expectation is that, when the library is unloaded, GDB will
automatically mark the breakpoint as disabled_by_cond, however, this
was not happening.

The problem is that in solib_add we only call breakpoint_re_set when
shared libraries are added, not when shared libraries are removed.

The solution I think is to just call breakpoint_re_set in both cases,
now the disabled_by_cond flag is updated as I'd expect.

Unfortunately, making this change causes a regression when running:

  make check-gdb \
     TESTS="gdb.trace/change-loc.exp" \
     RUNTESTFLAGS="--target_board=native-gdbserver"

This test unloads a shared library and expects breakpoints within the
shared library to enter the PENDING state (because the bp_location's
shlib_disabled flag will be set).  However, the new call to
breakpoint_re_set means that this is no longer the case.

The breakpoint_re_set call means that update_breakpoint_locations is
called, which then checks if all locations for a breakpoint are
pending or not.  In this test not all locations are pending, and so
GDB recalculates the locations of each breakpoint, this means that
pending locations are discarded.

There is a but report PR gdb/32404 which mentions the problems with
shlib_disabled pending breakpoints, and how they are prone to being
randomly deleted if the user can cause GDB to trigger a call to
breakpoint_re_set.  This patch just adds another call to
breakpoint_re_set, which triggers this bug in this one test case.

For now I have marked this test as KFAIL.  I do plan to try and
address the pending (shlib_disabled) breakpoint problem in the future,
but I'm not sure when that will be right now.

There are, of course, tests to cover all these cases.

During review I was pointed at bug PR gdb/32079 as something that this
commit might fix, or help in fixing.

And this commit is part of the fix for that bug, but is not the
complete solution.  However, the remaining parts of the fix for that
bug are not really related to the content of this commit.

The problem in PR gdb/32079 is that the inferior maps multiple copies
of libc in different linker namespaces using dlmopen (actually libc is
loaded as a consequence of loading some other library into a different
namespace, but that's just a detail).  The user then uses a 'next'
command to move the inferior forward.

GDB sets up internal breakpoints on the longjmp symbols, of which
there are multiple copies (there is a copy in every loaded libc).

However, the 'next' command is, in the problem case, stepping over a
dlclose call which unloads one of the loaded libc libraries.

In current HEAD GDB in solib_add we fail to call breakpoint_re_set()
when the library is unloaded; breakpoint_re_set() would delete and
then recreate the longjmp breakpoints.  As breakpoint_re_set() is not
called GDB thinks that the the longjmp breakpoint in the now unloaded
libc still exists, and is still inserted.

When the inferior stops after the 'next' GDB tries to delete and
remove the longjmp breakpoint which fails as the libc in which the
breakpoint was inserted is no longer mapped in.

When the user tries to 'next' again GDB tries to re-insert the still
existing longjmp breakpoint which again fails as the memory in which
the b/p should be inserted is no longer part of the inferior memory
space.

This commit helps a little.  Now when the libc library is unmapped GDB
does call breakpoint_re_set().  This deletes the longjmp breakpoints
including the one in the unmapped library, then, when we try to
recreate the longjmp breakpoints (at the end of breakpoint_re_set) we
don't create a b/p in the now unmapped copy of libc.

However GDB does still think that the deleted breakpoint is inserted.
The breakpoint location remains in GDB's data structures until the
next time the inferior stops, at which point GDB tries to remove the
breakpoint .... and fails.

However, as the b/p is now deleted, when the user tries to 'next' GDB
no longer tries to re-insert the b/p, and so one of the problems
reported in PR gdb/32079 is resolved.

I'll fix the remaining issues from PR gdb/32079 in a later commit in
this series.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32079

Tested-By: Hannes Domani <ssbssa@yahoo.de>
Approved-By: Tom Tromey <tom@tromey.com>
5 months agoAutomatic date update in version.in
GDB Administrator [Mon, 24 Feb 2025 00:00:09 +0000 (00:00 +0000)] 
Automatic date update in version.in

5 months agoFix formatting in dwarf2/index-write.c
Tom Tromey [Sun, 23 Feb 2025 16:05:51 +0000 (09:05 -0700)] 
Fix formatting in dwarf2/index-write.c

I noticed a spot in dwarf2/index-write.c that was mis-formatted.  This
fixes it.

5 months agoMIPS: Apply coding guidelines: indentation
Milica Matic [Sun, 23 Feb 2025 16:06:04 +0000 (16:06 +0000)] 
MIPS: Apply coding guidelines: indentation

Format mips-tdep.c code as described on links:

https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards
https://www.gnu.org/prep/standards/standards.html#Comments

correcting indentation as required.

Approved-by: Kevin Buettner <kevinb@redhat.com>
Approved-by: Maciej W. Rozycki <macro@orcam.me.uk>
5 months agoMIPS: Apply coding guidelines: tabs
Milica Matic [Sun, 23 Feb 2025 16:06:04 +0000 (16:06 +0000)] 
MIPS: Apply coding guidelines: tabs

Format mips-tdep.c code as described on links:

https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards
https://www.gnu.org/prep/standards/standards.html#Comments

converting spaces to tabs and fixing alignment as appropriate.

Approved-by: Kevin Buettner <kevinb@redhat.com>
Approved-by: Maciej W. Rozycki <macro@orcam.me.uk>
5 months agoMIPS: Apply coding guidelines: sentences
Milica Matic [Sun, 23 Feb 2025 16:06:04 +0000 (16:06 +0000)] 
MIPS: Apply coding guidelines: sentences

Format mips-tdep.c code as described on links:

https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards
https://www.gnu.org/prep/standards/standards.html#Comments

capitalizing sentences and adding full stops and spaces after them.

Approved-by: Kevin Buettner <kevinb@redhat.com>
Approved-by: Maciej W. Rozycki <macro@orcam.me.uk>
5 months agoMIPS: Apply coding guidelines: new lines
Milica Matic [Sun, 23 Feb 2025 16:06:04 +0000 (16:06 +0000)] 
MIPS: Apply coding guidelines: new lines

Format mips-tdep.c code as described on links:

https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards
https://www.gnu.org/prep/standards/standards.html#Comments

removing and adding new lines as appropriate.

Approved-by: Kevin Buettner <kevinb@redhat.com>
Approved-by: Maciej W. Rozycki <macro@orcam.me.uk>
5 months agoMIPS: Apply coding guidelines: trailing space
Milica Matic [Sun, 23 Feb 2025 16:06:04 +0000 (16:06 +0000)] 
MIPS: Apply coding guidelines: trailing space

Format mips-tdep.c code as described on links:

https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards
https://www.gnu.org/prep/standards/standards.html#Comments

removing trailing space.

Approved-by: Kevin Buettner <kevinb@redhat.com>
Approved-by: Maciej W. Rozycki <macro@orcam.me.uk>
5 months agogas: avoid dangling pointers into freed memory
Alan Modra [Sun, 23 Feb 2025 10:35:00 +0000 (21:05 +1030)] 
gas: avoid dangling pointers into freed memory

The oss-fuzz gas fuzzer is quite broken in that it doesn't
reinitialise all gas and bfd static variables between runs.  Since gas
naughtily modifies bfd_und_section and bfd_abs_section those bfd
statics can hold pointers into freed memory between runs.
This patch fixes oss-fuzz issue 398060144.

5 months agoPR 32731 ub sanitizer accessing filenames_reversed
Alan Modra [Sun, 23 Feb 2025 10:34:29 +0000 (21:04 +1030)] 
PR 32731 ub sanitizer accessing filenames_reversed

tic4x-coff and mcore-pe tickle this bug by a peculiarity of their
default ld scripts.

PR 32731
* ldlang.c (lang_add_wild): Init filenames_reversed when no
filespec.

5 months agoAutomatic date update in version.in
GDB Administrator [Sun, 23 Feb 2025 00:00:21 +0000 (00:00 +0000)] 
Automatic date update in version.in

5 months agoMIPS objdump: Recognize o64 ABI names
Maximilian Ciric [Sat, 22 Feb 2025 20:57:15 +0000 (20:57 +0000)] 
MIPS objdump: Recognize o64 ABI names

Add gpr and fpr names for the o64 ABI to objdump.

With the recent addition of both EABIs, this completes support for the
standard ABI options (ABI-breaking options such as -modd-spreg or
-mabi=32 -mfp64 notwithstanding). The names have been verified against
GCC's usage of the registers. Notably, the only(?) documentation that
defines the o64 ABI at

https://gcc.gnu.org/projects/mipso64-abi.html

appears to contain a mistake w.r.t. floating-point arguments. In
particular:

> If the first and second arguments floating-point arguments to a
> function are 32-bit values, they are passed in $f12 and $f14.

As from 4.0.0 this does not happen in GCC's implementation of the ABI;
a pair of single-float arguments are still passed in $f12 and $f13, the
same as when one or both of the arguments are double-precision floats.
The registers $f12, $f13 and $f14 have been named $fa0, $fa1 and $ft10
to match the implementation.

Signed-off-by: Maximilian Ciric <max.ciric@gmail.com>
5 months agoAutomatic date update in version.in
GDB Administrator [Sat, 22 Feb 2025 00:00:08 +0000 (00:00 +0000)] 
Automatic date update in version.in

5 months agogdb/testsuite/rocm.exp: Use system GPU(s) to detect features
Shahab Vahedi [Wed, 12 Feb 2025 14:58:15 +0000 (15:58 +0100)] 
gdb/testsuite/rocm.exp: Use system GPU(s) to detect features

gdb/testsuite/rocm.exp: Use system GPU(s) to detect features

Background
----------
This patch revisits the purpose of hcc_amdgpu_targets{} in
order to address the separation of concerns between:

- GPU targets passed to the compiler.  This kind of target
  is passed as an argument to flags like "--offload-arch=...",
  "--targets=...", etc.

- GPU targets as in available GPU devices on the system.  This
  is crucial for finding which capabilities are available,
  and therefore which tests should be executed or skipped.

Code change
-----------
- A new "find_amdgpu_devices{}" procedure is added.  It is
  responsible for listing the GPU devices that are available
  on the system.

- "hcc_amdgpu_targets{}" is rewritten to use the newly added
  "find_amdgpu_devices{}" when there's no environment variable
  (HCC_AMDGPU_TARGET) set.

- The output of "hcc_amdgpu_targets{}" is now only used in
  places that set the target for the building toolchains.

- The output of "find_amdgpu_devices{}" is used anywhere that
  needs to evaluate the GPU features.

Approved-By: Lancelot Six <lancelot.six@amd.com> (amdgpu)
Change-Id: Ib11021dbe674aa40192737ede78284a1bc531513

5 months agoIQ2000: drop maintainer
Jan Beulich [Fri, 21 Feb 2025 09:28:46 +0000 (10:28 +0100)] 
IQ2000: drop maintainer

After I found his email bouncing, Stan, via private communication which
Nick helped with, has indicated that - having retired - he won't any
longer fulfill the maintainer role here.

5 months agox86: GOT is an ELF-only entity
Jan Beulich [Fri, 21 Feb 2025 09:28:24 +0000 (10:28 +0100)] 
x86: GOT is an ELF-only entity

Make md_undefined_symbol() conditional upon dealing with ELF, much like
other architectures (e.g. Arm32 and Arm64) have it. This avoids errors
in gas and even assertions in libbfd when "accidentally" e.g. a COFF-
targeting source file uses "_GLOBAL_OFFSET_TABLE_" for whatever reason.

While there also convert the final return statement to properly use
NULL.

NB: In principle 64-bit Mach-O knows GOT, too. Yet only an i?86-macho
assembler can be built right now, as per configure.tgt. Pretty clearly
adjustments to gotrel[] would also be necessary before these targets
could actually work reasonably cleanly.

5 months agoix86: drop dead part of a conditional in elf_i386_convert_load_reloc()
Jan Beulich [Fri, 21 Feb 2025 09:27:35 +0000 (10:27 +0100)] 
ix86: drop dead part of a conditional in elf_i386_convert_load_reloc()

A few lines up we would have already bailed when "baseless && is_pic".

5 months agoix86: restrict use of GOT32X relocs
Jan Beulich [Fri, 21 Feb 2025 09:26:59 +0000 (10:26 +0100)] 
ix86: restrict use of GOT32X relocs

The ELF linker rejects use of this reloc type without a base register
for PIC code. Suppress its use by gas in such cases.

To keep things building for non-ELF, include the entire containing if()
in an #ifdef: All consumers of ->fx_tcbit* live in such conditionals as
well, hence there's no reason to keep the producer active.

5 months agox86-64: further tighten convert-load-reloc checking
Jan Beulich [Fri, 21 Feb 2025 09:25:41 +0000 (10:25 +0100)] 
x86-64: further tighten convert-load-reloc checking

REX2.M affects what insn we're actually dealing with, so we better check
this to avoid transforming (future) insns we must not touch.

5 months agox86: widen @got{,pcrel} support to PUSH and APX IMUL
Jan Beulich [Fri, 21 Feb 2025 09:24:50 +0000 (10:24 +0100)] 
x86: widen @got{,pcrel} support to PUSH and APX IMUL

With us doing the transformation to an immediate operand for MOV and
various ALU insns, there's little reason to then not support the same
conversion for the other two insns which have respective immediate
operand forms. Unfortunately for IMUL (due to the 0F opcode prefix)
there's no suitable relocation, so the pre-APX forms cannot be marked
for relaxation in the assembler.

5 months agox86/APX: use CS: in place of ES: in @gotpcrel and @gottpoff relaxation
Jan Beulich [Fri, 21 Feb 2025 09:23:21 +0000 (10:23 +0100)] 
x86/APX: use CS: in place of ES: in @gotpcrel and @gottpoff relaxation

H.J. requested this adjustment; I'm unaware of any specific technical
background.

5 months agoix86: tighten convert-load-reloc checking
Jan Beulich [Fri, 21 Feb 2025 09:22:50 +0000 (10:22 +0100)] 
ix86: tighten convert-load-reloc checking

Just like was done recently for x86-64 (commit 4998f9ea9d35): Even if
the assembler avoids using the relaxable relocation for inapplicable
insns, the relocation type can still appear for other reasons. Be more
thorough in the opcode checking we do, to avoid bogusly altering other
insns.

Furthermore correct an opcode mask (even if with the added condition
that's now fully benign).

5 months agoAutomatic date update in version.in
GDB Administrator [Fri, 21 Feb 2025 00:00:15 +0000 (00:00 +0000)] 
Automatic date update in version.in

5 months agogdb/doc: fix sentence in save gdb-index` command doc
Simon Marchi [Thu, 20 Feb 2025 16:38:04 +0000 (11:38 -0500)] 
gdb/doc: fix sentence in save gdb-index` command doc

The part "... this command by default creates it produces a single ..."
sounds wrong.  Replace with "... this command by default produces a
single ...".

Change-Id: I39cc533fa5a2bf473ca9e361ee0e6426d7d37ac6

5 months agoFix "compilation unit" matching in dwarf-font-lock-keywords
Tom Tromey [Thu, 20 Feb 2025 16:38:05 +0000 (09:38 -0700)] 
Fix "compilation unit" matching in dwarf-font-lock-keywords

Today I learned that, at least on my system (Fedora 40), the printf
"%#x" format will produce "0" rather than "0x0" when given 0 as an
argument.

This causes dwarf-mode.el to not correctly fontify the very first
"Compilation Unit" line it sees.

This patch adapts dwarf-mode.el.  As always, this patch bumps the
version number for easier installation.

I am checking this in.

5 months agogdb/doc: fix .debug_index -> .gdb_index
Simon Marchi [Thu, 20 Feb 2025 16:28:11 +0000 (11:28 -0500)] 
gdb/doc: fix .debug_index -> .gdb_index

Change-Id: Ibd8d6c35c2cc02e309f83b11b5fd1172dfa05283

5 months agogdb/compile: add missing entry in bfd_link_callbacks array
Simon Marchi [Thu, 20 Feb 2025 15:13:38 +0000 (10:13 -0500)] 
gdb/compile: add missing entry in bfd_link_callbacks array

clang 19 fails to build gdb with this error:

    /home/simark/src/binutils-gdb/gdb/compile/compile-object-load.c:302:3: error: cannot initialize a member subobject of type 'void (*)(const char *, ...) __attribute__((noreturn))' with an lvalue of type 'void (const char *, ...)'
      302 |   link_callbacks_einfo, /* einfo */
          |   ^~~~~~~~~~~~~~~~~~~~

This illustrates that the bfd_link_callbacks array is missing an entry
for the "fatal" callback, add it.

The fatal field was added very recently, in d26161914 ("PR 32603, more
ld -w misbehaviour").  We're lucky that the new callback was marked with
the noreturn attribute and that clang checks that, otherwise this would
have gone unnoticed.

Change-Id: I68b63d89f2707359e6254da23bdc0776b0e03ba2

5 months agoHandle optional lines correctly in gdb.ada/complete.exp
Tom Tromey [Thu, 5 Sep 2024 18:09:43 +0000 (12:09 -0600)] 
Handle optional lines correctly in gdb.ada/complete.exp

While working on another series, I discovered that the existing code
in gdb.ada/complete.exp that conditionally accepts a completion does
not work correctly.  The code assumes that wrapping a line in "(...)?"
will make the entire line optional, but really this will only match a
blank line.

Meanwhile, I needed this same patch for a second series I'm working
on, so I've pulled this out.  As it only affects Ada, I am going to
check it in.

5 months agoSmall get_tib_address cleanups
Tom Tromey [Wed, 19 Feb 2025 15:55:37 +0000 (08:55 -0700)] 
Small get_tib_address cleanups

I noticed a non-bool-like use of target_get_tib_address in
windows-tdep.c.  After fixing this I thought it would be good to
document the target method; and this also lead to some non-bool-like
commentary in remote.c.  This patch fixes all of these nits.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
5 months agoGDB: add stabs deprecation warning
Guinevere Larsen [Mon, 17 Feb 2025 19:43:04 +0000 (16:43 -0300)] 
GDB: add stabs deprecation warning

Now that stabs is deprecated, we should probably warn our users of it
before removing support, so that they have time to react and either make
themselves heard, or fix things on their end so that they can still debug
their applications.

This commit adds a new function that emits a warning whenever GDB does
stabs reading. Since there are several places where stabs is
re-invented, this warning had to be added to many places, but I think I
managed to warn everywhere relevant without duplicating warnings.

Also, the test gdb.stabs/weird.exp explicitly checks for GDB warnings
when reading stabs, so it had to be updated to account for the
deprecation warning. It is done generically, since it will be removed in
the next release anyway.

Approved-By: Tom Tromey <tom@tromey.com>
5 months agoPR 32721, internal error in tc-i386.c:parse_register
Alan Modra [Thu, 20 Feb 2025 01:19:25 +0000 (11:49 +1030)] 
PR 32721, internal error in tc-i386.c:parse_register

pr30117 showed one of the assertions added by 4d1bb7955a8b was too
strict.  oss-fuzz also found the second assertion to be too strict,
with this testcase distilled from 7k of garbage source:

 A=%eax%%!
 Y=A
 Z=A
 or $6,Z

PR 32721
* config/tc-i386.c (parse_register): Move "know" into
condition.  Simplify.

5 months agoHoist language-finding in expand_symtabs_matching
Tom Tromey [Sat, 8 Feb 2025 02:14:35 +0000 (19:14 -0700)] 
Hoist language-finding in expand_symtabs_matching

Right now, cooked_index_functions::expand_symtabs_matching computes
the language for each component of a split name, using the language of
the corresponding entry.

Instead, I think that we want to do all the comparisons using the
final entry's language.  I don't think there's a way to trigger bad
behavior here right now, but with another series I'm working on, we
end up with some entries whose language can't reliably be determined;
and in this case using the final entry's language avoids issues.

I suspect we could also dispense with the per-segment name-matcher
lookup as well.

5 months agoMove producer checks to dwarf2_cu
Tom Tromey [Fri, 31 Jan 2025 18:25:45 +0000 (11:25 -0700)] 
Move producer checks to dwarf2_cu

This changes the various producer-checking functions to be methods on
dwarf2_cu.  It adds a few new caching members as well -- every one
that could reasonably be done this way has been converted, with the
only exception being a gdbarch hook.

Note the new asserts in the accessors.  Without the earlier
prepare_one_comp_unit change, these could trigger in some modes.

5 months agoMake prepare_one_comp_unit a method of cutu_reader
Tom Tromey [Fri, 31 Jan 2025 19:38:15 +0000 (12:38 -0700)] 
Make prepare_one_comp_unit a method of cutu_reader

This changes prepare_one_comp_unit to be a private method of
cutu_reader.  This should make it somewhat simpler to reason about.

5 months agoClean up calls to prepare_one_comp_unit
Tom Tromey [Fri, 31 Jan 2025 19:25:05 +0000 (12:25 -0700)] 
Clean up calls to prepare_one_comp_unit

Currently, prepare_one_comp_unit is called somewhat haphazardly: it is
mostly called when a CU is read, but some places manage to instantiate
a cutu_reader* without calling it, and some code (e.g.,
read_file_scope) calls it without really needing to.

Aside from contributing to the general confusion around CU reading,
this doesn't really cause problems in the current tree.  However, it
is possible for the DWARF reader to check the CU's producer before it
is ever set -- which is certainly unintended.