diff options
author | Joel Brobecker <brobecker@gnat.com> | 2009-03-12 23:41:16 +0000 |
---|---|---|
committer | Joel Brobecker <brobecker@gnat.com> | 2009-03-12 23:41:16 +0000 |
commit | 0056e4d5746a88326596e433a09c13f14db3381b (patch) | |
tree | 5b334b0a627aed1b673327c60dbd1fad43268f8b /gdb/ada-lang.c | |
parent | 8a38181c39557b71cb2b0cc0b3ea7e965cb806ae (diff) | |
download | gdb-0056e4d5746a88326596e433a09c13f14db3381b.zip gdb-0056e4d5746a88326596e433a09c13f14db3381b.tar.gz gdb-0056e4d5746a88326596e433a09c13f14db3381b.tar.bz2 |
Fix crash printing packed record with packed array.
* ada-lang.c (ada_modulus_from_name): New function.
(ada_modulus): In the case where the type length is bigger than
the size of the type used to hold the bounds, try determining
the modulus from the type name.
(ada_value_primitive_packed_val): Fix bug in the computation of
ntarg causing an out-of-buffer invalid access.
Diffstat (limited to 'gdb/ada-lang.c')
-rw-r--r-- | gdb/ada-lang.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 12ee5cf..6988594 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -2015,6 +2015,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, /* ... And are placed at the beginning (most-significant) bytes of the target. */ targ = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT - 1; + ntarg = targ + 1; break; default: accumSize = 0; @@ -9597,11 +9598,55 @@ ada_is_modular_type (struct type *type) && TYPE_UNSIGNED (subranged_type)); } +/* Try to determine the lower and upper bounds of the given modular type + using the type name only. Return non-zero and set L and U as the lower + and upper bounds (respectively) if successful. */ + +int +ada_modulus_from_name (struct type *type, ULONGEST *modulus) +{ + char *name = ada_type_name (type); + char *suffix; + int k; + LONGEST U; + + if (name == NULL) + return 0; + + /* Discrete type bounds are encoded using an __XD suffix. In our case, + we are looking for static bounds, which means an __XDLU suffix. + Moreover, we know that the lower bound of modular types is always + zero, so the actual suffix should start with "__XDLU_0__", and + then be followed by the upper bound value. */ + suffix = strstr (name, "__XDLU_0__"); + if (suffix == NULL) + return 0; + k = 10; + if (!ada_scan_number (suffix, k, &U, NULL)) + return 0; + + *modulus = (ULONGEST) U + 1; + return 1; +} + /* Assuming ada_is_modular_type (TYPE), the modulus of TYPE. */ ULONGEST -ada_modulus (struct type * type) +ada_modulus (struct type *type) { + ULONGEST modulus; + + /* Normally, the modulus of a modular type is equal to the value of + its upper bound + 1. However, the upper bound is currently stored + as an int, which is not always big enough to hold the actual bound + value. To workaround this, try to take advantage of the encoding + that GNAT uses with with discrete types. To avoid some unnecessary + parsing, we do this only when the size of TYPE is greater than + the size of the field holding the bound. */ + if (TYPE_LENGTH (type) > sizeof (TYPE_HIGH_BOUND (type)) + && ada_modulus_from_name (type, &modulus)) + return modulus; + return (ULONGEST) (unsigned int) TYPE_HIGH_BOUND (type) + 1; } |