blob: 0f7100dfc949df9e90913858ffa8d084b3eed1bc [file] [log] [blame]
/* Ada language support routines for GDB, the GNU debugger.
Copyright (C) 1992-2024 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <ctype.h>
#include "event-top.h"
#include "exceptions.h"
#include "extract-store-integer.h"
#include "gdbsupport/gdb_regex.h"
#include "frame.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "cli/cli-cmds.h"
#include "expression.h"
#include "parser-defs.h"
#include "language.h"
#include "varobj.h"
#include "inferior.h"
#include "symfile.h"
#include "objfiles.h"
#include "breakpoint.h"
#include "gdbcore.h"
#include "hashtab.h"
#include "gdbsupport/gdb_obstack.h"
#include "ada-lang.h"
#include "completer.h"
#include "ui-out.h"
#include "block.h"
#include "infcall.h"
#include "annotate.h"
#include "valprint.h"
#include "source.h"
#include "observable.h"
#include "stack.h"
#include "typeprint.h"
#include "namespace.h"
#include "cli/cli-style.h"
#include "cli/cli-decode.h"
#include "value.h"
#include "mi/mi-common.h"
#include "arch-utils.h"
#include "cli/cli-utils.h"
#include "gdbsupport/function-view.h"
#include "gdbsupport/byte-vector.h"
#include "gdbsupport/selftest.h"
#include <algorithm>
#include "ada-exp.h"
#include "charset.h"
#include "ax-gdb.h"
static struct type *desc_base_type (struct type *);
static struct type *desc_bounds_type (struct type *);
static struct value *desc_bounds (struct value *);
static int fat_pntr_bounds_bitpos (struct type *);
static int fat_pntr_bounds_bitsize (struct type *);
static struct type *desc_data_target_type (struct type *);
static struct value *desc_data (struct value *);
static int fat_pntr_data_bitpos (struct type *);
static int fat_pntr_data_bitsize (struct type *);
static struct value *desc_one_bound (struct value *, int, int);
static int desc_bound_bitpos (struct type *, int, int);
static int desc_bound_bitsize (struct type *, int, int);
static struct type *desc_index_type (struct type *, int);
static int desc_arity (struct type *);
static int ada_args_match (struct symbol *, struct value **, int);
static struct value *make_array_descriptor (struct type *, struct value *);
static void ada_add_block_symbols (std::vector<struct block_symbol> &,
const struct block *,
const lookup_name_info &lookup_name,
domain_search_flags, struct objfile *);
static void ada_add_all_symbols (std::vector<struct block_symbol> &,
const struct block *,
const lookup_name_info &lookup_name,
domain_search_flags, int, int *);
static int is_nonfunction (const std::vector<struct block_symbol> &);
static void add_defn_to_vec (std::vector<struct block_symbol> &,
struct symbol *,
const struct block *);
static int possible_user_operator_p (enum exp_opcode, struct value **);
static const char *ada_decoded_op_name (enum exp_opcode);
static int numeric_type_p (struct type *);
static int integer_type_p (struct type *);
static int scalar_type_p (struct type *);
static int discrete_type_p (struct type *);
static struct type *ada_lookup_struct_elt_type (struct type *, const char *,
int, int);
static struct type *ada_find_parallel_type_with_name (struct type *,
const char *);
static int is_dynamic_field (struct type *, int);
static struct type *to_fixed_variant_branch_type (struct type *,
const gdb_byte *,
CORE_ADDR, struct value *);
static struct type *to_fixed_array_type (struct type *, struct value *, int);
static struct type *to_fixed_range_type (struct type *, struct value *);
static struct type *to_static_fixed_type (struct type *);
static struct type *static_unwrap_type (struct type *type);
static struct value *unwrap_value (struct value *);
static struct type *constrained_packed_array_type (struct type *, long *);
static struct type *decode_constrained_packed_array_type (struct type *);
static long decode_packed_array_bitsize (struct type *);
static struct value *decode_constrained_packed_array (struct value *);
static int ada_is_unconstrained_packed_array_type (struct type *);
static struct value *value_subscript_packed (struct value *, int,
struct value **);
static struct value *coerce_unspec_val_to_type (struct value *,
struct type *);
static int lesseq_defined_than (struct symbol *, struct symbol *);
static int equiv_types (struct type *, struct type *);
static int is_name_suffix (const char *);
static int advance_wild_match (const char **, const char *, char);
static bool wild_match (const char *name, const char *patn);
static struct value *ada_coerce_ref (struct value *);
static LONGEST pos_atr (struct value *);
static struct value *val_atr (struct type *, LONGEST);
static struct value *ada_search_struct_field (const char *, struct value *, int,
struct type *);
static int find_struct_field (const char *, struct type *, int,
struct type **, int *, int *, int *, int *);
static int ada_resolve_function (std::vector<struct block_symbol> &,
struct value **, int, const char *,
struct type *, bool);
static int ada_is_direct_array_type (struct type *);
static struct value *ada_index_struct_field (int, struct value *, int,
struct type *);
static struct type *ada_find_any_type (const char *name);
static symbol_name_matcher_ftype *ada_get_symbol_name_matcher
(const lookup_name_info &lookup_name);
static int symbols_are_identical_enums
(const std::vector<struct block_symbol> &syms);
static bool ada_identical_enum_types_p (struct type *type1,
struct type *type2);
/* The character set used for source files. */
static const char *ada_source_charset;
/* The string "UTF-8". This is here so we can check for the UTF-8
charset using == rather than strcmp. */
static const char ada_utf8[] = "UTF-8";
/* Each entry in the UTF-32 case-folding table is of this form. */
struct utf8_entry
{
/* The start and end, inclusive, of this range of codepoints. */
uint32_t start, end;
/* The delta to apply to get the upper-case form. 0 if this is
already upper-case. */
int upper_delta;
/* The delta to apply to get the lower-case form. 0 if this is
already lower-case. */
int lower_delta;
bool operator< (uint32_t val) const
{
return end < val;
}
};
static const utf8_entry ada_case_fold[] =
{
#include "ada-casefold.h"
};
static const char ada_completer_word_break_characters[] =
#ifdef VMS
" \t\n!@#%^&*()+=|~`}{[]\";:?/,-";
#else
" \t\n!@#$%^&*()+=|~`}{[]\";:?/,-";
#endif
/* The name of the symbol to use to get the name of the main subprogram. */
static const char ADA_MAIN_PROGRAM_SYMBOL_NAME[]
= "__gnat_ada_main_program_name";
/* Limit on the number of warnings to raise per expression evaluation. */
static int warning_limit = 2;
/* Number of warning messages issued; reset to 0 by cleanups after
expression evaluation. */
static int warnings_issued = 0;
static const char * const known_runtime_file_name_patterns[] = {
ADA_KNOWN_RUNTIME_FILE_NAME_PATTERNS NULL
};
static const char * const known_auxiliary_function_name_patterns[] = {
ADA_KNOWN_AUXILIARY_FUNCTION_NAME_PATTERNS NULL
};
/* Maintenance-related settings for this module. */
static struct cmd_list_element *maint_set_ada_cmdlist;
static struct cmd_list_element *maint_show_ada_cmdlist;
/* The "maintenance ada set/show ignore-descriptive-type" value. */
static bool ada_ignore_descriptive_types_p = false;
/* Inferior-specific data. */
/* Per-inferior data for this module. */
struct ada_inferior_data
{
/* The ada__tags__type_specific_data type, which is used when decoding
tagged types. With older versions of GNAT, this type was directly
accessible through a component ("tsd") in the object tag. But this
is no longer the case, so we cache it for each inferior. */
struct type *tsd_type = nullptr;
/* The exception_support_info data. This data is used to determine
how to implement support for Ada exception catchpoints in a given
inferior. */
const struct exception_support_info *exception_info = nullptr;
};
/* Our key to this module's inferior data. */
static const registry<inferior>::key<ada_inferior_data> ada_inferior_data;
/* Return our inferior data for the given inferior (INF).
This function always returns a valid pointer to an allocated
ada_inferior_data structure. If INF's inferior data has not
been previously set, this functions creates a new one with all
fields set to zero, sets INF's inferior to it, and then returns
a pointer to that newly allocated ada_inferior_data. */
static struct ada_inferior_data *
get_ada_inferior_data (struct inferior *inf)
{
struct ada_inferior_data *data;
data = ada_inferior_data.get (inf);
if (data == NULL)
data = ada_inferior_data.emplace (inf);
return data;
}
/* Perform all necessary cleanups regarding our module's inferior data
that is required after the inferior INF just exited. */
static void
ada_inferior_exit (struct inferior *inf)
{
ada_inferior_data.clear (inf);
}
/* program-space-specific data. */
/* The result of a symbol lookup to be stored in our symbol cache. */
struct cache_entry
{
/* The name used to perform the lookup. */
std::string name;
/* The namespace used during the lookup. */
domain_search_flags domain = 0;
/* The symbol returned by the lookup, or NULL if no matching symbol
was found. */
struct symbol *sym = nullptr;
/* The block where the symbol was found, or NULL if no matching
symbol was found. */
const struct block *block = nullptr;
};
/* The symbol cache uses this type when searching. */
struct cache_entry_search
{
const char *name;
domain_search_flags domain;
hashval_t hash () const
{
/* This must agree with hash_cache_entry, below. */
return htab_hash_string (name);
}
};
/* Hash function for cache_entry. */
static hashval_t
hash_cache_entry (const void *v)
{
const cache_entry *entry = (const cache_entry *) v;
return htab_hash_string (entry->name.c_str ());
}
/* Equality function for cache_entry. */
static int
eq_cache_entry (const void *a, const void *b)
{
const cache_entry *entrya = (const cache_entry *) a;
const cache_entry_search *entryb = (const cache_entry_search *) b;
return entrya->domain == entryb->domain && entrya->name == entryb->name;
}
/* Key to our per-program-space data. */
static const registry<program_space>::key<htab, htab_deleter>
ada_pspace_data_handle;
/* Return this module's data for the given program space (PSPACE).
If not is found, add a zero'ed one now.
This function always returns a valid object. */
static htab_t
get_ada_pspace_data (struct program_space *pspace)
{
htab_t data = ada_pspace_data_handle.get (pspace);
if (data == nullptr)
{
data = htab_create_alloc (10, hash_cache_entry, eq_cache_entry,
htab_delete_entry<cache_entry>,
xcalloc, xfree);
ada_pspace_data_handle.set (pspace, data);
}
return data;
}
/* Utilities */
/* If TYPE is a TYPE_CODE_TYPEDEF type, return the target type after
all typedef layers have been peeled. Otherwise, return TYPE.
Normally, we really expect a typedef type to only have 1 typedef layer.
In other words, we really expect the target type of a typedef type to be
a non-typedef type. This is particularly true for Ada units, because
the language does not have a typedef vs not-typedef distinction.
In that respect, the Ada compiler has been trying to eliminate as many
typedef definitions in the debugging information, since they generally
do not bring any extra information (we still use typedef under certain
circumstances related mostly to the GNAT encoding).
Unfortunately, we have seen situations where the debugging information
generated by the compiler leads to such multiple typedef layers. For
instance, consider the following example with stabs:
.stabs "pck__float_array___XUP:Tt(0,46)=s16P_ARRAY:(0,47)=[...]"[...]
.stabs "pck__float_array___XUP:t(0,36)=(0,46)",128,0,6,0
This is an error in the debugging information which causes type
pck__float_array___XUP to be defined twice, and the second time,
it is defined as a typedef of a typedef.
This is on the fringe of legality as far as debugging information is
concerned, and certainly unexpected. But it is easy to handle these
situations correctly, so we can afford to be lenient in this case. */
static struct type *
ada_typedef_target_type (struct type *type)
{
while (type->code () == TYPE_CODE_TYPEDEF)
type = type->target_type ();
return type;
}
/* Given DECODED_NAME a string holding a symbol name in its
decoded form (ie using the Ada dotted notation), returns
its unqualified name. */
static const char *
ada_unqualified_name (const char *decoded_name)
{
const char *result;
/* If the decoded name starts with '<', it means that the encoded
name does not follow standard naming conventions, and thus that
it is not your typical Ada symbol name. Trying to unqualify it
is therefore pointless and possibly erroneous. */
if (decoded_name[0] == '<')
return decoded_name;
result = strrchr (decoded_name, '.');
if (result != NULL)
result++; /* Skip the dot... */
else
result = decoded_name;
return result;
}
/* Return a string starting with '<', followed by STR, and '>'. */
static std::string
add_angle_brackets (const char *str)
{
return string_printf ("<%s>", str);
}
/* True (non-zero) iff TARGET matches FIELD_NAME up to any trailing
suffix of FIELD_NAME beginning "___". */
static int
field_name_match (const char *field_name, const char *target)
{
int len = strlen (target);
return
(strncmp (field_name, target, len) == 0
&& (field_name[len] == '\0'
|| (startswith (field_name + len, "___")
&& strcmp (field_name + strlen (field_name) - 6,
"___XVN") != 0)));
}
/* Assuming TYPE is a TYPE_CODE_STRUCT or a TYPE_CODE_TYPDEF to
a TYPE_CODE_STRUCT, find the field whose name matches FIELD_NAME,
and return its index. This function also handles fields whose name
have ___ suffixes because the compiler sometimes alters their name
by adding such a suffix to represent fields with certain constraints.
If the field could not be found, return a negative number if
MAYBE_MISSING is set. Otherwise raise an error. */
int
ada_get_field_index (const struct type *type, const char *field_name,
int maybe_missing)
{
int fieldno;
struct type *struct_type = check_typedef ((struct type *) type);
for (fieldno = 0; fieldno < struct_type->num_fields (); fieldno++)
if (field_name_match (struct_type->field (fieldno).name (), field_name))
return fieldno;
if (!maybe_missing)
error (_("Unable to find field %s in struct %s. Aborting"),
field_name, struct_type->name ());
return -1;
}
/* The length of the prefix of NAME prior to any "___" suffix. */
int
ada_name_prefix_len (const char *name)
{
if (name == NULL)
return 0;
else
{
const char *p = strstr (name, "___");
if (p == NULL)
return strlen (name);
else
return p - name;
}
}
/* Return non-zero if SUFFIX is a suffix of STR.
Return zero if STR is null. */
static int
is_suffix (const char *str, const char *suffix)
{
int len1, len2;
if (str == NULL)
return 0;
len1 = strlen (str);
len2 = strlen (suffix);
return (len1 >= len2 && strcmp (str + len1 - len2, suffix) == 0);
}
/* The contents of value VAL, treated as a value of type TYPE. The
result is an lval in memory if VAL is. */
static struct value *
coerce_unspec_val_to_type (struct value *val, struct type *type)
{
type = ada_check_typedef (type);
if (val->type () == type)
return val;
else
{
struct value *result;
if (val->optimized_out ())
result = value::allocate_optimized_out (type);
else if (val->lazy ()
/* Be careful not to make a lazy not_lval value. */
|| (val->lval () != not_lval
&& type->length () > val->type ()->length ()))
result = value::allocate_lazy (type);
else
{
result = value::allocate (type);
val->contents_copy (result, 0, 0, type->length ());
}
result->set_component_location (val);
result->set_bitsize (val->bitsize ());
result->set_bitpos (val->bitpos ());
if (result->lval () == lval_memory)
result->set_address (val->address ());
return result;
}
}
static const gdb_byte *
cond_offset_host (const gdb_byte *valaddr, long offset)
{
if (valaddr == NULL)
return NULL;
else
return valaddr + offset;
}
static CORE_ADDR
cond_offset_target (CORE_ADDR address, long offset)
{
if (address == 0)
return 0;
else
return address + offset;
}
/* Issue a warning (as for the definition of warning in utils.c, but
with exactly one argument rather than ...), unless the limit on the
number of warnings has passed during the evaluation of the current
expression. */
/* FIXME: cagney/2004-10-10: This function is mimicking the behavior
provided by "complaint". */
static void lim_warning (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
static void
lim_warning (const char *format, ...)
{
va_list args;
va_start (args, format);
warnings_issued += 1;
if (warnings_issued <= warning_limit)
vwarning (format, args);
va_end (args);
}
/* Maximum value of a SIZE-byte signed integer type. */
static LONGEST
max_of_size (int size)
{
LONGEST top_bit = (LONGEST) 1 << (size * 8 - 2);
return top_bit | (top_bit - 1);
}
/* Minimum value of a SIZE-byte signed integer type. */
static LONGEST
min_of_size (int size)
{
return -max_of_size (size) - 1;
}
/* Maximum value of a SIZE-byte unsigned integer type. */
static ULONGEST
umax_of_size (int size)
{
ULONGEST top_bit = (ULONGEST) 1 << (size * 8 - 1);
return top_bit | (top_bit - 1);
}
/* Maximum value of integral type T, as a signed quantity. */
static LONGEST
max_of_type (struct type *t)
{
if (t->is_unsigned ())
return (LONGEST) umax_of_size (t->length ());
else
return max_of_size (t->length ());
}
/* Minimum value of integral type T, as a signed quantity. */
static LONGEST
min_of_type (struct type *t)
{
if (t->is_unsigned ())
return 0;
else
return min_of_size (t->length ());
}
/* The largest value in the domain of TYPE, a discrete type, as an integer. */
LONGEST
ada_discrete_type_high_bound (struct type *type)
{
type = resolve_dynamic_type (type, {}, 0);
switch (type->code ())
{
case TYPE_CODE_RANGE:
{
const dynamic_prop &high = type->bounds ()->high;
if (high.is_constant ())
return high.const_val ();
else
{
gdb_assert (!high.is_available ());
/* This happens when trying to evaluate a type's dynamic bound
without a live target. There is nothing relevant for us to
return here, so return 0. */
return 0;
}
}
case TYPE_CODE_ENUM:
return type->field (type->num_fields () - 1).loc_enumval ();
case TYPE_CODE_BOOL:
return 1;
case TYPE_CODE_CHAR:
case TYPE_CODE_INT:
return max_of_type (type);
default:
error (_("Unexpected type in ada_discrete_type_high_bound."));
}
}
/* The smallest value in the domain of TYPE, a discrete type, as an integer. */
LONGEST
ada_discrete_type_low_bound (struct type *type)
{
type = resolve_dynamic_type (type, {}, 0);
switch (type->code ())
{
case TYPE_CODE_RANGE:
{
const dynamic_prop &low = type->bounds ()->low;
if (low.is_constant ())
return low.const_val ();
else
{
gdb_assert (!low.is_available ());
/* This happens when trying to evaluate a type's dynamic bound
without a live target. There is nothing relevant for us to
return here, so return 0. */
return 0;
}
}
case TYPE_CODE_ENUM:
return type->field (0).loc_enumval ();
case TYPE_CODE_BOOL:
return 0;
case TYPE_CODE_CHAR:
case TYPE_CODE_INT:
return min_of_type (type);
default:
error (_("Unexpected type in ada_discrete_type_low_bound."));
}
}
/* The identity on non-range types. For range types, the underlying
non-range scalar type. */
static struct type *
get_base_type (struct type *type)
{
while (type != NULL && type->code () == TYPE_CODE_RANGE)
{
if (type == type->target_type () || type->target_type () == NULL)
return type;
type = type->target_type ();
}
return type;
}
/* Return a decoded version of the given VALUE. This means returning
a value whose type is obtained by applying all the GNAT-specific
encodings, making the resulting type a static but standard description
of the initial type. */
struct value *
ada_get_decoded_value (struct value *value)
{
struct type *type = ada_check_typedef (value->type ());
if (ada_is_array_descriptor_type (type)
|| (ada_is_constrained_packed_array_type (type)
&& type->code () != TYPE_CODE_PTR))
{
if (type->code () == TYPE_CODE_TYPEDEF) /* array access type. */
value = ada_coerce_to_simple_array_ptr (value);
else
value = ada_coerce_to_simple_array (value);
}
else
value = ada_to_fixed_value (value);
return value;
}
/* Same as ada_get_decoded_value, but with the given TYPE.
Because there is no associated actual value for this type,
the resulting type might be a best-effort approximation in
the case of dynamic types. */
struct type *
ada_get_decoded_type (struct type *type)
{
type = to_static_fixed_type (type);
if (ada_is_constrained_packed_array_type (type))
type = ada_coerce_to_simple_array_type (type);
return type;
}
/* Language Selection */
/* If the main procedure is written in Ada, then return its name.
The result is good until the next call. Return NULL if the main
procedure doesn't appear to be in Ada. */
const char *
ada_main_name ()
{
static gdb::unique_xmalloc_ptr<char> main_program_name;
/* For Ada, the name of the main procedure is stored in a specific
string constant, generated by the binder. Look for that symbol,
extract its address, and then read that string. If we didn't find
that string, then most probably the main procedure is not written
in Ada. */
bound_minimal_symbol msym
= lookup_minimal_symbol (current_program_space,
ADA_MAIN_PROGRAM_SYMBOL_NAME);
if (msym.minsym != NULL)
{
CORE_ADDR main_program_name_addr = msym.value_address ();
if (main_program_name_addr == 0)
error (_("Invalid address for Ada main program name."));
/* Force trust_readonly, because we always want to fetch this
string from the executable, not from inferior memory. If the
user changes the exec-file and invokes "start", we want to
pick the "main" from the new executable, not one that may
come from the still-live inferior. */
scoped_restore save_trust_readonly
= make_scoped_restore (&trust_readonly, true);
main_program_name = target_read_string (main_program_name_addr, 1024);
return main_program_name.get ();
}
/* The main procedure doesn't seem to be in Ada. */
return NULL;
}
/* Symbols */
/* Table of Ada operators and their GNAT-encoded names. Last entry is pair
of NULLs. */
const struct ada_opname_map ada_opname_table[] = {
{"Oadd", "\"+\"", BINOP_ADD},
{"Osubtract", "\"-\"", BINOP_SUB},
{"Omultiply", "\"*\"", BINOP_MUL},
{"Odivide", "\"/\"", BINOP_DIV},
{"Omod", "\"mod\"", BINOP_MOD},
{"Orem", "\"rem\"", BINOP_REM},
{"Oexpon", "\"**\"", BINOP_EXP},
{"Olt", "\"<\"", BINOP_LESS},
{"Ole", "\"<=\"", BINOP_LEQ},
{"Ogt", "\">\"", BINOP_GTR},
{"Oge", "\">=\"", BINOP_GEQ},
{"Oeq", "\"=\"", BINOP_EQUAL},
{"One", "\"/=\"", BINOP_NOTEQUAL},
{"Oand", "\"and\"", BINOP_BITWISE_AND},
{"Oor", "\"or\"", BINOP_BITWISE_IOR},
{"Oxor", "\"xor\"", BINOP_BITWISE_XOR},
{"Oconcat", "\"&\"", BINOP_CONCAT},
{"Oabs", "\"abs\"", UNOP_ABS},
{"Onot", "\"not\"", UNOP_LOGICAL_NOT},
{"Oadd", "\"+\"", UNOP_PLUS},
{"Osubtract", "\"-\"", UNOP_NEG},
{NULL, NULL}
};
/* If STR is a decoded version of a compiler-provided suffix (like the
"[cold]" in "symbol[cold]"), return true. Otherwise, return
false. */
static bool
is_compiler_suffix (const char *str)
{
gdb_assert (*str == '[');
++str;
while (*str != '\0' && isalpha (*str))
++str;
/* We accept a missing "]" in order to support completion. */
return *str == '\0' || (str[0] == ']' && str[1] == '\0');
}
/* Append a non-ASCII character to RESULT. */
static void
append_hex_encoded (std::string &result, uint32_t one_char)
{
if (one_char <= 0xff)
{
result.append ("U");
result.append (phex (one_char, 1));
}
else if (one_char <= 0xffff)
{
result.append ("W");
result.append (phex (one_char, 2));
}
else
{
result.append ("WW");
result.append (phex (one_char, 4));
}
}
/* Return a string that is a copy of the data in STORAGE, with
non-ASCII characters replaced by the appropriate hex encoding. A
template is used because, for UTF-8, we actually want to work with
UTF-32 codepoints. */
template<typename T>
std::string
copy_and_hex_encode (struct obstack *storage)
{
const T *chars = (T *) obstack_base (storage);
int num_chars = obstack_object_size (storage) / sizeof (T);
std::string result;
for (int i = 0; i < num_chars; ++i)
{
if (chars[i] <= 0x7f)
{
/* The host character set has to be a superset of ASCII, as
are all the other character sets we can use. */
result.push_back (chars[i]);
}
else
append_hex_encoded (result, chars[i]);
}
return result;
}
/* The "encoded" form of DECODED, according to GNAT conventions. If
THROW_ERRORS, throw an error if invalid operator name is found.
Otherwise, return the empty string in that case. */
static std::string
ada_encode_1 (const char *decoded, bool throw_errors)
{
if (decoded == NULL)
return {};
std::string encoding_buffer;
bool saw_non_ascii = false;
for (const char *p = decoded; *p != '\0'; p += 1)
{
if ((*p & 0x80) != 0)
saw_non_ascii = true;
if (*p == '.')
encoding_buffer.append ("__");
else if (*p == '[' && is_compiler_suffix (p))
{
encoding_buffer = encoding_buffer + "." + (p + 1);
if (encoding_buffer.back () == ']')
encoding_buffer.pop_back ();
break;
}
else if (*p == '"')
{
const struct ada_opname_map *mapping;
for (mapping = ada_opname_table;
mapping->encoded != NULL
&& !startswith (p, mapping->decoded); mapping += 1)
;
if (mapping->encoded == NULL)
{
if (throw_errors)
error (_("invalid Ada operator name: %s"), p);
else
return {};
}
encoding_buffer.append (mapping->encoded);
break;
}
else
encoding_buffer.push_back (*p);
}
/* If a non-ASCII character is seen, we must convert it to the
appropriate hex form. As this is more expensive, we keep track
of whether it is even necessary. */
if (saw_non_ascii)
{
auto_obstack storage;
bool is_utf8 = ada_source_charset == ada_utf8;
try
{
convert_between_encodings
(host_charset (),
is_utf8 ? HOST_UTF32 : ada_source_charset,
(const gdb_byte *) encoding_buffer.c_str (),
encoding_buffer.length (), 1,
&storage, translit_none);
}
catch (const gdb_exception &)
{
static bool warned = false;
/* Converting to UTF-32 shouldn't fail, so if it doesn't, we
might like to know why. */
if (!warned)
{
warned = true;
warning (_("charset conversion failure for '%s'.\n"
"You may have the wrong value for 'set ada source-charset'."),
encoding_buffer.c_str ());
}
/* We don't try to recover from errors. */
return encoding_buffer;
}
if (is_utf8)
return copy_and_hex_encode<uint32_t> (&storage);
return copy_and_hex_encode<gdb_byte> (&storage);
}
return encoding_buffer;
}
/* Find the entry for C in the case-folding table. Return nullptr if
the entry does not cover C. */
static const utf8_entry *
find_case_fold_entry (uint32_t c)
{
auto iter = std::lower_bound (std::begin (ada_case_fold),
std::end (ada_case_fold),
c);
if (iter == std::end (ada_case_fold)
|| c < iter->start
|| c > iter->end)
return nullptr;
return &*iter;
}
/* Return NAME folded to lower case, or, if surrounded by single
quotes, unfolded, but with the quotes stripped away. If
THROW_ON_ERROR is true, encoding failures will throw an exception
rather than emitting a warning. Result good to next call. */
static const char *
ada_fold_name (std::string_view name, bool throw_on_error = false)
{
static std::string fold_storage;
if (!name.empty () && name[0] == '\'')
fold_storage = name.substr (1, name.size () - 2);
else
{
/* Why convert to UTF-32 and implement our own case-folding,
rather than convert to wchar_t and use the platform's
functions? I'm glad you asked.
The main problem is that GNAT implements an unusual rule for
case folding. For ASCII letters, letters in single-byte
encodings (such as ISO-8859-*), and Unicode letters that fit
in a single byte (i.e., code point is <= 0xff), the letter is
folded to lower case. Other Unicode letters are folded to
upper case.
This rule means that the code must be able to examine the
value of the character. And, some hosts do not use Unicode
for wchar_t, so examining the value of such characters is
forbidden. */
auto_obstack storage;
try
{
convert_between_encodings
(host_charset (), HOST_UTF32,
(const gdb_byte *) name.data (),
name.length (), 1,
&storage, translit_none);
}
catch (const gdb_exception &)
{
if (throw_on_error)
throw;
static bool warned = false;
/* Converting to UTF-32 shouldn't fail, so if it doesn't, we
might like to know why. */
if (!warned)
{
warned = true;
warning (_("could not convert '%s' from the host encoding (%s) to UTF-32.\n"
"This normally should not happen, please file a bug report."),
std::string (name).c_str (), host_charset ());
}
/* We don't try to recover from errors; just return the
original string. */
fold_storage = name;
return fold_storage.c_str ();
}
bool is_utf8 = ada_source_charset == ada_utf8;
uint32_t *chars = (uint32_t *) obstack_base (&storage);
int num_chars = obstack_object_size (&storage) / sizeof (uint32_t);
for (int i = 0; i < num_chars; ++i)
{
const struct utf8_entry *entry = find_case_fold_entry (chars[i]);
if (entry != nullptr)
{
uint32_t low = chars[i] + entry->lower_delta;
if (!is_utf8 || low <= 0xff)
chars[i] = low;
else
chars[i] = chars[i] + entry->upper_delta;
}
}
/* Now convert back to ordinary characters. */
auto_obstack reconverted;
try
{
convert_between_encodings (HOST_UTF32,
host_charset (),
(const gdb_byte *) chars,
num_chars * sizeof (uint32_t),
sizeof (uint32_t),
&reconverted,
translit_none);
obstack_1grow (&reconverted, '\0');
fold_storage = std::string ((const char *) obstack_base (&reconverted));
}
catch (const gdb_exception &)
{
if (throw_on_error)
throw;
static bool warned = false;
/* Converting back from UTF-32 shouldn't normally fail, but
there are some host encodings without upper/lower
equivalence. */
if (!warned)
{
warned = true;
warning (_("could not convert the lower-cased variant of '%s'\n"
"from UTF-32 to the host encoding (%s)."),
std::string (name).c_str (), host_charset ());
}
/* We don't try to recover from errors; just return the
original string. */
fold_storage = name;
}
}
return fold_storage.c_str ();
}
/* The "encoded" form of DECODED, according to GNAT conventions. If
FOLD is true (the default), case-fold any ordinary symbol. Symbols
with <...> quoting are not folded in any case. */
std::string
ada_encode (const char *decoded, bool fold)
{
if (fold && decoded[0] != '<')
decoded = ada_fold_name (decoded);
return ada_encode_1 (decoded, true);
}
/* Return nonzero if C is either a digit or a lowercase alphabet character. */
static int
is_lower_alphanum (const char c)
{
return (isdigit (c) || (isalpha (c) && islower (c)));
}
/* ENCODED is the linkage name of a symbol and LEN contains its length.
This function saves in LEN the length of that same symbol name but
without either of these suffixes:
. .{DIGIT}+
. ${DIGIT}+
. ___{DIGIT}+
. __{DIGIT}+.
These are suffixes introduced by the compiler for entities such as
nested subprogram for instance, in order to avoid name clashes.
They do not serve any purpose for the debugger. */
static void
ada_remove_trailing_digits (const char *encoded, int *len)
{
if (*len > 1 && isdigit (encoded[*len - 1]))
{
int i = *len - 2;
while (i > 0 && isdigit (encoded[i]))
i--;
if (i >= 0 && encoded[i] == '.')
*len = i;
else if (i >= 0 && encoded[i] == '$')
*len = i;
else if (i >= 2 && startswith (encoded + i - 2, "___"))
*len = i - 2;
else if (i >= 1 && startswith (encoded + i - 1, "__"))
*len = i - 1;
}
}
/* Remove the suffix introduced by the compiler for protected object
subprograms. */
static void
ada_remove_po_subprogram_suffix (const char *encoded, int *len)
{
/* Remove trailing N. */
/* Protected entry subprograms are broken into two
separate subprograms: The first one is unprotected, and has
a 'N' suffix; the second is the protected version, and has
the 'P' suffix. The second calls the first one after handling
the protection. Since the P subprograms are internally generated,
we leave these names undecoded, giving the user a clue that this
entity is internal. */
if (*len > 1
&& encoded[*len - 1] == 'N'
&& (isdigit (encoded[*len - 2]) || islower (encoded[*len - 2])))
*len = *len - 1;
}
/* If ENCODED ends with a compiler-provided suffix (like ".cold"),
then update *LEN to remove the suffix and return the offset of the
character just past the ".". Otherwise, return -1. */
static int
remove_compiler_suffix (const char *encoded, int *len)
{
int offset = *len - 1;
while (offset > 0 && isalpha (encoded[offset]))
--offset;
if (offset > 0 && encoded[offset] == '.')
{
*len = offset;
return offset + 1;
}
return -1;
}
/* Convert an ASCII hex string to a number. Reads exactly N
characters from STR. Returns true on success, false if one of the
digits was not a hex digit. */
static bool
convert_hex (const char *str, int n, uint32_t *out)
{
uint32_t result = 0;
for (int i = 0; i < n; ++i)
{
if (!isxdigit (str[i]))
return false;
result <<= 4;
result |= fromhex (str[i]);
}
*out = result;
return true;
}
/* Convert a wide character from its ASCII hex representation in STR
(consisting of exactly N characters) to the host encoding,
appending the resulting bytes to OUT. If N==2 and the Ada source
charset is not UTF-8, then hex refers to an encoding in the
ADA_SOURCE_CHARSET; otherwise, use UTF-32. Return true on success.
Return false and do not modify OUT on conversion failure. */
static bool
convert_from_hex_encoded (std::string &out, const char *str, int n)
{
uint32_t value;
if (!convert_hex (str, n, &value))
return false;
try
{
auto_obstack bytes;
/* In the 'U' case, the hex digits encode the character in the
Ada source charset. However, if the source charset is UTF-8,
this really means it is a single-byte UTF-32 character. */
if (n == 2 && ada_source_charset != ada_utf8)
{
gdb_byte one_char = (gdb_byte) value;
convert_between_encodings (ada_source_charset, host_charset (),
&one_char,
sizeof (one_char), sizeof (one_char),
&bytes, translit_none);
}
else
convert_between_encodings (HOST_UTF32, host_charset (),
(const gdb_byte *) &value,
sizeof (value), sizeof (value),
&bytes, translit_none);
obstack_1grow (&bytes, '\0');
out.append ((const char *) obstack_base (&bytes));
}
catch (const gdb_exception &)
{
/* On failure, the caller will just let the encoded form
through, which seems basically reasonable. */
return false;
}
return true;
}
/* See ada-lang.h. */
std::string
ada_decode (const char *encoded, bool wrap, bool operators, bool wide)
{
int i;
int len0;
const char *p;
int at_start_name;
std::string decoded;
int suffix = -1;
/* With function descriptors on PPC64, the value of a symbol named
".FN", if it exists, is the entry point of the function "FN". */
if (encoded[0] == '.')
encoded += 1;
/* The name of the Ada main procedure starts with "_ada_".
This prefix is not part of the decoded name, so skip this part
if we see this prefix. */
if (startswith (encoded, "_ada_"))
encoded += 5;
/* The "___ghost_" prefix is used for ghost entities. Normally
these aren't preserved but when they are, it's useful to see
them. */
if (startswith (encoded, "___ghost_"))
encoded += 9;
/* If the name starts with '_', then it is not a properly encoded
name, so do not attempt to decode it. Similarly, if the name
starts with '<', the name should not be decoded. */
if (encoded[0] == '_' || encoded[0] == '<')
goto Suppress;
len0 = strlen (encoded);
suffix = remove_compiler_suffix (encoded, &len0);
ada_remove_trailing_digits (encoded, &len0);
ada_remove_po_subprogram_suffix (encoded, &len0);
/* Remove the ___X.* suffix if present. Do not forget to verify that
the suffix is located before the current "end" of ENCODED. We want
to avoid re-matching parts of ENCODED that have previously been
marked as discarded (by decrementing LEN0). */
p = strstr (encoded, "___");
if (p != NULL && p - encoded < len0 - 3)
{
if (p[3] == 'X')
len0 = p - encoded;
else
goto Suppress;
}
/* Remove any trailing TKB suffix. It tells us that this symbol
is for the body of a task, but that information does not actually
appear in the decoded name. */
if (len0 > 3 && startswith (encoded + len0 - 3, "TKB"))
len0 -= 3;
/* Remove any trailing TB suffix. The TB suffix is slightly different
from the TKB suffix because it is used for non-anonymous task
bodies. */
if (len0 > 2 && startswith (encoded + len0 - 2, "TB"))
len0 -= 2;
/* Remove trailing "B" suffixes. */
/* FIXME: brobecker/2006-04-19: Not sure what this are used for... */
if (len0 > 1 && startswith (encoded + len0 - 1, "B"))
len0 -= 1;
/* Remove trailing __{digit}+ or trailing ${digit}+. */
if (len0 > 1 && isdigit (encoded[len0 - 1]))
{
i = len0 - 2;
while ((i >= 0 && isdigit (encoded[i]))
|| (i >= 1 && encoded[i] == '_' && isdigit (encoded[i - 1])))
i -= 1;
if (i > 1 && encoded[i] == '_' && encoded[i - 1] == '_')
len0 = i - 1;
else if (i >= 0 && encoded[i] == '$')
len0 = i;
}
/* The first few characters that are not alphabetic are not part
of any encoding we use, so we can copy them over verbatim. */
for (i = 0; i < len0 && !isalpha (encoded[i]); i += 1)
decoded.push_back (encoded[i]);
at_start_name = 1;
while (i < len0)
{
/* Is this a symbol function? */
if (operators && at_start_name && encoded[i] == 'O')
{
int k;
for (k = 0; ada_opname_table[k].encoded != NULL; k += 1)
{
int op_len = strlen (ada_opname_table[k].encoded);
if ((strncmp (ada_opname_table[k].encoded + 1, encoded + i + 1,
op_len - 1) == 0)
&& !isalnum (encoded[i + op_len]))
{
decoded.append (ada_opname_table[k].decoded);
at_start_name = 0;
i += op_len;
break;
}
}
if (ada_opname_table[k].encoded != NULL)
continue;
}
at_start_name = 0;
/* Replace "TK__" with "__", which will eventually be translated
into "." (just below). */
if (i < len0 - 4 && startswith (encoded + i, "TK__"))
i += 2;
/* Replace "__B_{DIGITS}+__" sequences by "__", which will eventually
be translated into "." (just below). These are internal names
generated for anonymous blocks inside which our symbol is nested. */
if (len0 - i > 5 && encoded [i] == '_' && encoded [i+1] == '_'
&& encoded [i+2] == 'B' && encoded [i+3] == '_'
&& isdigit (encoded [i+4]))
{
int k = i + 5;
while (k < len0 && isdigit (encoded[k]))
k++; /* Skip any extra digit. */
/* Double-check that the "__B_{DIGITS}+" sequence we found
is indeed followed by "__". */
if (len0 - k > 2 && encoded [k] == '_' && encoded [k+1] == '_')
i = k;
}
/* Remove _E{DIGITS}+[sb] */
/* Just as for protected object subprograms, there are 2 categories
of subprograms created by the compiler for each entry. The first
one implements the actual entry code, and has a suffix following
the convention above; the second one implements the barrier and
uses the same convention as above, except that the 'E' is replaced
by a 'B'.
Just as above, we do not decode the name of barrier functions
to give the user a clue that the code he is debugging has been
internally generated. */
if (len0 - i > 3 && encoded [i] == '_' && encoded[i+1] == 'E'
&& isdigit (encoded[i+2]))
{
int k = i + 3;
while (k < len0 && isdigit (encoded[k]))
k++;
if (k < len0
&& (encoded[k] == 'b' || encoded[k] == 's'))
{
k++;
/* Just as an extra precaution, make sure that if this
suffix is followed by anything else, it is a '_'.
Otherwise, we matched this sequence by accident. */
if (k == len0
|| (k < len0 && encoded[k] == '_'))
i = k;
}
}
/* Remove trailing "N" in [a-z0-9]+N__. The N is added by
the GNAT front-end in protected object subprograms. */
if (i < len0 + 3
&& encoded[i] == 'N' && encoded[i+1] == '_' && encoded[i+2] == '_')
{
/* Backtrack a bit up until we reach either the begining of
the encoded name, or "__". Make sure that we only find
digits or lowercase characters. */
const char *ptr = encoded + i - 1;
while (ptr >= encoded && is_lower_alphanum (ptr[0]))
ptr--;
if (ptr < encoded
|| (ptr > encoded && ptr[0] == '_' && ptr[-1] == '_'))
i++;
}
if (wide && i < len0 + 3 && encoded[i] == 'U' && isxdigit (encoded[i + 1]))
{
if (convert_from_hex_encoded (decoded, &encoded[i + 1], 2))
{
i += 3;
continue;
}
}
else if (wide && i < len0 + 5 && encoded[i] == 'W' && isxdigit (encoded[i + 1]))
{
if (convert_from_hex_encoded (decoded, &encoded[i + 1], 4))
{
i += 5;
continue;
}
}
else if (wide && i < len0 + 10 && encoded[i] == 'W' && encoded[i + 1] == 'W'
&& isxdigit (encoded[i + 2]))
{
if (convert_from_hex_encoded (decoded, &encoded[i + 2], 8))
{
i += 10;
continue;
}
}
if (encoded[i] == 'X' && i != 0 && isalnum (encoded[i - 1]))
{
/* This is a X[bn]* sequence not separated from the previous
part of the name with a non-alpha-numeric character (in other
words, immediately following an alpha-numeric character), then
verify that it is placed at the end of the encoded name. If
not, then the encoding is not valid and we should abort the
decoding. Otherwise, just skip it, it is used in body-nested
package names. */
do
i += 1;
while (i < len0 && (encoded[i] == 'b' || encoded[i] == 'n'));
if (i < len0)
goto Suppress;
}
else if (i < len0 - 2 && encoded[i] == '_' && encoded[i + 1] == '_')
{
/* Replace '__' by '.'. */
decoded.push_back ('.');
at_start_name = 1;
i += 2;
}
else
{
/* It's a character part of the decoded name, so just copy it
over. */
decoded.push_back (encoded[i]);
i += 1;
}
}
/* Decoded names should never contain any uppercase character.
Double-check this, and abort the decoding if we find one. */
if (operators)
{
for (i = 0; i < decoded.length(); ++i)
if (isupper (decoded[i]) || decoded[i] == ' ')
goto Suppress;
}
/* If the compiler added a suffix, append it now. */
if (suffix >= 0)
decoded = decoded + "[" + &encoded[suffix] + "]";
return decoded;
Suppress:
if (!wrap)
return {};
if (encoded[0] == '<')
decoded = encoded;
else
decoded = '<' + std::string(encoded) + '>';
return decoded;
}
#ifdef GDB_SELF_TEST
static void
ada_decode_tests ()
{
/* This isn't valid, but used to cause a crash. PR gdb/30639. The
result does not really matter very much. */
SELF_CHECK (ada_decode ("44") == "44");
}
#endif
/* Table for keeping permanent unique copies of decoded names. Once
allocated, names in this table are never released. While this is a
storage leak, it should not be significant unless there are massive
changes in the set of decoded names in successive versions of a
symbol table loaded during a single session. */
static struct htab *decoded_names_store;
/* Returns the decoded name of GSYMBOL, as for ada_decode, caching it
in the language-specific part of GSYMBOL, if it has not been
previously computed. Tries to save the decoded name in the same
obstack as GSYMBOL, if possible, and otherwise on the heap (so that,
in any case, the decoded symbol has a lifetime at least that of
GSYMBOL).
The GSYMBOL parameter is "mutable" in the C++ sense: logically
const, but nevertheless modified to a semantically equivalent form
when a decoded name is cached in it. */
const char *
ada_decode_symbol (const struct general_symbol_info *arg)
{
struct general_symbol_info *gsymbol = (struct general_symbol_info *) arg;
const char **resultp =
&gsymbol->language_specific.demangled_name;
if (!gsymbol->ada_mangled)
{
std::string decoded = ada_decode (gsymbol->linkage_name ());
struct obstack *obstack = gsymbol->language_specific.obstack;
gsymbol->ada_mangled = 1;
if (obstack != NULL)
*resultp = obstack_strdup (obstack, decoded.c_str ());
else
{
/* Sometimes, we can't find a corresponding objfile, in
which case, we put the result on the heap. Since we only
decode when needed, we hope this usually does not cause a
significant memory leak (FIXME). */
char **slot = (char **) htab_find_slot (decoded_names_store,
decoded.c_str (), INSERT);
if (*slot == NULL)
*slot = xstrdup (decoded.c_str ());
*resultp = *slot;
}
}
return *resultp;
}
/* Arrays */
/* Assuming that INDEX_DESC_TYPE is an ___XA structure, a structure
generated by the GNAT compiler to describe the index type used
for each dimension of an array, check whether it follows the latest
known encoding. If not, fix it up to conform to the latest encoding.
Otherwise, do nothing. This function also does nothing if
INDEX_DESC_TYPE is NULL.
The GNAT encoding used to describe the array index type evolved a bit.
Initially, the information would be provided through the name of each
field of the structure type only, while the type of these fields was
described as unspecified and irrelevant. The debugger was then expected
to perform a global type lookup using the name of that field in order
to get access to the full index type description. Because these global
lookups can be very expensive, the encoding was later enhanced to make
the global lookup unnecessary by defining the field type as being
the full index type description.
The purpose of this routine is to allow us to support older versions
of the compiler by detecting the use of the older encoding, and by
fixing up the INDEX_DESC_TYPE to follow the new one (at this point,
we essentially replace each field's meaningless type by the associated
index subtype). */
void
ada_fixup_array_indexes_type (struct type *index_desc_type)
{
int i;
if (index_desc_type == NULL)
return;
gdb_assert (index_desc_type->num_fields () > 0);
/* Check if INDEX_DESC_TYPE follows the older encoding (it is sufficient
to check one field only, no need to check them all). If not, return
now.
If our INDEX_DESC_TYPE was generated using the older encoding,
the field type should be a meaningless integer type whose name
is not equal to the field name. */
if (index_desc_type->field (0).type ()->name () != NULL
&& strcmp (index_desc_type->field (0).type ()->name (),
index_desc_type->field (0).name ()) == 0)
return;
/* Fixup each field of INDEX_DESC_TYPE. */
for (i = 0; i < index_desc_type->num_fields (); i++)
{
const char *name = index_desc_type->field (i).name ();
struct type *raw_type = ada_check_typedef (ada_find_any_type (name));
if (raw_type)
index_desc_type->field (i).set_type (raw_type);
}
}
/* The desc_* routines return primitive portions of array descriptors
(fat pointers). */
/* The descriptor or array type, if any, indicated by TYPE; removes
level of indirection, if needed. */
static struct type *
desc_base_type (struct type *type)
{
if (type == NULL)
return NULL;
type = ada_check_typedef (type);
if (type->code () == TYPE_CODE_TYPEDEF)
type = ada_typedef_target_type (type);
if (type != NULL
&& (type->code () == TYPE_CODE_PTR
|| type->code () == TYPE_CODE_REF))
return ada_check_typedef (type->target_type ());
else
return type;
}
/* True iff TYPE indicates a "thin" array pointer type. */
static int
is_thin_pntr (struct type *type)
{
return
is_suffix (ada_type_name (desc_base_type (type)), "___XUT")
|| is_suffix (ada_type_name (desc_base_type (type)), "___XUT___XVE");
}
/* The descriptor type for thin pointer type TYPE. */
static struct type *
thin_descriptor_type (struct type *type)
{
struct type *base_type = desc_base_type (type);
if (base_type == NULL)
return NULL;
if (is_suffix (ada_type_name (base_type), "___XVE"))
return base_type;
else
{
struct type *alt_type = ada_find_parallel_type (base_type, "___XVE");
if (alt_type == NULL)
return base_type;
else
return alt_type;
}
}
/* A pointer to the array data for thin-pointer value VAL. */
static struct value *
thin_data_pntr (struct value *val)
{
struct type *type = ada_check_typedef (val->type ());
struct type *data_type = desc_data_target_type (thin_descriptor_type (type));
data_type = lookup_pointer_type (data_type);
if (type->code () == TYPE_CODE_PTR)
return value_cast (data_type, val->copy ());
else
return value_from_longest (data_type, val->address ());
}
/* True iff TYPE indicates a "thick" array pointer type. */
static int
is_thick_pntr (struct type *type)
{
type = desc_base_type (type);
return (type != NULL && type->code () == TYPE_CODE_STRUCT
&& lookup_struct_elt_type (type, "P_BOUNDS", 1) != NULL);
}
/* If TYPE is the type of an array descriptor (fat or thin pointer) or a
pointer to one, the type of its bounds data; otherwise, NULL. */
static struct type *
desc_bounds_type (struct type *type)
{
struct type *r;
type = desc_base_type (type);
if (type == NULL)
return NULL;
else if (is_thin_pntr (type))
{
type = thin_descriptor_type (type);
if (type == NULL)
return NULL;
r = lookup_struct_elt_type (type, "BOUNDS", 1);
if (r != NULL)
return ada_check_typedef (r);
}
else if (type->code () == TYPE_CODE_STRUCT)
{
r = lookup_struct_elt_type (type, "P_BOUNDS", 1);
if (r != NULL)
return ada_check_typedef (ada_check_typedef (r)->target_type ());
}
return NULL;
}
/* If ARR is an array descriptor (fat or thin pointer), or pointer to
one, a pointer to its bounds data. Otherwise NULL. */
static struct value *
desc_bounds (struct value *arr)
{
struct type *type = ada_check_typedef (arr->type ());
if (is_thin_pntr (type))
{
struct type *bounds_type =
desc_bounds_type (thin_descriptor_type (type));
LONGEST addr;
if (bounds_type == NULL)
error (_("Bad GNAT array descriptor"));
/* NOTE: The following calculation is not really kosher, but
since desc_type is an XVE-encoded type (and shouldn't be),
the correct calculation is a real pain. FIXME (and fix GCC). */
if (type->code () == TYPE_CODE_PTR)
addr = value_as_long (arr);
else
addr = arr->address ();
return
value_from_longest (lookup_pointer_type (bounds_type),
addr - bounds_type->length ());
}
else if (is_thick_pntr (type))
{
struct value *p_bounds = value_struct_elt (&arr, {}, "P_BOUNDS", NULL,
_("Bad GNAT array descriptor"));
struct type *p_bounds_type = p_bounds->type ();
if (p_bounds_type
&& p_bounds_type->code () == TYPE_CODE_PTR)
{
struct type *target_type = p_bounds_type->target_type ();
if (target_type->is_stub ())
p_bounds = value_cast (lookup_pointer_type
(ada_check_typedef (target_type)),
p_bounds);
}
else
error (_("Bad GNAT array descriptor"));
return p_bounds;
}
else
return NULL;
}
/* If TYPE is the type of an array-descriptor (fat pointer), the bit
position of the field containing the address of the bounds data. */
static int
fat_pntr_bounds_bitpos (struct type *type)
{
return desc_base_type (type)->field (1).loc_bitpos ();
}
/* If TYPE is the type of an array-descriptor (fat pointer), the bit
size of the field containing the address of the bounds data. */
static int
fat_pntr_bounds_bitsize (struct type *type)
{
type = desc_base_type (type);
if (type->field (1).bitsize () > 0)
return type->field (1).bitsize ();
else
return 8 * ada_check_typedef (type->field (1).type ())->length ();
}
/* If TYPE is the type of an array descriptor (fat or thin pointer) or a
pointer to one, the type of its array data (a array-with-no-bounds type);
otherwise, NULL. Use ada_type_of_array to get an array type with bounds
data. */
static struct type *
desc_data_target_type (struct type *type)
{
type = desc_base_type (type);
/* NOTE: The following is bogus; see comment in desc_bounds. */
if (is_thin_pntr (type))
return desc_base_type (thin_descriptor_type (type)->field (1).type ());
else if (is_thick_pntr (type))
{
struct type *data_type = lookup_struct_elt_type (type, "P_ARRAY", 1);
if (data_type
&& ada_check_typedef (data_type)->code () == TYPE_CODE_PTR)
return ada_check_typedef (data_type->target_type ());
}
return NULL;
}
/* If ARR is an array descriptor (fat or thin pointer), a pointer to
its array data. */
static struct value *
desc_data (struct value *arr)
{
struct type *type = arr->type ();
if (is_thin_pntr (type))
return thin_data_pntr (arr);
else if (is_thick_pntr (type))
return value_struct_elt (&arr, {}, "P_ARRAY", NULL,
_("Bad GNAT array descriptor"));
else
return NULL;
}
/* If TYPE is the type of an array-descriptor (fat pointer), the bit
position of the field containing the address of the data. */
static int
fat_pntr_data_bitpos (struct type *type)
{
return desc_base_type (type)->field (0).loc_bitpos ();
}
/* If TYPE is the type of an array-descriptor (fat pointer), the bit
size of the field containing the address of the data. */
static int
fat_pntr_data_bitsize (struct type *type)
{
type = desc_base_type (type);
if (type->field (0).bitsize () > 0)
return type->field (0).bitsize ();
else
return TARGET_CHAR_BIT * type->field (0).type ()->length ();
}
/* If BOUNDS is an array-bounds structure (or pointer to one), return
the Ith lower bound stored in it, if WHICH is 0, and the Ith upper
bound, if WHICH is 1. The first bound is I=1. */
static struct value *
desc_one_bound (struct value *bounds, int i, int which)
{
char bound_name[20];
xsnprintf (bound_name, sizeof (bound_name), "%cB%d",
which ? 'U' : 'L', i - 1);
return value_struct_elt (&bounds, {}, bound_name, NULL,
_("Bad GNAT array descriptor bounds"));
}
/* If BOUNDS is an array-bounds structure type, return the bit position
of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper
bound, if WHICH is 1. The first bound is I=1. */
static int
desc_bound_bitpos (struct type *type, int i, int which)
{
return desc_base_type (type)->field (2 * i + which - 2).loc_bitpos ();
}
/* If BOUNDS is an array-bounds structure type, return the bit field size
of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper
bound, if WHICH is 1. The first bound is I=1. */
static int
desc_bound_bitsize (struct type *type, int i, int which)
{
type = desc_base_type (type);
if (type->field (2 * i + which - 2).bitsize () > 0)
return type->field (2 * i + which - 2).bitsize ();
else
return 8 * type->field (2 * i + which - 2).type ()->length ();
}
/* If TYPE is the type of an array-bounds structure, the type of its
Ith bound (numbering from 1). Otherwise, NULL. */
static struct type *
desc_index_type (struct type *type, int i)
{
type = desc_base_type (type);
if (type->code () == TYPE_CODE_STRUCT)
{
char bound_name[20];
xsnprintf (bound_name, sizeof (bound_name), "LB%d", i - 1);
return lookup_struct_elt_type (type, bound_name, 1);
}
else
return NULL;
}
/* The number of index positions in the array-bounds type TYPE.
Return 0 if TYPE is NULL. */
static int
desc_arity (struct type *type)
{
type = desc_base_type (type);
if (type != NULL)
return type->num_fields () / 2;
return 0;
}
/* Non-zero iff TYPE is a simple array type (not a pointer to one) or
an array descriptor type (representing an unconstrained array
type). */
static int
ada_is_direct_array_type (struct type *type)
{
if (type == NULL)
return 0;
type = ada_check_typedef (type);
return (type->code () == TYPE_CODE_ARRAY
|| ada_is_array_descriptor_type (type));
}
/* Non-zero iff TYPE represents any kind of array in Ada, or a pointer
* to one. */
static int
ada_is_array_type (struct type *type)
{
while (type != NULL
&& (type->code () == TYPE_CODE_PTR
|| type->code () == TYPE_CODE_REF))
type = type->target_type ();
return ada_is_direct_array_type (type);
}
/* Non-zero iff TYPE is a simple array type or pointer to one. */
int
ada_is_simple_array_type (struct type *type)
{
if (type == NULL)
return 0;
type = ada_check_typedef (type);
return (type->code () == TYPE_CODE_ARRAY
|| (type->code () == TYPE_CODE_PTR
&& (ada_check_typedef (type->target_type ())->code ()
== TYPE_CODE_ARRAY)));
}
/* Non-zero iff TYPE belongs to a GNAT array descriptor. */
int
ada_is_array_descriptor_type (struct type *type)
{
struct type *data_type = desc_data_target_type (type);
if (type == NULL)
return 0;
type = ada_check_typedef (type);
return (data_type != NULL
&& data_type->code () == TYPE_CODE_ARRAY
&& desc_arity (desc_bounds_type (type)) > 0);
}
/* If ARR has a record type in the form of a standard GNAT array descriptor,
(fat pointer) returns the type of the array data described---specifically,
a pointer-to-array type. If BOUNDS is non-zero, the bounds data are filled
in from the descriptor; otherwise, they are left unspecified. If
the ARR denotes a null array descriptor and BOUNDS is non-zero,
returns NULL. The result is simply the type of ARR if ARR is not
a descriptor. */
static struct type *
ada_type_of_array (struct value *arr, int bounds)
{
if (ada_is_constrained_packed_array_type (arr->type ()))
return decode_constrained_packed_array_type (arr->type ());
if (!ada_is_array_descriptor_type (arr->type ()))
return arr->type ();
if (!bounds)
{
struct type *array_type =
ada_check_typedef (desc_data_target_type (arr->type ()));
if (ada_is_unconstrained_packed_array_type (arr->type ()))
array_type->field (0).set_bitsize
(decode_packed_array_bitsize (arr->type ()));
return array_type;
}
else
{
struct type *elt_type;
int arity;
struct value *descriptor;
elt_type = ada_array_element_type (arr->type (), -1);
arity = ada_array_arity (arr->type ());
if (elt_type == NULL || arity == 0)
return ada_check_typedef (arr->type ());
descriptor = desc_bounds (arr);
if (value_as_long (descriptor) == 0)
return NULL;
while (arity > 0)
{
type_allocator alloc (arr->type ());
struct value *low = desc_one_bound (descriptor, arity, 0);
struct value *high = desc_one_bound (descriptor, arity, 1);
arity -= 1;
struct type *range_type
= create_static_range_type (alloc, low->type (),
longest_to_int (value_as_long (low)),
longest_to_int (value_as_long (high)));
elt_type = create_array_type (alloc, elt_type, range_type);
INIT_GNAT_SPECIFIC (elt_type);
if (ada_is_unconstrained_packed_array_type (arr->type ()))
{
/* We need to store the element packed bitsize, as well as
recompute the array size, because it was previously
computed based on the unpacked element size. */
LONGEST lo = value_as_long (low);
LONGEST hi = value_as_long (high);
elt_type->field (0).set_bitsize
(decode_packed_array_bitsize (arr->type ()));
/* If the array has no element, then the size is already
zero, and does not need to be recomputed. */
if (lo < hi)
{
int array_bitsize =
(hi - lo + 1) * elt_type->field (0).bitsize ();
elt_type->set_length ((array_bitsize + 7) / 8);
}
}
}
return lookup_pointer_type (elt_type);
}
}
/* If ARR does not represent an array, returns ARR unchanged.
Otherwise, returns either a standard GDB array with bounds set
appropriately or, if ARR is a non-null fat pointer, a pointer to a standard
GDB array. Returns NULL if ARR is a null fat pointer. */
struct value *
ada_coerce_to_simple_array_ptr (struct value *arr)
{
if (ada_is_array_descriptor_type (arr->type ()))
{
struct type *arrType = ada_type_of_array (arr, 1);
if (arrType == NULL)
return NULL;
return value_cast (arrType, desc_data (arr)->copy ());
}
else if (ada_is_constrained_packed_array_type (arr->type ()))
return decode_constrained_packed_array (arr);
else
return arr;
}
/* If ARR does not represent an array, returns ARR unchanged.
Otherwise, returns a standard GDB array describing ARR (which may
be ARR itself if it already is in the proper form). */
struct value *
ada_coerce_to_simple_array (struct value *arr)
{
if (ada_is_array_descriptor_type (arr->type ()))
{
struct value *arrVal = ada_coerce_to_simple_array_ptr (arr);
if (arrVal == NULL)
error (_("Bounds unavailable for null array pointer."));
return value_ind (arrVal);
}
else if (ada_is_constrained_packed_array_type (arr->type ()))
return decode_constrained_packed_array (arr);
else
return arr;
}
/* If TYPE represents a GNAT array type, return it translated to an
ordinary GDB array type (possibly with BITSIZE fields indicating
packing). For other types, is the identity. */
struct type *
ada_coerce_to_simple_array_type (struct type *type)
{
if (ada_is_constrained_packed_array_type (type))
return decode_constrained_packed_array_type (type);
if (ada_is_array_descriptor_type (type))
return ada_check_typedef (desc_data_target_type (type));
return type;
}
/* Non-zero iff TYPE represents a standard GNAT packed-array type. */
static int
ada_is_gnat_encoded_packed_array_type (struct type *type)
{
if (type == NULL)
return 0;
type = desc_base_type (type);
type = ada_check_typedef (type);
return
ada_type_name (type) != NULL
&& strstr (ada_type_name (type), "___XP") != NULL;
}
/* Non-zero iff TYPE represents a standard GNAT constrained
packed-array type. */
int
ada_is_constrained_packed_array_type (struct type *type)
{
return ada_is_gnat_encoded_packed_array_type (type)
&& !ada_is_array_descriptor_type (type);
}
/* Non-zero iff TYPE represents an array descriptor for a
unconstrained packed-array type. */
static int
ada_is_unconstrained_packed_array_type (struct type *type)
{
if (!ada_is_array_descriptor_type (type))
return 0;
if (ada_is_gnat_encoded_packed_array_type (type))
return 1;
/* If we saw GNAT encodings, then the above code is sufficient.
However, with minimal encodings, we will just have a thick
pointer instead. */
if (is_thick_pntr (type))
{
type = desc_base_type (type);
/* The structure's first field is a pointer to an array, so this
fetches the array type. */
type = type->field (0).type ()->target_type ();
if (type->code () == TYPE_CODE_TYPEDEF)
type = ada_typedef_target_type (type);
/* Now we can see if the array elements are packed. */
return type->field (0).bitsize () > 0;
}
return 0;
}
/* Return true if TYPE is a (Gnat-encoded) constrained packed array
type, or if it is an ordinary (non-Gnat-encoded) packed array. */
static bool
ada_is_any_packed_array_type (struct type *type)
{
return (ada_is_constrained_packed_array_type (type)
|| (type->code () == TYPE_CODE_ARRAY
&& type->field (0).bitsize () % 8 != 0));
}
/* Given that TYPE encodes a packed array type (constrained or unconstrained),
return the size of its elements in bits. */
static long
decode_packed_array_bitsize (struct type *type)
{
const char *raw_name;
const char *tail;
long bits;
/* Access to arrays implemented as fat pointers are encoded as a typedef
of the fat pointer type. We need the name of the fat pointer type
to do the decoding, so strip the typedef layer. */
if (type->code () == TYPE_CODE_TYPEDEF)
type = ada_typedef_target_type (type);
raw_name = ada_type_name (ada_check_typedef (type));
if (!raw_name)
raw_name = ada_type_name (desc_base_type (type));
if (!raw_name)
return 0;
tail = strstr (raw_name, "___XP");
if (tail == nullptr)
{
gdb_assert (is_thick_pntr (type));
/* The structure's first field is a pointer to an array, so this
fetches the array type. */
type = type->field (0).type ()->target_type ();
/* Now we can see if the array elements are packed. */
return type->field (0).bitsize ();
}
if (sscanf (tail + sizeof ("___XP") - 1, "%ld", &bits) != 1)
{
lim_warning
(_("could not understand bit size information on packed array"));
return 0;
}
return bits;
}
/* Given that TYPE is a standard GDB array type with all bounds filled
in, and that the element size of its ultimate scalar constituents
(that is, either its elements, or, if it is an array of arrays, its
elements' elements, etc.) is *ELT_BITS, return an identical type,
but with the bit sizes of its elements (and those of any
constituent arrays) recorded in the BITSIZE components of its
TYPE_FIELD_BITSIZE values, and with *ELT_BITS set to its total size
in bits.
Note that, for arrays whose index type has an XA encoding where
a bound references a record discriminant, getting that discriminant,
and therefore the actual value of that bound, is not possible
because none of the given parameters gives us access to the record.
This function assumes that it is OK in the context where it is being
used to return an array whose bounds are still dynamic and where
the length is arbitrary. */
static struct type *
constrained_packed_array_type (struct type *type, long *elt_bits)
{
struct type *new_elt_type;
struct type *new_type;
struct type *index_type_desc;
struct type *index_type;
LONGEST low_bound, high_bound;
type = ada_check_typedef (type);
if (type->code () != TYPE_CODE_ARRAY)
return type;
index_type_desc = ada_find_parallel_type (type, "___XA");
if (index_type_desc)
index_type = to_fixed_range_type (index_type_desc->field (0).type (),
NULL);
else
index_type = type->index_type ();
type_allocator alloc (type);
new_elt_type =
constrained_packed_array_type (ada_check_typedef (type->target_type ()),
elt_bits);
new_type = create_array_type (alloc, new_elt_type, index_type);
new_type->field (0).set_bitsize (*elt_bits);
new_type->set_name (ada_type_name (type));
if ((check_typedef (index_type)->code () == TYPE_CODE_RANGE
&& is_dynamic_type (check_typedef (index_type)))
|| !get_discrete_bounds (index_type, &low_bound, &high_bound))
low_bound = high_bound = 0;
if (high_bound < low_bound)
{
*elt_bits = 0;
new_type->set_length (0);
}
else
{
*elt_bits *= (high_bound - low_bound + 1);
new_type->set_length ((*elt_bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT);
}
new_type->set_is_fixed_instance (true);
return new_type;
}
/* The array type encoded by TYPE, where
ada_is_constrained_packed_array_type (TYPE). */
static struct type *
decode_constrained_packed_array_type (struct type *type)
{
const char *raw_name = ada_type_name (ada_check_typedef (type));
char *name;
const char *tail;
struct type *shadow_type;
long bits;
if (!raw_name)
raw_name = ada_type_name (desc_base_type (type));
if (!raw_name)
return NULL;
name = (char *) alloca (strlen (raw_name) + 1);
tail = strstr (raw_name, "___XP");
type = desc_base_type (type);
memcpy (name, raw_name, tail - raw_name);
name[tail - raw_name] = '\000';
shadow_type = ada_find_parallel_type_with_name (type, name);
if (shadow_type == NULL)
{
lim_warning (_("could not find bounds information on packed array"));
return NULL;
}
shadow_type = check_typedef (shadow_type);
if (shadow_type->code () != TYPE_CODE_ARRAY)
{
lim_warning (_("could not understand bounds "
"information on packed array"));
return NULL;
}
bits = decode_packed_array_bitsize (type);
return constrained_packed_array_type (shadow_type, &bits);
}
/* Helper function for decode_constrained_packed_array. Set the field
bitsize on a series of packed arrays. Returns the number of
elements in TYPE. */
static LONGEST
recursively_update_array_bitsize (struct type *type)
{
gdb_assert (type->code () == TYPE_CODE_ARRAY);
LONGEST low, high;
if (!get_discrete_bounds (type->index_type (), &low, &high)
|| low > high)
return 0;
LONGEST our_len = high - low + 1;
struct type *elt_type = type->target_type ();
if (elt_type->code () == TYPE_CODE_ARRAY)
{
LONGEST elt_len = recursively_update_array_bitsize (elt_type);
LONGEST elt_bitsize = elt_len * elt_type->field (0).bitsize ();
type->field (0).set_bitsize (elt_bitsize);
type->set_length (((our_len * elt_bitsize + HOST_CHAR_BIT - 1)
/ HOST_CHAR_BIT));
}
return our_len;
}
/* Given that ARR is a struct value *indicating a GNAT constrained packed
array, returns a simple array that denotes that array. Its type is a
standard GDB array type except that the BITSIZEs of the array
target types are set to the number of bits in each element, and the
type length is set appropriately. */
static struct value *
decode_constrained_packed_array (struct value *arr)
{
struct type *type;
/* If our value is a pointer, then dereference it. Likewise if
the value is a reference. Make sure that this operation does not
cause the target type to be fixed, as this would indirectly cause
this array to be decoded. The rest of the routine assumes that
the array hasn't been decoded yet, so we use the basic "coerce_ref"
and "value_ind" routines to perform the dereferencing, as opposed
to using "ada_coerce_ref" or "ada_value_ind". */
arr = coerce_ref (arr);
if (ada_check_typedef (arr->type ())->code () == TYPE_CODE_PTR)
arr = value_ind (arr);
type = decode_constrained_packed_array_type (arr->type ());
if (type == NULL)
{
error (_("can't unpack array"));
return NULL;
}
/* Decoding the packed array type could not correctly set the field
bitsizes for any dimension except the innermost, because the
bounds may be variable and were not passed to that function. So,
we further resolve the array bounds here and then update the
sizes. */
const gdb_byte *valaddr = arr->contents_for_printing ().data ();
CORE_ADDR address = arr->address ();
gdb::array_view<const gdb_byte> view
= gdb::make_array_view (valaddr, type->length ());
type = resolve_dynamic_type (type, view, address);
recursively_update_array_bitsize (type);
if (type_byte_order (arr->type ()) == BFD_ENDIAN_BIG
&& ada_is_modular_type (arr->type ()))
{
/* This is a (right-justified) modular type representing a packed
array with no wrapper. In order to interpret the value through
the (left-justified) packed array type we just built, we must
first left-justify it. */
int bit_size, bit_pos;
ULONGEST mod;
mod = ada_modulus (arr->type ()) - 1;
bit_size = 0;
while (mod > 0)
{
bit_size += 1;
mod >>= 1;
}
bit_pos = HOST_CHAR_BIT * arr->type ()->length () - bit_size;
arr = ada_value_primitive_packed_val (arr, NULL,
bit_pos / HOST_CHAR_BIT,
bit_pos % HOST_CHAR_BIT,
bit_size,
type);
}
return coerce_unspec_val_to_type (arr, type);
}
/* The value of the element of packed array ARR at the ARITY indices
given in IND. ARR must be a simple array. */
static struct value *
value_subscript_packed (struct value *arr, int arity, struct value **ind)
{
int i;
int bits, elt_off, bit_off;
long elt_total_bit_offset;
struct type *elt_type;
struct value *v;
bits = 0;
elt_total_bit_offset = 0;
elt_type = ada_check_typedef (arr->type ());
for (i = 0; i < arity; i += 1)
{
if (elt_type->code () != TYPE_CODE_ARRAY
|| elt_type->field (0).bitsize () == 0)
error
(_("attempt to do packed indexing of "
"something other than a packed array"));
else
{
struct type *range_type = elt_type->index_type ();
LONGEST lowerbound, upperbound;
LONGEST idx;
if (!get_discrete_bounds (range_type, &lowerbound, &upperbound))
{
lim_warning (_("don't know bounds of array"));
lowerbound = upperbound = 0;
}
idx = pos_atr (ind[i]);
if (idx < lowerbound || idx > upperbound)
lim_warning (_("packed array index %ld out of bounds"),
(long) idx);
bits = elt_type->field (0).bitsize ();
elt_total_bit_offset += (idx - lowerbound) * bits;
elt_type = ada_check_typedef (elt_type->target_type ());
}
}
elt_off = elt_total_bit_offset / HOST_CHAR_BIT;
bit_off = elt_total_bit_offset % HOST_CHAR_BIT;
v = ada_value_primitive_packed_val (arr, NULL, elt_off, bit_off,
bits, elt_type);
return v;
}
/* Non-zero iff TYPE includes negative integer values. */
static int
has_negatives (struct type *type)
{
switch (type->code ())
{
default:
return 0;
case TYPE_CODE_INT:
return !type->is_unsigned ();
case TYPE_CODE_RANGE:
return type->bounds ()->low.const_val () - type->bounds ()->bias < 0;
}
}
/* With SRC being a buffer containing BIT_SIZE bits of data at BIT_OFFSET,
unpack that data into UNPACKED. UNPACKED_LEN is the size in bytes of
the unpacked buffer.
The size of the unpacked buffer (UNPACKED_LEN) is expected to be large
enough to contain at least BIT_OFFSET bits. If not, an error is raised.
IS_BIG_ENDIAN is nonzero if the data is stored in big endian mode,
zero otherwise.
IS_SIGNED_TYPE is nonzero if the data corresponds to a signed type.
IS_SCALAR is nonzero if the data corresponds to a signed type. */
static void
ada_unpack_from_contents (const gdb_byte *src, int bit_offset, int bit_size,
gdb_byte *unpacked, int unpacked_len,
int is_big_endian, int is_signed_type,
int is_scalar)
{
int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
int src_idx; /* Index into the source area */
int src_bytes_left; /* Number of source bytes left to process. */
int srcBitsLeft; /* Number of source bits left to move */
int unusedLS; /* Number of bits in next significant
byte of source that are unused */
int unpacked_idx; /* Index into the unpacked buffer */
int unpacked_bytes_left; /* Number of bytes left to set in unpacked. */
unsigned long accum; /* Staging area for bits being transferred */
int accumSize; /* Number of meaningful bits in accum */
unsigned char sign;
/* Transmit bytes from least to most significant; delta is the direction
the indices move. */
int delta = is_big_endian ? -1 : 1;
/* Make sure that unpacked is large enough to receive the BIT_SIZE
bits from SRC. .*/
if ((bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT > unpacked_len)
error (_("Cannot unpack %d bits into buffer of %d bytes"),
bit_size, unpacked_len);
srcBitsLeft = bit_size;
src_bytes_left = src_len;
unpacked_bytes_left = unpacked_len;
sign = 0;
if (is_big_endian)
{
src_idx = src_len - 1;
if (is_signed_type
&& ((src[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1))))
sign = ~0;
unusedLS =
(HOST_CHAR_BIT - (bit_size + bit_offset) % HOST_CHAR_BIT)
% HOST_CHAR_BIT;
if (is_scalar)
{
accumSize = 0;
unpacked_idx = unpacked_len - 1;
}
else
{
/* Non-scalar values must be aligned at a byte boundary... */
accumSize =
(HOST_CHAR_BIT - bit_size % HOST_CHAR_BIT) % HOST_CHAR_BIT;
/* ... And are placed at the beginning (most-significant) bytes
of the target. */
unpacked_idx = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT - 1;
unpacked_bytes_left = unpacked_idx + 1;
}
}
else
{
int sign_bit_offset = (bit_size + bit_offset - 1) % 8;
src_idx = unpacked_idx = 0;
unusedLS = bit_offset;
accumSize = 0;
if (is_signed_type && (src[src_len - 1] & (1 << sign_bit_offset)))
sign = ~0;
}
accum = 0;
while (src_bytes_left > 0)
{
/* Mask for removing bits of the next source byte that are not
part of the value. */
unsigned int unusedMSMask =
(1 << (srcBitsLeft >= HOST_CHAR_BIT ? HOST_CHAR_BIT : srcBitsLeft)) -
1;
/* Sign-extend bits for this byte. */
unsigned int signMask = sign & ~unusedMSMask;
accum |=
(((src[src_idx] >> unusedLS) & unusedMSMask) | signMask) << accumSize;
accumSize += HOST_CHAR_BIT - unusedLS;
if (accumSize >= HOST_CHAR_BIT)
{
unpacked[unpacked_idx] = accum & ~(~0UL << HOST_CHAR_BIT);
accumSize -= HOST_CHAR_BIT;
accum >>= HOST_CHAR_BIT;
unpacked_bytes_left -= 1;
unpacked_idx += delta;
}
srcBitsLeft -= HOST_CHAR_BIT - unusedLS;
unusedLS = 0;
src_bytes_left -= 1;
src_idx += delta;
}
while (unpacked_bytes_left > 0)
{
accum |= sign << accumSize;
unpacked[unpacked_idx] = accum & ~(~0UL << HOST_CHAR_BIT);
accumSize -= HOST_CHAR_BIT;
if (accumSize < 0)
accumSize = 0;
accum >>= HOST_CHAR_BIT;
unpacked_bytes_left -= 1;
unpacked_idx += delta;
}
}
/* Create a new value of type TYPE from the contents of OBJ starting
at byte OFFSET, and bit offset BIT_OFFSET within that byte,
proceeding for BIT_SIZE bits. If OBJ is an lval in memory, then
assigning through the result will set the field fetched from.
VALADDR is ignored unless OBJ is NULL, in which case,
VALADDR+OFFSET must address the start of storage containing the
packed value. The value returned in this case is never an lval.
Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT. */
struct value *
ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
long offset, int bit_offset, int bit_size,
struct type *type)
{
struct value *v;
const gdb_byte *src; /* First byte containing data to unpack */
gdb_byte *unpacked;
const int is_scalar = is_scalar_type (type);
const int is_big_endian = type_byte_order (type) == BFD_ENDIAN_BIG;
gdb::byte_vector staging;
type = ada_check_typedef (type);
if (obj == NULL)
src = valaddr + offset;
else
src = obj->contents ().data () + offset;
if (is_dynamic_type (type))
{
/* The length of TYPE might by dynamic, so we need to resolve
TYPE in order to know its actual size, which we then use
to create the contents buffer of the value we return.
The difficulty is that the data containing our object is
packed, and therefore maybe not at a byte boundary. So, what
we do, is unpack the data into a byte-aligned buffer, and then
use that buffer as our object's value for resolving the type. */
int staging_len = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
staging.resize (staging_len);
ada_unpack_from_contents (src, bit_offset, bit_size,
staging.data (), staging.size (),
is_big_endian, has_negatives (type),
is_scalar);
type = resolve_dynamic_type (type, staging, 0);
if (type->length () < (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT)
{
/* This happens when the length of the object is dynamic,
and is actually smaller than the space reserved for it.
For instance, in an array of variant records, the bit_size
we're given is the array stride, which is constant and
normally equal to the maximum size of its element.
But, in reality, each element only actually spans a portion
of that stride. */
bit_size = type->length () * HOST_CHAR_BIT;
}
}
if (obj == NULL)
{
v = value::allocate (type);
src = valaddr + offset;
}
else if (obj->lval () == lval_memory && obj->lazy ())
{
int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
gdb_byte *buf;
v = value_at (type, obj->address () + offset);
buf = (gdb_byte *) alloca (src_len);
read_memory (v->address (), buf, src_len);
src = buf;
}
else
{
v = value::allocate (type);
src = obj->contents ().data () + offset;
}
if (obj != NULL)
{
long new_offset = offset;
v->set_component_location (obj);
v->set_bitpos (bit_offset + obj->bitpos ());
v->set_bitsize (bit_size);
if (v->bitpos () >= HOST_CHAR_BIT)
{
++new_offset;
v->set_bitpos (v->bitpos () - HOST_CHAR_BIT);
}
v->set_offset (new_offset);
/* Also set the parent value. This is needed when trying to
assign a new value (in inferior memory). */
v->set_parent (obj);
}
else
v->set_bitsize (bit_size);
unpacked = v->contents_writeable ().data ();
if (bit_size == 0)
{
memset (unpacked, 0, type->length ());
return v;
}
if (staging.size () == type->length ())
{
/* Small short-cut: If we've unpacked the data into a buffer
of the same size as TYPE's length, then we can reuse that,
instead of doing the unpacking again. */
memcpy (unpacked, staging.data (), staging.size ());
}
else
ada_unpack_from_contents (src, bit_offset, bit_size,
unpacked, type->length (),
is_big_endian, has_negatives (type), is_scalar);
return v;
}
/* Store the contents of FROMVAL into the location of TOVAL.
Return a new value with the location of TOVAL and contents of
FROMVAL. Handles assignment into packed fields that have
floating-point or non-scalar types. */
static struct value *
ada_value_assign (struct value *toval, struct value *fromval)
{
struct type *type = toval->type ();
int bits = toval->bitsize ();
toval = ada_coerce_ref (toval);
fromval = ada_coerce_ref (fromval);
if (ada_is_direct_array_type (toval->type ()))
toval = ada_coerce_to_simple_array (toval);
if (ada_is_direct_array_type (fromval->type ()))
fromval = ada_coerce_to_simple_array (fromval);
if (!toval->deprecated_modifiable ())
error (_("Left operand of assignment is not a modifiable lvalue."));
if (toval->lval () == lval_memory
&& bits > 0
&& (type->code () == TYPE_CODE_FLT
|| type->code () == TYPE_CODE_STRUCT))
{
int len = (toval->bitpos ()
+ bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
int from_size;
gdb_byte *buffer = (gdb_byte *) alloca (len);
struct value *val;
CORE_ADDR to_addr = toval->address ();
if (type->code () == TYPE_CODE_FLT)
fromval = value_cast (type, fromval);
read_memory (to_addr, buffer, len);
from_size = fromval->bitsize ();
if (from_size == 0)
from_size = fromval->type ()->length () * TARGET_CHAR_BIT;
const int is_big_endian = type_byte_order (type) == BFD_ENDIAN_BIG;
ULONGEST from_offset = 0;
if (is_big_endian && is_scalar_type (fromval->type ()))
from_offset = from_size - bits;
copy_bitwise (buffer, toval->bitpos (),
fromval->contents ().data (), from_offset,
bits, is_big_endian);
write_memory_with_notification (to_addr, buffer, len);
val = toval->copy ();
memcpy (val->contents_raw ().data (),
fromval->contents ().data (),
type->length ());
val->deprecated_set_type (type);
return val;
}
return value_assign (toval, fromval);
}
/* Given that COMPONENT is a memory lvalue that is part of the lvalue
CONTAINER, assign the contents of VAL to COMPONENTS's place in
CONTAINER. Modifies the VALUE_CONTENTS of CONTAINER only, not
COMPONENT, and not the inferior's memory. The current contents
of COMPONENT are ignored.
Although not part of the initial design, this function also works
when CONTAINER and COMPONENT are not_lval's: it works as if CONTAINER
had a null address, and COMPONENT had an address which is equal to
its offset inside CONTAINER. */
static void
value_assign_to_component (struct value *container, struct value *component,
struct value *val)
{
LONGEST offset_in_container =
(LONGEST) (component->address () - container->address ());
int bit_offset_in_container =
component->bitpos () - container->bitpos ();
int bits;
val = value_cast (component->type (), val);
if (component->bitsize () == 0)
bits = TARGET_CHAR_BIT * component->type ()->length ();
else
bits = component->bitsize ();
if (type_byte_order (container->type ()) == BFD_ENDIAN_BIG)
{
int src_offset;
if (is_scalar_type (check_typedef (component->type ())))
src_offset
= component->type ()->length () * TARGET_CHAR_BIT - bits;
else
src_offset = 0;
copy_bitwise ((container->contents_writeable ().data ()
+ offset_in_container),
container->bitpos () + bit_offset_in_container,
val->contents ().data (), src_offset, bits, 1);
}
else
copy_bitwise ((container->contents_writeable ().data ()
+ offset_in_container),
container->bitpos () + bit_offset_in_container,
val->contents ().data (), 0, bits, 0);
}
/* Determine if TYPE is an access to an unconstrained array. */
bool
ada_is_access_to_unconstrained_array (struct type *type)
{
return (type->code () == TYPE_CODE_TYPEDEF
&& is_thick_pntr (ada_typedef_target_type (type)));
}
/* The value of the element of array ARR at the ARITY indices given in IND.
ARR may be either a simple array, GNAT array descriptor, or pointer
thereto. */
struct value *
ada_value_subscript (struct value *arr, int arity, struct value **ind)
{
int k;
struct value *elt;
struct type *elt_type;
elt = ada_coerce_to_simple_array (arr);
elt_type = ada_check_typedef (elt->type ());
if (elt_type->code () == TYPE_CODE_ARRAY
&& elt_type->field (0).bitsize () > 0)
return value_subscript_packed (elt, arity, ind);
for (k = 0; k < arity; k += 1)
{
struct type *saved_elt_type = elt_type->target_type ();
if (elt_type->code () != TYPE_CODE_ARRAY)
error (_("too many subscripts (%d expected)"), k);
elt = value_subscript (elt, pos_atr (ind[k]));
if (ada_is_access_to_unconstrained_array (saved_elt_type)
&& elt->type ()->code () != TYPE_CODE_TYPEDEF)
{
/* The element is a typedef to an unconstrained array,
except that the value_subscript call stripped the
typedef layer. The typedef layer is GNAT's way to
specify that the element is, at the source level, an
access to the unconstrained array, rather than the
unconstrained array. So, we need to restore that
typedef layer, which we can do by forcing the element's
type back to its original type. Otherwise, the returned
value is going to be printed as the array, rather
than as an access. Another symptom of the same issue
would be that an expression trying to dereference the
element would also be improperly rejected. */
elt->deprecated_set_type (saved_elt_type);
}
elt_type = ada_check_typedef (elt->type ());
}
return elt;
}
/* Assuming ARR is a pointer to a GDB array, the value of the element
of *ARR at the ARITY indices given in IND.
Does not read the entire array into memory.
Note: Unlike what one would expect, this function is used instead of
ada_value_subscript for basically all non-packed array types. The reason
for this is that a side effect of doing our own pointer arithmetics instead
of relying on value_subscript is that there is no implicit typedef peeling.
This is important for arrays of array accesses, where it allows us to
preserve the fact that the array's element is an array access, where the
access part os encoded in a typedef layer. */
static struct value *
ada_value_ptr_subscript (struct value *arr, int arity, struct value **ind)
{
int k;
struct value *array_ind = ada_value_ind (arr);
struct type *type
= check_typedef (array_ind->enclosing_type ());
if (type->code () == TYPE_CODE_ARRAY
&& type->field (0).bitsize () > 0)
return value_subscript_packed (array_ind, arity, ind);
for (k = 0; k < arity; k += 1)
{
LONGEST lwb, upb;
if (type->code () != TYPE_CODE_ARRAY)
error (_("too many subscripts (%d expected)"), k);
arr = value_cast (lookup_pointer_type (type->target_type ()),
arr->copy ());
get_discrete_bounds (type->index_type (), &lwb, &upb);
arr = value_ptradd (arr, pos_atr (ind[k]) - lwb);
type = type->target_type ();
}
return value_ind (arr);
}
/* Given that ARRAY_PTR is a pointer or reference to an array of type TYPE (the
actual type of ARRAY_PTR is ignored), returns the Ada slice of
HIGH'Pos-LOW'Pos+1 elements starting at index LOW. The lower bound of
this array is LOW, as per Ada rules. */
static struct value *
ada_value_slice_from_ptr (struct value *array_ptr, struct type *type,
int low, int high)
{
struct type *type0 = ada_check_typedef (type);
struct type *base_index_type = type0->index_type ()->target_type ();
type_allocator alloc (base_index_type);
struct type *index_type
= create_static_range_type (alloc, base_index_type, low, high);
struct type *slice_type = create_array_type_with_stride
(alloc, type0->target_type (), index_type,
type0->dyn_prop (DYN_PROP_BYTE_STRIDE),
type0->field (0).bitsize ());
int base_low = ada_discrete_type_low_bound (type0->index_type ());
std::optional<LONGEST> base_low_pos, low_pos;
CORE_ADDR base;
low_pos = discrete_position (base_index_type, low);
base_low_pos = discrete_position (base_index_type, base_low);
if (!low_pos.has_value () || !base_low_pos.has_value ())
{
warning (_("unable to get positions in slice, use bounds instead"));
low_pos = low;
base_low_pos = base_low;
}
ULONGEST stride = slice_type->field (0).bitsize () / 8;
if (stride == 0)
stride = type0->target_type ()->length ();
base = value_as_address (array_ptr) + (*low_pos - *base_low_pos) * stride;
return value_at_lazy (slice_type, base);
}
static struct value *
ada_value_slice (struct value *array, int low, int high)
{
struct type *type = ada_check_typedef (array->type ());
struct type *base_index_type = type->index_type ()->target_type ();
type_allocator alloc (type->index_type ());
struct type *index_type
= create_static_range_type (alloc, type->index_type (), low, high);
struct type *slice_type = create_array_type_with_stride
(alloc, type->target_type (), index_type,
type->dyn_prop (DYN_PROP_BYTE_STRIDE),
type->field (0).bitsize ());
std::optional<LONGEST> low_pos, high_pos;
low_pos = discrete_position (base_index_type, low);
high_pos = discrete_position (base_index_type, high);
if (!low_pos.has_value () || !high_pos.has_value ())
{
warning (_("unable to get positions in slice, use bounds instead"));
low_pos = low;
high_pos = high;
}
return value_cast (slice_type,
value_slice (array, low, *high_pos - *low_pos + 1));
}
/* If type is a record type in the form of a standard GNAT array
descriptor, returns the number of dimensions for type. If arr is a
simple array, returns the number of "array of"s that prefix its
type designation. Otherwise, returns 0. */
int
ada_array_arity (struct type *type)
{
int arity;