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 c34e8714662 "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 5b7d941b90d1 ("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 7c6f27129631 ("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 7c6f27129631, 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 7c6f27129631 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 7c6f27129631. 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
get_discrete_bounds currently has three possible return values (see its
current doc for details). It appears that for all callers, it would be
sufficient to have a boolean "worked" / "didn't work" return value.
Change the return type of get_discrete_bounds to bool and adjust all
callers. Doing so simplifies the following patch.
gdb/ChangeLog:
* gdbtypes.h (get_discrete_bounds): Return bool, adjust all
callers.
* gdbtypes.c (get_discrete_bounds): Return bool.
Change-Id: Ie51feee23c75f0cd7939742604282d745db59172
Instead of returning a boolean status and returning the value through a
pointer, return an optional that does both jobs. This helps in the
following patches, and I think it is an improvement in general.
gdb/ChangeLog:
* ada-lang.c (ada_value_slice_from_ptr): Adjust.
(ada_value_slice): Adjust.
(pos_atr): Adjust.
* gdbtypes.c (get_discrete_bounds): Adjust.
(discrete_position): Return optional.
* gdbtypes.h (discrete_position): Return optional.
Change-Id: I758dbd8858b296ee472ed39ec35db1dbd624a5ae
This logically connects this function to the object it inspects.
gdb/ChangeLog:
* gdbtypes.h (struct type) <fixed_point_scaling_factor>: New method,
replacing fixed_point_scaling_factor. All callers updated
throughout this project.
(fixed_point_scaling_factor): Delete declaration.
* gdbtypes.c (type::fixed_point_scaling_factor): Replaces
fixed_point_scaling_factor. Adjust implementation accordingly.
As suggested by Simon, to logically connect this function to
the object it inspects.
Note that, logically, this method should be "const". Unfortunately,
the implementation iterates on struct type objects starting with "this",
and thus trying to declare the method "const" triggers a compilation
error.
gdb/ChangeLog:
* gdbtypes.h (struct type) <fixed_point_type_base_type> New method,
replacing the fixed_point_type_base_type function. All callers
updated throughout this project.
(fixed_point_type_base_type): Remove declaration.
* gdbtypes.c (type::fixed_point_type_base_type): Replaces
fixed_point_type_base_type. Adjust implementation accordingly.
This is one step further towards the removal of all these macros.
gdb/ChangeLog:
* gdbtypes.h (struct type) <fixed_point_info, set_fixed_point_info>:
New methods.
(INIT_FIXED_POINT_SPECIFIC): Adjust.
(TYPE_FIXED_POINT_INFO): Delete macro.
(allocate_fixed_point_type_info): Change return type to void.
* gdbtypes.c (copy_type_recursive): Replace the use of
TYPE_FIXED_POINT_INFO by a call to the fixed_point_info method.
(fixed_point_scaling_factor): Likewise.
(allocate_fixed_point_type_info): Change return type to void.
Adjust implementation accordingly.
* dwarf2/read.c (finish_fixed_point_type): Replace the use of
TYPE_FIXED_POINT_INFO by a call to the fixed_point_info method.
This was suggested by Simon during a code review of this package upstream.
The upside is that this makes the function's API more natural and C++.
The downside is an extra malloc, which might be the reason why we went
for using a unique_xmalloc_ptr in the first place. Since this function
is not expected to be called frequently, the API improvement might be
worth the performance impact.
gdb/ChangeLog:
* gmp-utils.h (gmp_string_printf): Rename from gmp_string_asprintf.
Change return type to std::string. Update all callers.
* gmp-utils.c (gmp_string_printf): Likewise.
This commit brings array slice support to GDB.
WARNING: This patch contains a rather big hack which is limited to
Fortran arrays, this can be seen in gdbtypes.c and f-lang.c. More
details on this below.
This patch rewrites two areas of GDB's Fortran support, the code to
extract an array slice, and the code to print an array.
After this commit a user can, from the GDB prompt, ask for a slice of
a Fortran array and should get the correct result back. Slices can
(optionally) have the lower bound, upper bound, and a stride
specified. Slices can also have a negative stride.
Fortran has the concept of repacking array slices. Within a compiled
Fortran program if a user passes a non-contiguous array slice to a
function then the compiler may have to repack the slice, this involves
copying the elements of the slice to a new area of memory before the
call, and copying the elements back to the original array after the
call. Whether repacking occurs will depend on which version of
Fortran is being used, and what type of function is being called.
This commit adds support for both packed, and unpacked array slicing,
with the default being unpacked.
With an unpacked array slice, when the user asks for a slice of an
array GDB creates a new type that accurately describes where the
elements of the slice can be found within the original array, a
value of this type is then returned to the user. The address of an
element within the slice will be equal to the address of an element
within the original array.
A user can choose to select packed array slices instead using:
(gdb) set fortran repack-array-slices on|off
(gdb) show fortran repack-array-slices
With packed array slices GDB creates a new type that reflects how the
elements of the slice would look if they were laid out in contiguous
memory, allocates a value of this type, and then fetches the elements
from the original array and places then into the contents buffer of
the new value.
One benefit of using packed slices over unpacked slices is the memory
usage, taking a small slice of N elements from a large array will
require (in GDB) N * ELEMENT_SIZE bytes of memory, while an unpacked
array will also include all of the "padding" between the
non-contiguous elements. There are new tests added that highlight
this difference.
There is also a new debugging flag added with this commit that
introduces these commands:
(gdb) set debug fortran-array-slicing on|off
(gdb) show debug fortran-array-slicing
This prints information about how the array slices are being built.
As both the repacking, and the array printing requires GDB to walk
through a multi-dimensional Fortran array visiting each element, this
commit adds the file f-array-walk.h, which introduces some
infrastructure to support this process. This means the array printing
code in f-valprint.c is significantly reduced.
The only slight issue with this commit is the "rather big hack" that I
mentioned above. This hack allows us to handle one specific case,
array slices with negative strides. This is something that I don't
believe the current GDB value contents model will allow us to
correctly handle, and rather than rewrite the value contents code
right now, I'm hoping to slip this hack in as a work around.
The problem is that, as I see it, the current value contents model
assumes that an object base address will be the lowest address within
that object, and that the contents of the object start at this base
address and occupy the TYPE_LENGTH bytes after that.
( We do have the embedded_offset, which is used for C++ sub-classes,
such that an object can start at some offset from the content buffer,
however, the assumption that the object then occupies the next
TYPE_LENGTH bytes is still true within GDB. )
The problem is that Fortran arrays with a negative stride don't follow
this pattern. In this case the base address of the object points to
the element with the highest address, the contents of the array then
start at some offset _before_ the base address, and proceed for one
element _past_ the base address.
As the stride for such an array would be negative then, in theory the
TYPE_LENGTH for this type would also be negative. However, in many
places a value in GDB will degrade to a pointer + length, and the
length almost always comes from the TYPE_LENGTH.
It is my belief that in order to correctly model this case the value
content handling of GDB will need to be reworked to split apart the
value's content buffer (which is a block of memory with a length), and
the object's in memory base address and length, which could be
negative.
Things are further complicated because arrays with negative strides
like this are always dynamic types. When a value has a dynamic type
and its base address needs resolving we actually store the address of
the object within the resolved dynamic type, not within the value
object itself.
In short I don't currently see an easy path to cleanly support this
situation within GDB. And so I believe that leaves two options,
either add a work around, or catch cases where the user tries to make
use of a negative stride, or access an array with a negative stride,
and throw an error.
This patch currently goes with adding a work around, which is that
when we resolve a dynamic Fortran array type, if the stride is
negative, then we adjust the base address to point to the lowest
address required by the array. The printing and slicing code is aware
of this adjustment and will correctly slice and print Fortran arrays.
Where this hack will show through to the user is if they ask for the
address of an array in their program with a negative array stride, the
address they get from GDB will not match the address that would be
computed within the Fortran program.
gdb/ChangeLog:
* Makefile.in (HFILES_NO_SRCDIR): Add f-array-walker.h.
* NEWS: Mention new options.
* f-array-walker.h: New file.
* f-lang.c: Include 'gdbcmd.h' and 'f-array-walker.h'.
(repack_array_slices): New static global.
(show_repack_array_slices): New function.
(fortran_array_slicing_debug): New static global.
(show_fortran_array_slicing_debug): New function.
(value_f90_subarray): Delete.
(skip_undetermined_arglist): Delete.
(class fortran_array_repacker_base_impl): New class.
(class fortran_lazy_array_repacker_impl): New class.
(class fortran_array_repacker_impl): New class.
(fortran_value_subarray): Complete rewrite.
(set_fortran_list): New static global.
(show_fortran_list): Likewise.
(_initialize_f_language): Register new commands.
(fortran_adjust_dynamic_array_base_address_hack): New function.
* f-lang.h (fortran_adjust_dynamic_array_base_address_hack):
Declare.
* f-valprint.c: Include 'f-array-walker.h'.
(class fortran_array_printer_impl): New class.
(f77_print_array_1): Delete.
(f77_print_array): Delete.
(fortran_print_array): New.
(f_value_print_inner): Update to call fortran_print_array.
* gdbtypes.c: Include 'f-lang.h'.
(resolve_dynamic_type_internal): Call
fortran_adjust_dynamic_array_base_address_hack.
gdb/testsuite/ChangeLog:
* gdb.fortran/array-slices-bad.exp: New file.
* gdb.fortran/array-slices-bad.f90: New file.
* gdb.fortran/array-slices-sub-slices.exp: New file.
* gdb.fortran/array-slices-sub-slices.f90: New file.
* gdb.fortran/array-slices.exp: Rewrite tests.
* gdb.fortran/array-slices.f90: Rewrite tests.
* gdb.fortran/vla-sizeof.exp: Correct expected results.
gdb/doc/ChangeLog:
* gdb.texinfo (Debugging Output): Document 'set/show debug
fortran-array-slicing'.
(Special Fortran Commands): Document 'set/show fortran
repack-array-slices'.
With current trunk I run into:
...
src/gdb/gdbtypes.c: In function 'bool update_static_array_size(type*)':
src/gdb/gdbtypes.c:1250:64: error: comparison of constant '0' with boolean \
expression is always true [-Werror=bool-compare]
&& get_array_bounds (element_type, &low_bound, &high_bound) >= 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
...
Fix this by dropping the compare.
gdb/ChangeLog:
2020-11-18 Tom de Vries <tdevries@suse.de>
* gdbtypes.c (update_static_array_size): Fix -Werror=bool-compare
warning.
Obvious change from int to bool. I took the opportunity to move the doc
to the header file.
gdb/ChangeLog:
* gdbtypes.h (get_array_bounds): Return bool, adjust some
callers. Move doc here.
* gdbtypes.c (get_array_bounds): Return bool
Change-Id: I8ed20298cb0927963c1f09b345966533d5ed06e2
This commit introduces a new kind of type, meant to describe
fixed-point types, using a new code added specifically for
this purpose (TYPE_CODE_FIXED_POINT).
It then adds handling of fixed-point base types in the DWARF reader.
And finally, as a first step, this commit adds support for printing
the value of fixed-point type objects.
Note that this commit has a known issue: Trying to print the value
of a fixed-point object with a format letter (e.g. "print /x NAME")
causes the wrong value to be printed because the scaling factor
is not applied. Since the fix for this issue is isolated, and
this is not a regression, the fix will be made in a pach of its own.
This is meant to simplify review and archeology.
Also, other functionalities related to fixed-point type handling
(ptype, arithmetics, etc), will be added piecemeal as well, for
the same reasons (faciliate reviews and archeology). Related to this,
the testcase gdb.ada/fixed_cmp.exp is adjusted to compile the test
program with -fgnat-encodings=all, so as to force the use of GNAT
encodings, rather than rely on the compiler's default to use them.
The intent is to enhance this testcase to also test the pure DWARF
approach using -fgnat-encodings=minimal as soon as the corresponding
suport gets added in. Thus, the modification to the testcase is made
in a way that it prepares this testcase to be tested in both modes.
gdb/ChangeLog:
* ada-valprint.c (ada_value_print_1): Add fixed-point type handling.
* dwarf2/read.c (get_dwarf2_rational_constant)
(get_dwarf2_unsigned_rational_constant, finish_fixed_point_type)
(has_zero_over_zero_small_attribute): New functions.
read_base_type, set_die_type): Add fixed-point type handling.
* gdb-gdb.py.in: Add fixed-point type handling.
* gdbtypes.c: #include "gmp-utils.h".
(create_range_type, set_type_code): Add fixed-point type handling.
(init_fixed_point_type): New function.
(is_integral_type, is_scalar_type): Add fixed-point type handling.
(print_fixed_point_type_info): New function.
(recursive_dump_type, copy_type_recursive): Add fixed-point type
handling.
(fixed_point_type_storage): New typedef.
(fixed_point_objfile_key): New static global.
(allocate_fixed_point_type_info, is_fixed_point_type): New functions.
(fixed_point_type_base_type, fixed_point_scaling_factor): New
functions.
* gdbtypes.h: #include "gmp-utils.h".
(enum type_code) <TYPE_SPECIFIC_FIXED_POINT>: New enum.
(union type_specific) <fixed_point_info>: New field.
(struct fixed_point_type_info): New struct.
(INIT_FIXED_POINT_SPECIFIC, TYPE_FIXED_POINT_INFO): New macros.
(init_fixed_point_type, is_fixed_point_type)
(fixed_point_type_base_type, fixed_point_scaling_factor)
(allocate_fixed_point_type_info): Add declarations.
* valprint.c (generic_val_print_fixed_point): New function.
(generic_value_print): Add fixed-point type handling.
* value.c (value_as_address, unpack_long): Add fixed-point type
handling.
gdb/testsuite/ChangeLog:
* gdb.ada/fixed_cmp.exp: Force compilation to use -fgnat-encodings=all.
* gdb.ada/fixed_points.exp: Add fixed-point variables printing tests.
* gdb.ada/fixed_points/pck.ads, gdb.ada/fixed_points/pck.adb:
New files.
* gdb.ada/fixed_points/fixed_points.adb: Add use of package Pck.
* gdb.dwarf2/dw2-fixed-point.c, gdb.dwarf2/dw2-fixed-point.exp:
New files.
With -fgnat-encodings=minimal, the enum_idx_packed.exp test will fail.
In this test case, we have an array (with dynamic length) of arrays,
and the inner array has a bit stride. In this situation, the outer
array's bit stride must be updated to account for the entire bit
length of the inner array.
Here, again, some tests must be kfail'd when an older version of GNAT
is in use.
gdb/ChangeLog
2020-11-04 Tom Tromey <tromey@adacore.com>
* gdbtypes.c (update_static_array_size): Handle bit stride.
gdb/testsuite/ChangeLog
2020-11-04 Tom Tromey <tromey@adacore.com>
* gdb.ada/enum_idx_packed.exp: Test two forms of -fgnat-encodings.
A recent commit changed gdb to inherit the signed-ness of a range type
from its underlying type:
commit cfabbd351a174406fd5aa063303f5c8bf9266bbc
Author: Tom Tromey <tom@tromey.com>
Date: Sat Oct 17 11:41:59 2020 -0600
Make range types inherit signed-ness from base type
This passed testing -- but unfortunately, additional testing at
AdaCore showed that this change was incorrect. GNAT, at least, can
emit an unsigned range type whose underlying type is signed.
This patch reverts the code change from the above. I chose not to
reintroduce the FIXME comments, because now we know that they are
incorrect. Instead, this patch also adds a comment to
create_range_type.
A new test case is included as well.
2020-10-26 Tom Tromey <tromey@adacore.com>
* gdbtypes.c (create_range_type): Revert previous patch. Add
comment.
gdb/testsuite/ChangeLog
2020-10-26 Tom Tromey <tromey@adacore.com>
* gdb.ada/unsigned_range/foo.adb: New file.
* gdb.ada/unsigned_range/pack.adb: New file.
* gdb.ada/unsigned_range/pack.ads: New file.
* gdb.ada/unsigned_range.exp: New file.
This causes gdb to crash in strlen.
Happens if init_complex_type is called for a type created by
dbx_init_float_type in stabsread.c.
gdb/ChangeLog:
2020-10-22 Hannes Domani <ssbssa@yahoo.de>
* gdbtypes.c (init_complex_type): Check target type name.
I ran across this comment in valprint.c:
/* FIXME: create_static_range_type does not set the unsigned bit in a
range type (I think it probably should copy it from the target
type), so we won't print values which are too large to
fit in a signed integer correctly. */
It seems to me that a range type ought to inherit its signed-ness from
the underlying type, so this patch implements this change, and removes
the comment. (It was also copied into m2-valprint.c.)
I also remove the comment about handling ranges of enums, because I
think that comment is incorrect.
gdb/ChangeLog
2020-10-17 Tom Tromey <tom@tromey.com>
* valprint.c (generic_value_print): Remove comment.
* m2-valprint.c (m2_value_print_inner): Remove comment.
* gdbtypes.c (create_range_type): Set TYPE_UNSIGNED from base
type.
PR symtab/25470 points out that the Zig programming language allows
integers of various bit sizes (including zero), not just sizes that
are a multiple of 8.
This is supported in DWARF by applying both a byte size and a
DW_AT_bit_size.
This patch adds support for this feature to integer and boolean types.
Other base types are not handled -- for floating-point types, this
didn't seem to make sense, and for character types I didn't see much
need. (These can be added later if desired.)
I've also added support for DW_AT_data_bit_offset at the same time. I
don't know whether the Zig compiler requires this, but it was
described in the same section in the DWARF standard and was easy to
add.
A new test case is supplied, using the DWARF assembler.
gdb/ChangeLog
2020-09-23 Tom Tromey <tom@tromey.com>
PR symtab/25470:
* value.c (unpack_long, pack_long, pack_unsigned_long): Handle bit
offset and bit size.
* printcmd.c (print_scalar_formatted): Handle zero-length
integer.
(print_scalar_formatted): Use bit_size_differs_p.
* gdbtypes.h (enum type_specific_kind) <TYPE_SPECIFIC_INT>: New
constant.
(union type_specific): <int_stuff>: New member.
(struct type) <bit_size_differs_p, bit_size, bit_offset>: New
methods.
* gdbtypes.c (init_integer_type, init_boolean_type): Initialize
TYPE_SPECIFIC_FIELD.
(recursive_dump_type, copy_type_recursive): Update.
* dwarf2/read.c (read_base_type): Handle DW_AT_bit_size and
DW_AT_data_bit_offset.
gdb/testsuite/ChangeLog
2020-09-23 Tom Tromey <tom@tromey.com>
* gdb.dwarf2/intbits.exp: New file.
* gdb.dwarf2/intbits.c: New file.
Remove it, use the `type::instance_flags` method everywhere.
gdb/ChangeLog:
* gdbtypes.h (TYPE_INSTANCE_FLAGS): Remove, replace all uses
with `type::instance_flags`.
Change-Id: I3653108b712e6186529cb0102e2b70247bbcabbe
These methods now take/return a type_instance_flags instead of a raw
integer, so rename them accordingly.
gdb/ChangeLog:
* c-typeprint.c (c_type_print_modifier): Adjust to rename.
* gdbtypes.c (address_space_name_to_int): Rename to ...
(address_space_name_to_type_instance_flags): ... this.
(address_space_int_to_name): Rename to ...
(address_space_type_instance_flags_to_name): ... this.
* gdbtypes.h (address_space_name_to_int): Rename to ...
(address_space_name_to_type_instance_flags): ... this.
(address_space_int_to_name): Rename to ...
(address_space_type_instance_flags_to_name): ... this.
* type-stack.c (type_stack::insert): Adjust to rename.
* type-stack.h (type_stack::insert): Likewise.
A later patch in this series will rewrite enum_flags fixing some API
holes. That would cause build failures around code using
type_instance_flags. Or rather, that should be using it, but wasn't.
This patch fixes it by using type_instance_flags throughout instead of
plain integers.
Note that we can't make the seemingly obvious change to struct
type::instance_flags:
- unsigned instance_flags : 9;
+ ENUM_BITFIELD (type_instance_flag_value) instance_flags : 9;
Because G++ complains then that 9 bits isn't sufficient for holding
all values of type_instance_flag_value.
So the patch adds an type::instance_flags() method, which takes care
of casting appropriately, and adds a separate type::set_instance_flags
method, following the pattern of the ongoing TYPE_XXX macro
elimination. This converts uses of TYPE_INSTANCE_FLAGS to
type::instance_flags() in the places where the code was already being
touched, but there are still many references to the
TYPE_INSTANCE_FLAGS macro left behind. Those could/should be fully
replaced at some point.
gdb/ChangeLog:
* avr-tdep.c (avr_address_class_type_flags): Return
type_instance_flags.
(avr_address_class_type_flags_to_name): Take a
type_instance_flags.
(avr_address_class_name_to_type_flags): Return bool and take a
type_instance_flags.
* d-lang.c (build_d_types): Use type::set_instance_flags.
* ft32-tdep.c (ft32_address_class_type_flags): Return
type_instance_flags.
(ft32_address_class_type_flags_to_name): Take a
type_instance_flags.
(ft32_address_class_name_to_type_flags): Return bool and take a
type_instance_flags.
(ft32_gdbarch_init): Use type::set_instance_flags.
* eval.c (fake_method::fake_method): Use type::set_instance_flags.
* gdbarch.h, gdbarch.c: Regenerate.
* gdbarch.sh (address_class_type_flags): Use type_instance_flags.
(address_class_name_to_type_flags): Use type_instance_flags and
bool.
* gdbtypes.c (address_space_name_to_int)
(address_space_int_to_name, make_qualified_type): Use
type_instance_flags.
(make_qualified_type): Use type_instance_flags and
type::set_instance_flags.
(make_type_with_address_space, make_cv_type, make_vector_type)
(check_typedef): Use type_instance_flags.
(recursive_dump_type): Cast type_instance_flags to unsigned for
printing.
(copy_type_recursive): Use type::set_instance_flags.
(gdbtypes_post_init): Use type::set_instance_flags.
* gdbtypes.h (struct type) <instance_flags>: Rename to ...
<m_instance_flags>: ... this.
<instance_flags, set_instance_flags>: New methods.
(TYPE_INSTANCE_FLAGS): Use the instance_flags method.
(SET_TYPE_INSTANCE_FLAGS): New.
(address_space_name_to_int, address_space_int_to_name)
(make_type_with_address_space): Pass flags using
type_instance_flags instead of int.
* stabsread.c (cleanup_undefined_types_noname): Use
type::set_instance_flags.
* s390-tdep.c (s390_address_class_type_flags): Return
type_instance_flags.
(s390_address_class_type_flags_to_name): Take a
type_instance_flags.
(s390_address_class_name_to_type_flags): Return bool and take a
type_instance_flags.
* type-stack.c (type_stack::follow_types): Use
type_instance_flags.
* dwarf2/read.c (read_tag_pointer_type): Use type_instance_flags.
The two function pointers optionally passed to gdb::bcache are very good
candidates to be turned into virtual methods, this patch does that in
the most straightforward / unsurprising way.
gdb/ChangeLog:
* bcache.h (struct bcache) <bcache>: Remove constructor.
<m_hash_function, m_compare_function>: Remove.
<~bcache>: Make virtual.
<compare>: Remove static method, introduce virtual method.
<default_hash>: Remove.
<hash>: New virtual method.
* bcache.c (bcache::expand_hash_table): Update.
(bcache::insert): Update.
(bcache::hash): New.
(bcache::compare): Update comment and parameter names.
* gdbtypes.c (types_deeply_equal): Update.
* psymtab.h (struct psymbol_bcache): New struct.
(class psymtab_storage) <psymtab_storage>: Make default.
<psymbol_cache>: Change type to psymbol_bcache.
* psymtab.c (psymtab_storage::psymtab_storage): Remove.
(psymbol_hash): Change to...
(psymbol_bcache::hash): ... this.
(psymbol_compare): Change to...
(psymbol_bcache::compare): ... this.
Change-Id: I41d578e61de8ac1163461a28fbd220d1f855e372
Add the `endianity_is_not_default` and `set_endianity_is_not_default`
methods on `struct type`, in order to remove the
`TYPE_ENDIANITY_NOT_DEFAULT` macro. In this patch, the macro is changed
to use the getter, so all the call sites of the macro that are used as a
setter are changed to use the setter method directly. The next patch
will remove the macro completely.
gdb/ChangeLog:
* gdbtypes.h (struct type) <endianity_is_not_default,
set_endianity_is_not_default>: New methods.
(TYPE_ENDIANITY_NOT_DEFAULT): Use
type::endianity_is_not_default, change all write call sites to
use type::set_endianity_is_not_default.
Change-Id: I67acd68fcdae424d7e4a601afda78612ad5d92db
Add the `is_gnu_ifunc` and `set_is_gnu_ifunc` methods on `struct type`, in
order to remove the `TYPE_GNU_IFUNC` macro. In this patch, the macro is
changed to use the getter, so all the call sites of the macro that are
used as a setter are changed to use the setter method directly. The
next patch will remove the macro completely.
gdb/ChangeLog:
* gdbtypes.h (struct type) <is_gnu_ifunc, set_is_gnu_ifunc>: New methods.
(TYPE_GNU_IFUNC): Use type::is_gnu_ifunc, change all write call sites to
use type::set_is_gnu_ifunc.
Change-Id: Ic23ba8c5b8e589d9fc368385111aa16a94e014e2
Add the `is_vector` and `set_is_vector` methods on `struct type`, in
order to remove the `TYPE_VECTOR` macro. In this patch, the macro is
changed to use the getter, so all the call sites of the macro that are
used as a setter are changed to use the setter method directly. The
next patch will remove the macro completely.
gdb/ChangeLog:
* gdbtypes.h (struct type) <is_vector, set_is_vector>: New methods.
(TYPE_VECTOR): Use type::is_vector, change all write call sites to
use type::set_is_vector.
Change-Id: I415e8d169f058662e0750329bfa4017bea3ca0cb