The bug fixed by this [1] patch was caused by an out-of-bounds access to
a value's content. The code gets the value's content (just a pointer)
and then indexes it with a non-sensical index.
This made me think of changing functions that return value contents to
return array_views instead of a plain pointer. This has the advantage
that when GDB is built with _GLIBCXX_DEBUG, accesses to the array_view
are checked, making bugs more apparent / easier to find.
This patch changes the return types of these functions, and updates
callers to call .data() on the result, meaning it's not changing
anything in practice. Additional work will be needed (which can be done
little by little) to make callers propagate the use of array_view and
reap the benefits.
[1] https://sourceware.org/pipermail/gdb-patches/2021-September/182306.html
Change-Id: I5151f888f169e1c36abe2cbc57620110673816f3
This changes gdb to check the index that is passed to type::field.
This caught one bug in the Ada code when running the test suite
(actually I found the bug first, then realized that the check would
have helped), so this patch fixes that as well.
Regression tested on x86-64 Fedora 34.
A customer-reported problem led us to a bug in dynamic type
resolution. resolve_dynamic_struct will recursively call
resolve_dynamic_type_internal, passing it the sub-object for the
particular field being resolved. While it offsets the address here,
it does not also offset the "valaddr" -- the array of bytes describing
the memory.
This patch fixes the bug, by offsetting both. A test case is included
that can be used to reproduce the bug.
Add accessors for the various location values in struct field. This
lets us assert that when we get a location value of a certain kind (say,
bitpos), the field's location indeed contains a value of that kind.
Remove the SET_FIELD_* macros, instead use the new setters directly.
Update the FIELD_* macros used to access field locations to go through
the getters. They will be removed in a subsequent patch.
There are places where the FIELD_* macros are used on call_site_target
structures, because it contains members of the same name (loc_kind and
loc). For now, I have replicated the getters/setters in
call_site_target. But we could perhaps eventually factor them in a
"location" structure that can be used at both places.
Note that the field structure, being zero-initialized, defaults to a
bitpos location with value 0. While writing this patch, I tried to make
it default to an "unset" location, to catch places where we would miss
setting a field's location. However, I found that some places relied on
the default being "bitpos 0", so I left it as-is. This change could
always be done as follow-up work, making these places explicitly set the
"bitpos 0" location.
I found two issues to fix:
- I got some failures in the gdb.base/infcall-nested-structs-c++.exp
test. They were caused by two functions in amd64-tdep.c using
TYPE_FIELD_BITPOS before checking if the location is of the bitpos
kind, which they do indirectly through `field_is_static`. Simply
move getting the bitpos below the field_is_static call.
- I got a failure in gdb.xml/tdesc-regs.exp. It turns out that in
make_gdb_type_enum, we set enum field values using SET_FIELD_BITPOS,
and later access them through FIELD_ENUMVAL. Fix that by using
set_loc_enumval to set the value.
Change-Id: I53d3734916c46457576ba11dd77df4049d2fc1e8
I noticed that some methods in language_defn could use
unique_xmalloc_ptr<char> rather than a plain 'char *'. This patch
implements this change, fixing up the fallout and changing
gdb_demangle to also return this type. In one spot, std::string is
used to simplify some related code, and in another, an auto_obstack is
used to avoid manual management.
Regression tested on x86-64 Fedora 34.
Consider test-case gdb.trace/entry-values.exp with target board
unix/-fPIE/-pie.
Using this command we have an abbreviated version, and can see the correct
@entry values for foo:
...
$ gdb -q -batch outputs/gdb.trace/entry-values/entry-values \
-ex start \
-ex "break foo" \
-ex "set print entry-values both" \
-ex continue
Temporary breakpoint 1 at 0x679
Temporary breakpoint 1, 0x0000555555554679 in main ()
Breakpoint 2 at 0x55555555463e
Breakpoint 2, 0x000055555555463e in foo (i=0, i@entry=2, j=2, j@entry=3)
...
Now, let's try the same again, but run directly to foo rather than stopping at
main:
...
$ gdb -q -batch outputs/gdb.trace/entry-values/entry-values \
-ex "break foo" \
-ex "set print entry-values both" \
-ex run
Breakpoint 1 at 0x63e
Breakpoint 1, 0x000055555555463e in foo (i=0, i@entry=<optimized out>, \
j=2, j@entry=<optimized out>)
...
So, what explains the difference? Noteworthy, this is a dwarf assembly
test-case, with debug info for foo and bar, but not for main.
In the first case:
- we run to main
- this does not trigger expanding debug info, because there's none for main
- we set a breakpoint at foo
- this triggers expanding debug info. Relocated addresses are used in
call_site info (because the exec is started)
- we continue to foo, and manage to find the call_site info
In the second case:
- we set a breakpoint at foo
- this triggers expanding debug info. Unrelocated addresses are used in
call_site info (because the exec is not started)
- we run to foo
- this triggers objfile_relocate1, but it doesn't update the call_site
info addresses
- we don't manage to find the call_site info
We could fix this by adding the missing call_site relocation in
objfile_relocate1.
This solution however is counter-trend in the sense that we're trying to
work towards the situation where when starting two instances of an executable,
we need only one instance of debug information, implying the use of
unrelocated addresses.
So, fix this instead by using unrelocated addresses in call_site info.
Tested on x86_64-linux.
This fixes all remaining unix/-fno-PIE/-no-pie vs unix/-fPIE/-pie
regressions, like f.i. PR24892.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24892
Co-Authored-By: Tom de Vries <tdevries@suse.de>
Remove the `TYPE_FIELD_NAME` and `FIELD_NAME` macros, changing all the
call sites to use field::name directly.
Change-Id: I6900ae4e1ffab1396e24fb3298e94bf123826ca6
Add the `name` and `set_name` methods on `struct field`, in order to
remove `FIELD_NAME` and `TYPE_FIELD_NAME` macros. In this patch, the
macros are changed to use `field::name`, so all the call sites that are
used to set the field's name are changed to use `field::set_name`.
The next patch will remove the macros completely.
Note that because of the name clash between the existing field named
`name` and the new method, I renamed the field `m_name`. It is not
private per-se, because we can't make `struct field` a non-POD yet, but
it should be considered private anyway (not accessed outside `struct
field`).
Change-Id: If16ddbca4e0c39d0ff9da420bb5cdebe5b9b0896
I noticed that pointer_type is declared in language.h and defined in
language.c. However, it really has to do with types, so it should
have been in gdbtypes.h all along.
This patch changes it to be a method on struct type. And, I went
through uses of TYPE_IS_REFERENCE and updated many spots to use the
new method as well. (I didn't update ones that were in arch-specific
code, as I couldn't readily test that.)
The case for FIELD_LOC_KIND_DWARF_BLOCK was missing for
switch TYPE_FIELD_LOC_KIND. Thas caused an internal-error
under some circumstances.
Fixes bug 28030.
When printing the fields of a register that is of a custom struct type,
the "unpack_bits_as_long ()" function is used:
do_val_print (...)
cp_print_value_fields (...)
value_field_bitfield (...)
unpack_value_bitfield (...)
unpack_bits_as_long (...)
This function may sign-extend the extracted field while returning it:
val >>= lsbcount;
if (...)
{
valmask = (((ULONGEST) 1) << bitsize) - 1;
val &= valmask;
if (!field_type->is_unsigned ())
if (val & (valmask ^ (valmask >> 1)))
val |= ~valmask;
}
return val;
lsbcount: Number of lower bits to get rid of.
bitsize: The bit length of the field to be extracted.
val: The register value.
field_type: The type of field that is being handled.
While the logic here is correct, there is a problem when it is
handling "field_type"s of "boolean". Those types are NOT marked
as "unsigned" and therefore they end up being sign extended.
Although this is not a problem for "false" (0), it definitely
causes trouble for "true".
This patch constructs the builtin boolean type as such that it is
marked as an "unsigned" entity.
The issue tackled here was first encountered for arc-elf32 target
running on an x86_64 machine. The unit-test introduced in this change
has passed for all the targets (--enable-targets=all) running on the
same x86_64 host.
Fixes: https://sourceware.org/PR28104
The assertion
gdb_assert (nr_bits >= 1 && nr_bits <= type_bitsize);
is not correct. Well, it's correct in that we do want the number of
bits to be in the range [1, type_bitsize]. But we don't check anywhere
that the end of the specified flag is within the containing type.
The following code should generate a failed assertion, as the flag goes
past the 32 bits of the underlying type, but it's currently not caught:
static void
test_print_flag (gdbarch *arch)
{
type *flags_type = arch_flags_type (arch, "test_type", 32);
type *field_type = builtin_type (arch)->builtin_uint32;
append_flags_type_field (flags_type, 31, 2, field_type, "invalid");
}
(You can test this by registering it as a selftest using
selftests::register_test_foreach_arc and running.)
Change the assertion to verify that the end bit is within the range of
the underlying type. This implicitly verifies that nr_bits is not
too big as well, so we don't need a separate assertion for that.
Change-Id: I9be79e5fd7a5917bf25b03b598727e6274c892e8
Co-Authored-By: Tony Tye <Tony.Tye@amd.com>
Calling the `make-value' procedure with an integer value and a pointer
type for the #:type argument triggers a failed assertion in
`get_unsigned_type_max', as that function doesn't consider pointers to
be an unsigned type. This commit fixes the issue by adding a separate
code path for pointers.
As previously suggested, range checking is done using a new helper
function in gdbtypes.
gdb/ChangeLog:
2021-07-30 George Barrett <bob@bob131.so>
* gdbtypes.h (get_pointer_type_max): Add declaration.
* gdbtypes.c (get_pointer_type_max): Add definition for new
helper function.
* guile/scm-math.c (vlscm_convert_typed_number): Add code path
for handling conversions to pointer types without failing an
assert.
gdb/testsuite/ChangeLog:
2021-07-30 George Barrett <bob@bob131.so>
* gdb.guile/scm-math.exp (test_value_numeric_ops): Add test
for creating pointers with make-value.
(test_make_pointer_value, test_pointer_numeric_range): Add
test procedures containing checks for integer-to-pointer
validation.
Change-Id: I9994dd1c848840a3d995f745e6d72867732049f0
Changes the signature of get_unsigned_type_max to return the computed
value rather than returning void and writing the value into a pointer
passed by the caller.
gdb/ChangeLog:
2021-07-30 George Barrett <bob@bob131.so>
* gdbtypes.h (get_unsigned_type_max): Change signature to
return the result instead of accepting a pointer argument in
which to store the result.
* gdbtypes.c (get_unsigned_type_max): Likewise.
* guile/scm-math.c (vlscm_convert_typed_number): Update caller
of get_unsigned_type_max.
(vlscm_integer_fits_p): Likewise.
Change-Id: Ibb1bf0c0fa181fac7853147dfde082a7d1ae2323
Investigation of using the Python API with an Ada program showed that
an array of dynamic types was not being handled properly. I tracked
this down to an oddity of how array strides are handled.
In gdb, an array stride can be attached to the range type, via the
range_bounds object. However, the stride can also be put into the
array's first field. From create_range_type_with_stride:
else if (bit_stride > 0)
TYPE_FIELD_BITSIZE (result_type, 0) = bit_stride;
It's hard to be sure why this is done, but I would guess a combination
of historical reasons plus a desire (mentioned in a comment somewhere)
to avoid modifying the range type.
This patch fixes the problem by changing type::bit_stride to
understand this convention. It also fixes one spot that reproduces
this logic.
Regression tested on x86-64 Fedora 32.
I wrote a small script to spot a pattern of indentation mistakes I saw
happened in breakpoint.c. And while at it I ran it on all files and
fixed what I found. No behavior changes intended, just indentation and
addition / removal of curly braces.
gdb/ChangeLog:
* Fix some indentation mistakes throughout.
gdbserver/ChangeLog:
* Fix some indentation mistakes throughout.
Change-Id: Ia01990c26c38e83a243d8f33da1d494f16315c6e
I noticed that in types equal we start with a cheap pointer equality
check, then resolve typedefs, then do a series of (semi-)expensive
checks, including checking type names, before, finally performing
another pointer equality check.
We should hoist the second pointer equality check to immediately after
we have resolved typedefs. This would save performing the more
expensive checks.
This isn't going to give any noticable performance improvement, I just
spotted this in passing and figured I might as well commit the fix.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* gdbtypes.c (types_equal): Move pointer equality check earlier in
the function.
resolve_dynamic_struct says:
gdb_assert (type->num_fields () > 0);
However, a certain Ada program has a structure with no fields but with
a dynamic size, causing this assertion to fire.
It is difficult to be certain, but we think this is a compiler bug.
However, in the meantime this assertion does not seem to be checking
any kind of internal consistency; so this patch removes it.
gdb/ChangeLog
2021-02-09 Tom Tromey <tromey@adacore.com>
* gdbtypes.c (resolve_dynamic_struct): Handle structure with no
fields.
I'm running into this assertion failure:
...
$ gdb -batch -ex "p (void *)0 - 5i"
gdbtypes.c:3430: internal-error: \
type* init_complex_type(const char*, type*): Assertion \
`target_type->code () == TYPE_CODE_INT \
|| target_type->code () == TYPE_CODE_FLT' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
...
This is a regression since commit c34e871466 "Implement complex arithmetic".
Before that commit we had:
...
(gdb) p (void *)0 - 5i
Argument to arithmetic operation not a number or boolean.
...
Fix this in complex_binop by throwing an error, such that we have:
...
(gdb) print (void *)0 - 5i
Argument to complex arithmetic operation not supported.
...
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-05 Tom de Vries <tdevries@suse.de>
PR exp/27265
* valarith.c (complex_binop): Throw an error if complex type can't
be created.
gdb/testsuite/ChangeLog:
2021-02-05 Tom de Vries <tdevries@suse.de>
PR exp/27265
* gdb.base/complex-parts.exp: Add tests.
I think this makes the names of the methods clearer, especially for the
arch. The type::arch method (which gets the arch owner, or NULL if the
type is not arch owned) is easily confused with the get_type_arch method
(which returns an arch no matter what). The name "arch_owner" will make
it intuitive that the method returns NULL if the type is not arch-owned.
Also, this frees the type::arch name, so we will be able to morph the
get_type_arch function into the type::arch method.
gdb/ChangeLog:
* gdbtypes.h (struct type) <arch>: Rename to...
<arch_owner>: ... this, update all users.
<objfile>: Rename to...
<objfile_owner>: ... this, update all users.
Change-Id: Ie7c28684c7b565adec05a7619c418c69429bd8c0
Commit 5b7d941b90 ("gdb: add owner-related methods to struct type")
introduced a regression when running gdb.base/jit-reader-simple.exp and
others. A NULL pointer dereference happens here:
#3 0x0000557b7e9e8650 in gdbarch_obstack (arch=0x0) at /home/simark/src/binutils-gdb/gdb/gdbarch.c:484
#4 0x0000557b7ea5b138 in copy_type_recursive (objfile=0x614000006640, type=0x62100018da80, copied_types=0x62100018e280) at /home/simark/src/binutils-gdb/gdb/gdbtypes.c:5537
#5 0x0000557b7ea5dcbb in copy_type_recursive (objfile=0x614000006640, type=0x62100018e200, copied_types=0x62100018e280) at /home/simark/src/binutils-gdb/gdb/gdbtypes.c:5598
#6 0x0000557b802cef51 in preserve_one_value (value=0x6110000b3640, objfile=0x614000006640, copied_types=0x62100018e280) at /home/simark/src/binutils-gdb/gdb/value.c:2518
#7 0x0000557b802cf787 in preserve_values (objfile=0x614000006640) at /home/simark/src/binutils-gdb/gdb/value.c:2562
#8 0x0000557b7fbaf19b in reread_symbols () at /home/simark/src/binutils-gdb/gdb/symfile.c:2489
#9 0x0000557b7ec65d1d in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at /home/simark/src/binutils-gdb/gdb/infcmd.c:439
#10 0x0000557b7ec67a97 in run_command (args=0x0, from_tty=1) at /home/simark/src/binutils-gdb/gdb/infcmd.c:546
This is inside a TYPE_ALLOC macro. The fact that gdbarch_obstack is
called means that the type is flagged as being arch-owned, but arch=0x0
means that type::arch returned NULL, probably meaning that the m_owner
field contains NULL.
If we look at the code before the problematic patch, in the
copy_type_recursive function, we see:
if (! TYPE_OBJFILE_OWNED (type))
return type;
...
TYPE_OBJFILE_OWNED (new_type) = 0;
TYPE_OWNER (new_type).gdbarch = get_type_arch (type);
The last two lines were replaced with:
new_type->set_owner (type->arch ());
get_type_arch and type->arch isn't the same thing: get_type_arch gets
the type's arch owner if it is arch-owned, and gets the objfile's arch
if the type is objfile owned. So it always returns non-NULL.
type->arch returns the type's arch if the type is arch-owned, else NULL.
So since the original type is objfile owned, it effectively made the new
type arch-owned (that is good) but set the owner to NULL (that is bad).
Fix this by using get_type_arch again there.
I spotted one other similar change in lookup_array_range_type, in the
original patch. But that one appears to be correct, as it is executed
only if the type is arch-owned.
Add some asserts in type::set_owner to ensure we never set a NULL owner.
That would have helped catch the issue a little bit earlier, so it could
help in the future.
gdb/ChangeLog:
* gdbtypes.c (copy_type_recursive): Use get_type_arch.
* gdbtypes.h (struct type) <set_owner>: Add asserts.
Change-Id: I5d8bc7bfc83b3abc579be0b5aadeae4241179a00
Change all users to use the type::objfile method instead.
gdb/ChangeLog:
* gdbtypes.h (TYPE_OBJFILE): Remove, change all users to use the
type::objfile method instead.
Change-Id: I6b3f580913fb1fb0cf986b176dba8db68e1fabf9
Update all users to use the type::is_objfile_owned method.
gdb/ChangeLog:
* gdbtypes.h (TYPE_OBJFILE_OWNED): Remove, update all users to
use the type::is_objfile_owned method.
Change-Id: Icae84d136393ab9f756f50a33ac3cedda13c5ba2
Add the following methods to struct type:
* is_objfile_owned
* set_owner (objfile and gdbarch overloads)
* objfile and arch getters
Rename the fields in main_type to ensure no other code accesses them
directly. As usual, we can't make them actually private, but giving
them the `m_` prefix will help making sure they are not accessed when
not supposed to, by convention.
Remove the TYPE_OWNER macro to ensure no code uses the type_owner struct
directly.
gdb/ChangeLog:
* gdbtypes.h (TYPE_OBJFILE_OWNED): Adjust.
(TYPE_OWNER): Remove.
(TYPE_OBJFILE): Adjust.
(struct main_type) <flag_objfile_owned>: Rename to...
<m_flag_objfile_owned>: ... this.
<owner>: Rename to...
<m_owner>: ... this.
(struct type) <is_objfile_owned, set_owner, objfile, arch>: New
methods.
(TYPE_ALLOC): Adjust.
* gdbtypes.c (alloc_type): Adjust.
(alloc_type_arch): Adjust.
(alloc_type_copy): Adjust.
(get_type_arch): Adjust.
(smash_type): Adjust.
(lookup_array_range_type): Adjust.
(recursive_dump_type): Adjust.
(copy_type_recursive): Adjust.
* compile/compile-c-types.c (convert_func): Adjust.
(convert_type_basic): Adjust.
* compile/compile-cplus-types.c (compile_cplus_convert_func):
Adjust.
* language.c
(language_arch_info::type_and_symbol::alloc_type_symbol):
Adjust.
Change-Id: I7f92e869d9f92e2402a3d3007dd0832e05aa6ac8
This commits the result of running gdb/copyright.py as per our Start
of New Year procedure...
gdb/ChangeLog
Update copyright year range in copyright header of all GDB files.
In PR gdb/27059 an issue was discovered where GDB would sometimes
trigger undefined behaviour in the form of signed integer overflow.
The problem here is that GDB was reading random garbage from the
inferior memory space, assuming this data was valid, and performing
arithmetic on it.
This bug raises an interesting general problem with GDB's DWARF
expression evaluator, which is this:
We currently assume that the DWARF expressions being evaluated are
well formed, and well behaving. As an example, this is the expression
that the bug was running into problems on, this was used as the
expression for a DW_AT_byte_stride of a DW_TAG_subrange_type:
DW_OP_push_object_address;
DW_OP_plus_uconst: 88;
DW_OP_deref;
DW_OP_push_object_address;
DW_OP_plus_uconst: 32;
DW_OP_deref;
DW_OP_mul
Two values are read from the inferior and multiplied together. GDB
should not assume that any value read from the inferior is in any way
sane, as such the implementation of DW_OP_mul should be guarding
against overflow and doing something semi-sane here.
However, it turns out that the original bug PR gdb/27059, is hitting a
more specific case, which doesn't require changes to the DWARF
expression evaluator, so I'm going to leave the above issue for
another day.
In the test mentioned in the bug GDB is actually trying to resolve the
dynamic type of a Fortran array that is NOT allocated. A
non-allocated Fortran array is one that does not have any data
allocated for it yet, and even the upper and lower bounds of the array
are not yet known.
It turns out that, at least for gfortran compiled code, the data
fields that describe the byte-stride are not initialised until the
array is allocated.
This leads me to the following conclusion: GDB should not try to
resolve the bounds, or stride information for an array that is not
allocated (or not associated, a similar, but slightly different
Fortran feature). Instead, each of these properties should be set to
undefined if the array is not allocated (or associated).
That is what this commit does. There's a new flag that is passed
around during the dynamic array resolution. When this flag is true
the dynamic properties are resolved using the DWARF expressions as
they currently are, but when this flag is false the expressions are
not evaluated, and instead the properties are set to undefined.
gdb/ChangeLog:
PR gdb/27059
* eval.c (evaluate_subexp_for_sizeof): Handle not allocated and
not associated arrays.
* f-lang.c (fortran_adjust_dynamic_array_base_address_hack): Don't
adjust arrays that are not allocated/associated.
* gdbtypes.c (resolve_dynamic_range): Update header comment. Add
new parameter which is used to sometimes set dynamic properties to
undefined.
(resolve_dynamic_array_or_string): Update header comment. Add new
parameter which is used to guard evaluating dynamic properties.
Resolve allocated/associated properties first.
gdb/testsuite/ChangeLog:
PR gdb/27059
* gdb.dwarf2/dyn-type-unallocated.c: New file.
* gdb.dwarf2/dyn-type-unallocated.exp: New file.
Adds the allocated and associated dynamic properties into the output
of the 'maintenance print type' command.
gdb/ChangeLog:
* gdbtypes (recursive_dump_type): Include allocated and associated
properties.
When called with an array type of unknown dimensions,
is_scalar_type_recursive ended up comparing uninitialized values.
This was picked up by the following compiler warning:
CXX gdbtypes.o
/binutils-gdb/gdb/gdbtypes.c: In function int is_scalar_type_recursive(type*):
/binutils-gdb/gdb/gdbtypes.c:3670:38: warning: high_bound may be used uninitialized in this function [-Wmaybe-uninitialized]
3670 | return high_bound == low_bound && is_scalar_type_recursive (elt_type);
| ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/binutils-gdb/gdb/gdbtypes.c:3670:38: warning: low_bound may be used uninitialized in this function [-Wmaybe-uninitialized]
This patch makes sure that when dealing with an array of unknown size
(or an array of more than 1 element), is_scalar_type_recursive returns
false.
gdb/ChangeLog:
* gdbtypes.c (is_scalar_type_recursive): Prevent comparison
between uninitialized values.
Change-Id: Ifc005ced166aa7a065fef3e652977bae67625bf4
Comparing types of enum fields results in a crash, because they don't
have a type.
It can be reproduced by comparing the types of 2 instances of the same
enum type in different objects:
enum.h:
enum e
{
zero,
one,
};
enum-1.c:
#include <enum.h>
int func();
enum e e1;
int main()
{
return e1 + func();
}
enum-2.c:
#include <enum.h>
enum e e2;
int func()
{
return e2;
}
$ gcc -g -oenum enum-1.c enum-2.c
$ gdb -q enum.exe
Reading symbols from enum.exe...
(gdb) py print(gdb.parse_and_eval("e1").type==gdb.parse_and_eval("e2").type)
Thread 1 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 6184.0x1cc4]
check_typedef (type=0x0) at C:/src/repos/binutils-gdb.git/gdb/gdbtypes.c:2745
2745 while (type->code () == TYPE_CODE_TYPEDEF)
gdb/ChangeLog:
2020-12-19 Hannes Domani <ssbssa@yahoo.de>
PR exp/27070
* gdbtypes.c (check_types_equal): Don't compare types of enum fields.
gdb/testsuite/ChangeLog:
2020-12-19 Hannes Domani <ssbssa@yahoo.de>
PR exp/27070
* gdb.python/compare-enum-type-a.c: New test.
* gdb.python/compare-enum-type-b.c: New test.
* gdb.python/compare-enum-type.exp: New file.
* gdb.python/compare-enum-type.h: New test.
After seeing Simon's patch, I thought maybe it was finally time to
remove printfi_filtered and fprintfi_filtered, in favor of using the
"%*s" approach to indenting.
In this patch I took the straightforward approach of always adding a
leading "%*s", even when the format already started with "%s", to
avoid the trickier form of:
printf ("%*s", -indent, string)
Regression tested on x86-64 Fedora 32.
Let me know what you think.
gdb/ChangeLog
2020-12-17 Tom Tromey <tromey@adacore.com>
* gdbtypes.c (print_args, dump_fn_fieldlists, print_cplus_stuff)
(print_gnat_stuff, print_fixed_point_type_info)
(recursive_dump_type): Update.
* go32-nat.c (go32_sysinfo, display_descriptor): Update.
* c-typeprint.c (c_type_print_base_struct_union)
(c_type_print_base_1): Update.
* rust-lang.c (rust_internal_print_type): Update.
* f-typeprint.c (f_language::f_type_print_base): Update.
* utils.h (fprintfi_filtered, printfi_filtered): Remove.
* m2-typeprint.c (m2_record_fields): Update.
* p-typeprint.c (pascal_type_print_base): Update.
* compile/compile-loc2c.c (push, pushf, unary, binary)
(do_compile_dwarf_expr_to_c): Update.
* utils.c (fprintfi_filtered, printfi_filtered): Remove.
I noticed that the argumen to parse_and_eval_type could be "const".
This patch implements this change.
I wonder if this could be removed. It's only called via
check_stub_method_group, which seems questionable to me. However, I
didn't look into doing this.
gdb/ChangeLog
2020-12-13 Tom Tromey <tom@tromey.com>
* gdbtypes.c (safe_parse_type): Make argument const.
* value.h (parse_and_eval_type): Make argument const.
* eval.c (parse_and_eval_type): Make argument const.
I forgot to include fixes for review comments I got before pushing the
previous commits (or I pushed the wrong commits). This one fixes it.
- Return {} instead of false in get_discrete_low_bound and
get_discrete_high_bound.
- Compute high bound after confirming low bound is valid in
get_discrete_bounds.
gdb/ChangeLog:
* gdbtypes.c (get_discrete_low_bound, get_discrete_high_bound):
Return {} instead of false.
(get_discrete_bounds): Compute high bound only if low bound is
valid.
Change-Id: I5f9a66b3672adfac9441068c899ab113ab2c331a
Since commit 7c6f271296 ("gdb: make get_discrete_bounds check for
non-constant range bounds"), subscripting flexible array member fails:
struct no_size
{
int n;
int items[];
};
(gdb) p *ns
$1 = {n = 3, items = 0x5555555592a4}
(gdb) p ns->items[0]
Cannot access memory at address 0xfffe555b733a0164
(gdb) p *((int *) 0x5555555592a4)
$2 = 101 <--- we would expect that
(gdb) p &ns->items[0]
$3 = (int *) 0xfffe5559ee829a24 <--- wrong address
Since the flexible array member (items) has an unspecified size, the array type
created for it in the DWARF doesn't have dimensions (this is with gcc 9.3.0,
Ubuntu 20.04):
0x000000a4: DW_TAG_array_type
DW_AT_type [DW_FORM_ref4] (0x00000038 "int")
DW_AT_sibling [DW_FORM_ref4] (0x000000b3)
0x000000ad: DW_TAG_subrange_type
DW_AT_type [DW_FORM_ref4] (0x00000031 "long unsigned int")
This causes GDB to create a range type (TYPE_CODE_RANGE) with a defined
constant low bound (dynamic_prop with kind PROP_CONST) and an undefined
high bound (dynamic_prop with kind PROP_UNDEFINED).
value_subscript gets both bounds of that range using
get_discrete_bounds. Before commit 7c6f271296, get_discrete_bounds
didn't check the kind of the dynamic_props and would just blindly read
them as if they were PROP_CONST. It would return 0 for the high bound,
because we zero-initialize the range_bounds structure. And it didn't
really matter in this case, because the returned high bound wasn't used
in the end.
Commit 7c6f271296 changed get_discrete_bounds to return a failure if
either the low or high bound is not a constant, to make sure we don't
read a dynamic prop that isn't a PROP_CONST as a PROP_CONST. This
change made get_discrete_bounds start to return a failure for that
range, and as a result would not set *lowp and *highp. And since
value_subscript doesn't check get_discrete_bounds' return value, it just
carries on an uses an uninitialized value for the low bound. If
value_subscript did check the return value of get_discrete_bounds, we
would get an error message instead of a bogus value. But it would still
be a bug, as we wouldn't be able to print the flexible array member's
elements.
Looking at value_subscript, we see that the low bound is always needed,
but the high bound is only needed if !c_style. So, change
value_subscript to use get_discrete_low_bound and
get_discrete_high_bound separately. This fixes the case described
above, where the low bound is known but the high bound isn't (and is not
needed). This restores the original behavior without accessing a
dynamic_prop in a wrong way.
A test is added. In addition to the case described above, a case with
an array member of size 0 is added, which is a GNU C extension that
existed before flexible array members were introduced. That case
currently fails when compiled with gcc <= 8. gcc <= 8 produces DWARF
similar to the one shown above, while gcc 9 adds a DW_AT_count of 0 in
there, which makes the high bound known. A case where an array member
of size 0 is the only member of the struct is also added, as that was
how PR 28675 was originally reported, and it's an interesting corner
case that I think could trigger other funny bugs.
Question about the implementation: in value_subscript, I made it such
that if the low or high bound is unknown, we fall back to zero. That
effectively makes it the same as it was before 7c6f271296. But should
we instead error() out?
gdb/ChangeLog:
PR 26875, PR 26901
* gdbtypes.c (get_discrete_low_bound): Make non-static.
(get_discrete_high_bound): Make non-static.
* gdbtypes.h (get_discrete_low_bound): New declaration.
(get_discrete_high_bound): New declaration.
* valarith.c (value_subscript): Only fetch high bound if
necessary.
gdb/testsuite/ChangeLog:
PR 26875, PR 26901
* gdb.base/flexible-array-member.c: New test.
* gdb.base/flexible-array-member.exp: New test.
Change-Id: I832056f80e6c56f621f398b4780d55a3a1e299d7
get_discrete_bounds is not flexible for ranges (TYPE_CODE_RANGE), in the
sense that it returns true (success) only if both bounds are present and
constant values.
This is a problem for code that only needs to know the low bound and
fails unnecessarily if the high bound is unknown.
Split the function in two, get_discrete_low_bound and
get_discrete_high_bound, that both return an optional. Provide a new
implementation of get_discrete_bounds based on the two others, so the
callers don't have to be changed.
gdb/ChangeLog:
* gdbtypes.c (get_discrete_bounds): Implement with
get_discrete_low_bound and get_discrete_high_bound.
(get_discrete_low_bound): New.
(get_discrete_high_bound): New.
Change-Id: I986b5e9c0dd969800e3fb9546af9c827d52e80d0