binutils-gdb/gdb/xml-tdesc.c
Pedro Alves a121b7c1ac -Wwrite-strings: The Rest
This is the remainder boring constification that all looks more of less
borderline obvious IMO.

gdb/ChangeLog:
2017-04-05  Pedro Alves  <palves@redhat.com>

	* ada-exp.y (yyerror): Constify.
	* ada-lang.c (bound_name, get_selections)
	(ada_variant_discrim_type)
	(ada_variant_discrim_name, ada_value_struct_elt)
	(ada_lookup_struct_elt_type, is_unchecked_variant)
	(ada_which_variant_applies, standard_exc, ada_get_next_arg)
	(catch_ada_exception_command_split)
	(catch_ada_assert_command_split, catch_assert_command)
	(ada_op_name): Constify.
	* ada-lang.h (ada_yyerror, get_selections)
	(ada_variant_discrim_name, ada_value_struct_elt): Constify.
	* arc-tdep.c (arc_print_frame_cache): Constify.
	* arm-tdep.c (arm_skip_stub): Constify.
	* ax-gdb.c (gen_binop, gen_struct_ref_recursive, gen_struct_ref)
	(gen_aggregate_elt_ref): Constify.
	* bcache.c (print_bcache_statistics): Constify.
	* bcache.h (print_bcache_statistics): Constify.
	* break-catch-throw.c (catch_exception_command_1):
	* breakpoint.c (struct ep_type_description::description):
	Constify.
	(add_solib_catchpoint): Constify.
	(catch_fork_command_1): Add cast.
	(add_catch_command): Constify.
	* breakpoint.h (add_catch_command, add_solib_catchpoint):
	Constify.
	* bsd-uthread.c (bsd_uthread_state): Constify.
	* buildsym.c (patch_subfile_names): Constify.
	* buildsym.h (next_symbol_text_func, patch_subfile_names):
	Constify.
	* c-exp.y (yyerror): Constify.
	(token::oper): Constify.
	* c-lang.h (c_yyerror, cp_print_class_member): Constify.
	* c-varobj.c (cplus_describe_child): Constify.
	* charset.c (find_charset_names): Add cast.
	(find_charset_names): Constify array and add const_cast.
	* cli/cli-cmds.c (complete_command, cd_command): Constify.
	(edit_command): Constify.
	* cli/cli-decode.c (lookup_cmd): Constify.
	* cli/cli-dump.c (dump_memory_command, dump_value_command):
	Constify.
	(struct dump_context): Constify.
	(add_dump_command, restore_command): Constify.
	* cli/cli-script.c (get_command_line): Constify.
	* cli/cli-script.h (get_command_line): Constify.
	* cli/cli-utils.c (check_for_argument): Constify.
	* cli/cli-utils.h (check_for_argument): Constify.
	* coff-pe-read.c (struct read_pe_section_data): Constify.
	* command.h (lookup_cmd): Constify.
	* common/print-utils.c (decimal2str): Constify.
	* completer.c (gdb_print_filename): Constify.
	* corefile.c (set_gnutarget): Constify.
	* cp-name-parser.y (yyerror): Constify.
	* cp-valprint.c (cp_print_class_member): Constify.
	* cris-tdep.c (cris_register_name, crisv32_register_name):
	Constify.
	* d-exp.y (yyerror): Constify.
	(struct token::oper): Constify.
	* d-lang.h (d_yyerror): Constify.
	* dbxread.c (struct header_file_location::name): Constify.
	(add_old_header_file, add_new_header_file, last_function_name)
	(dbx_next_symbol_text, add_bincl_to_list)
	(find_corresponding_bincl_psymtab, set_namestring)
	(find_stab_function_addr, read_dbx_symtab, start_psymtab)
	(dbx_end_psymtab, read_ofile_symtab, process_one_symbol):
	* defs.h (command_line_input, print_address_symbolic)
	(deprecated_readline_begin_hook): Constify.
	* dwarf2read.c (anonymous_struct_prefix, dwarf_bool_name):
	Constify.
	* event-top.c (handle_line_of_input): Constify and add cast.
	* exceptions.c (catch_errors): Constify.
	* exceptions.h (catch_errors): Constify.
	* expprint.c (print_subexp_standard, op_string, op_name)
	(op_name_standard, dump_raw_expression, dump_raw_expression):
	* expression.h (op_name, op_string, dump_raw_expression):
	Constify.
	* f-exp.y (yyerror): Constify.
	(struct token::oper): Constify.
	(struct f77_boolean_val::name): Constify.
	* f-lang.c (f_word_break_characters): Constify.
	* f-lang.h (f_yyerror): Constify.
	* fork-child.c (fork_inferior): Add cast.
	* frv-tdep.c (struct gdbarch_tdep::register_names): Constify.
	(new_variant): Constify.
	* gdbarch.sh (pstring_ptr, pstring_list): Constify.
	* gdbarch.c: Regenerate.
	* gdbcore.h (set_gnutarget): Constify.
	* go-exp.y (yyerror): Constify.
	(token::oper): Constify.
	* go-lang.h (go_yyerror): Constify.
	* go32-nat.c (go32_sysinfo): Constify.
	* guile/scm-breakpoint.c (gdbscm_breakpoint_expression): Constify.
	* guile/scm-cmd.c (cmdscm_function): Constify.
	* guile/scm-param.c (pascm_param_value): Constify.
	* h8300-tdep.c (h8300_register_name, h8300s_register_name)
	(h8300sx_register_name): Constify.
	* hppa-tdep.c (hppa32_register_name, hppa64_register_name):
	Constify.
	* ia64-tdep.c (ia64_register_names): Constify.
	* infcmd.c (construct_inferior_arguments): Constify.
	(path_command, attach_post_wait): Constify.
	* language.c (show_range_command, show_case_command)
	(unk_lang_error): Constify.
	* language.h (language_defn::la_error)
	(language_defn::la_name_of_this): Constify.
	* linespec.c (decode_line_2): Constify.
	* linux-thread-db.c (thread_db_err_str): Constify.
	* lm32-tdep.c (lm32_register_name): Constify.
	* m2-exp.y (yyerror): Constify.
	* m2-lang.h (m2_yyerror): Constify.
	* m32r-tdep.c (m32r_register_names): Constify and make static.
	* m68hc11-tdep.c (m68hc11_register_names): Constify.
	* m88k-tdep.c (m88k_register_name): Constify.
	* macroexp.c (appendmem): Constify.
	* mdebugread.c (fdr_name, add_data_symbol, parse_type)
	(upgrade_type, parse_external, parse_partial_symbols)
	(mdebug_next_symbol_text, cross_ref, mylookup_symbol, new_psymtab)
	(new_symbol): Constify.
	* memattr.c (mem_info_command): Constify.
	* mep-tdep.c (register_name_from_keyword): Constify.
	* mi/mi-cmd-env.c (mi_cmd_env_path, _initialize_mi_cmd_env):
	Constify.
	* mi/mi-cmd-stack.c (list_args_or_locals): Constify.
	* mi/mi-cmd-var.c (mi_cmd_var_show_attributes): Constify.
	* mi/mi-main.c (captured_mi_execute_command): Constify and add
	cast.
	(mi_execute_async_cli_command): Constify.
	* mips-tdep.c (mips_register_name): Constify.
	* mn10300-tdep.c (register_name, mn10300_generic_register_name)
	(am33_register_name, am33_2_register_name)
	* moxie-tdep.c (moxie_register_names): Constify.
	* nat/linux-osdata.c (osdata_type): Constify fields.
	* nto-tdep.c (nto_parse_redirection): Constify.
	* objc-lang.c (lookup_struct_typedef, lookup_objc_class)
	(lookup_child_selector): Constify.
	(objc_methcall::name): Constify.
	* objc-lang.h (lookup_objc_class, lookup_child_selector)
	(lookup_struct_typedef): Constify.
	* objfiles.c (pc_in_section): Constify.
	* objfiles.h (pc_in_section): Constify.
	* p-exp.y (struct token::oper): Constify.
	(yyerror): Constify.
	* p-lang.h (pascal_yyerror): Constify.
	* parser-defs.h (op_name_standard): Constify.
	(op_print::string): Constify.
	(exp_descriptor::op_name): Constify.
	* printcmd.c (print_address_symbolic): Constify.
	* psymtab.c (print_partial_symbols): Constify.
	* python/py-breakpoint.c (stop_func): Constify.
	(bppy_get_expression): Constify.
	* python/py-cmd.c (cmdpy_completer::name): Constify.
	(cmdpy_function): Constify.
	* python/py-event.c (evpy_add_attribute)
	(gdbpy_initialize_event_generic): Constify.
	* python/py-event.h (evpy_add_attribute)
	(gdbpy_initialize_event_generic): Constify.
	* python/py-evts.c (add_new_registry): Constify.
	* python/py-finishbreakpoint.c (outofscope_func): Constify.
	* python/py-framefilter.c (get_py_iter_from_func): Constify.
	* python/py-inferior.c (get_buffer): Add cast.
	* python/py-param.c (parm_constant::name): Constify.
	* python/py-unwind.c (fprint_frame_id): Constify.
	* python/python.c (gdbpy_parameter_value): Constify.
	* remote-fileio.c (remote_fio_func_map): Make 'name' const.
	* remote.c (memory_packet_config::name): Constify.
	(show_packet_config_cmd, remote_write_bytes)
	(remote_buffer_add_string):
	* reverse.c (exec_reverse_once): Constify.
	* rs6000-tdep.c (variant::name, variant::description): Constify.
	* rust-exp.y (rustyyerror): Constify.
	* rust-lang.c (rust_op_name): Constify.
	* rust-lang.h (rustyyerror): Constify.
	* serial.h (serial_ops::name): Constify.
	* sh-tdep.c (sh_sh_register_name, sh_sh3_register_name)
	(sh_sh3e_register_name, sh_sh2e_register_name)
	(sh_sh2a_register_name, sh_sh2a_nofpu_register_name)
	(sh_sh_dsp_register_name, sh_sh3_dsp_register_name)
	(sh_sh4_register_name, sh_sh4_nofpu_register_name)
	(sh_sh4al_dsp_register_name): Constify.
	* sh64-tdep.c (sh64_register_name): Constify.
	* solib-darwin.c (lookup_symbol_from_bfd): Constify.
	* spu-tdep.c (spu_register_name, info_spu_dma_cmdlist): Constify.
	* stabsread.c (patch_block_stabs, read_type_number)
	(ref_map::stabs, ref_add, process_reference)
	(symbol_reference_defined, define_symbol, define_symbol)
	(error_type, read_type, read_member_functions, read_cpp_abbrev)
	(read_one_struct_field, read_struct_fields, read_baseclasses)
	(read_tilde_fields, read_struct_type, read_array_type)
	(read_enum_type, read_sun_builtin_type, read_sun_floating_type)
	(read_huge_number, read_range_type, read_args, common_block_start)
	(find_name_end): Constify.
	* stabsread.h (common_block_start, define_symbol)
	(process_one_symbol, symbol_reference_defined, ref_add):
	* symfile.c (get_section_index, add_symbol_file_command):
	* symfile.h (get_section_index): Constify.
	* target-descriptions.c (tdesc_type::name): Constify.
	(tdesc_free_type): Add cast.
	* target.c (find_default_run_target):
	(add_deprecated_target_alias, find_default_run_target)
	(target_announce_detach): Constify.
	(do_option): Constify.
	* target.h (add_deprecated_target_alias): Constify.
	* thread.c (print_thread_info_1): Constify.
	* top.c (deprecated_readline_begin_hook, command_line_input):
	Constify.
	(init_main): Add casts.
	* top.h (handle_line_of_input): Constify.
	* tracefile-tfile.c (tfile_write_uploaded_tsv): Constify.
	* tracepoint.c (tvariables_info_1, trace_status_mi): Constify.
	(tfind_command): Rename to ...
	(tfind_command_1): ... this and constify.
	(tfind_command): New function.
	(tfind_end_command, tfind_start_command): Adjust.
	(encode_source_string): Constify.
	* tracepoint.h (encode_source_string): Constify.
	* tui/tui-data.c (tui_partial_win_by_name): Constify.
	* tui/tui-data.h (tui_partial_win_by_name): Constify.
	* tui/tui-source.c (tui_set_source_content_nil): Constify.
	* tui/tui-source.h (tui_set_source_content_nil): Constify.
	* tui/tui-win.c (parse_scrolling_args): Constify.
	* tui/tui-windata.c (tui_erase_data_content): Constify.
	* tui/tui-windata.h (tui_erase_data_content): Constify.
	* tui/tui-winsource.c (tui_erase_source_content): Constify.
	* tui/tui.c (tui_enable): Add cast.
	* utils.c (defaulted_query): Constify.
	(init_page_info): Add cast.
	(puts_debug, subset_compare): Constify.
	* utils.h (subset_compare): Constify.
	* varobj.c (varobj_format_string): Constify.
	* varobj.h (varobj_format_string): Constify.
	* vax-tdep.c (vax_register_name): Constify.
	* windows-nat.c (windows_detach): Constify.
	* xcoffread.c (process_linenos, xcoff_next_symbol_text): Constify.
	* xml-support.c (gdb_xml_end_element): Constify.
	* xml-tdesc.c (tdesc_start_reg): Constify.
	* xstormy16-tdep.c (xstormy16_register_name): Constify.
	* xtensa-tdep.c (xtensa_find_register_by_name): Constify.
	* xtensa-tdep.h (xtensa_register_t::name): Constify.

gdb/gdbserver/ChangeLog:
2017-04-05  Pedro Alves  <palves@redhat.com>

	* gdbreplay.c (sync_error): Constify.
	* linux-x86-low.c (push_opcode): Constify.
2017-04-05 19:21:37 +01:00

800 lines
24 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* XML target description support for GDB.
Copyright (C) 2006-2017 Free Software Foundation, Inc.
Contributed by CodeSourcery.
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 "defs.h"
#include "target.h"
#include "target-descriptions.h"
#include "xml-support.h"
#include "xml-tdesc.h"
#include "osabi.h"
#include "filenames.h"
/* Maximum sizes.
This is just to catch obviously wrong values. */
#define MAX_FIELD_SIZE 65536
#define MAX_FIELD_BITSIZE (MAX_FIELD_SIZE * TARGET_CHAR_BIT)
#define MAX_VECTOR_SIZE 65536
#if !defined(HAVE_LIBEXPAT)
/* Parse DOCUMENT into a target description. Or don't, since we don't have
an XML parser. */
static struct target_desc *
tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
void *fetcher_baton)
{
static int have_warned;
if (!have_warned)
{
have_warned = 1;
warning (_("Can not parse XML target description; XML support was "
"disabled at compile time"));
}
return NULL;
}
#else /* HAVE_LIBEXPAT */
/* A record of every XML description we have parsed. We never discard
old descriptions, because we never discard gdbarches. As long as we
have a gdbarch referencing this description, we want to have a copy
of it here, so that if we parse the same XML document again we can
return the same "struct target_desc *"; if they are not singletons,
then we will create unnecessary duplicate gdbarches. See
gdbarch_list_lookup_by_info. */
struct tdesc_xml_cache
{
const char *xml_document;
struct target_desc *tdesc;
};
typedef struct tdesc_xml_cache tdesc_xml_cache_s;
DEF_VEC_O(tdesc_xml_cache_s);
static VEC(tdesc_xml_cache_s) *xml_cache;
/* Callback data for target description parsing. */
struct tdesc_parsing_data
{
/* The target description we are building. */
struct target_desc *tdesc;
/* The target feature we are currently parsing, or last parsed. */
struct tdesc_feature *current_feature;
/* The register number to use for the next register we see, if
it does not have its own. This starts at zero. */
int next_regnum;
/* The struct or union we are currently parsing, or last parsed. */
struct tdesc_type *current_type;
/* The byte size of the current struct/flags type, if specified. Zero
if not specified. Flags values must specify a size. */
int current_type_size;
};
/* Handle the end of an <architecture> element and its value. */
static void
tdesc_end_arch (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, const char *body_text)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
const struct bfd_arch_info *arch;
arch = bfd_scan_arch (body_text);
if (arch == NULL)
gdb_xml_error (parser, _("Target description specified unknown "
"architecture \"%s\""), body_text);
set_tdesc_architecture (data->tdesc, arch);
}
/* Handle the end of an <osabi> element and its value. */
static void
tdesc_end_osabi (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, const char *body_text)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
enum gdb_osabi osabi;
osabi = osabi_from_tdesc_string (body_text);
if (osabi == GDB_OSABI_UNKNOWN)
warning (_("Target description specified unknown osabi \"%s\""),
body_text);
else
set_tdesc_osabi (data->tdesc, osabi);
}
/* Handle the end of a <compatible> element and its value. */
static void
tdesc_end_compatible (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, const char *body_text)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
const struct bfd_arch_info *arch;
arch = bfd_scan_arch (body_text);
tdesc_add_compatible (data->tdesc, arch);
}
/* Handle the start of a <target> element. */
static void
tdesc_start_target (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
char *version = (char *) xml_find_attribute (attributes, "version")->value;
if (strcmp (version, "1.0") != 0)
gdb_xml_error (parser,
_("Target description has unsupported version \"%s\""),
version);
}
/* Handle the start of a <feature> element. */
static void
tdesc_start_feature (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
char *name = (char *) xml_find_attribute (attributes, "name")->value;
data->current_feature = tdesc_create_feature (data->tdesc, name);
}
/* Handle the start of a <reg> element. Fill in the optional
attributes and attach it to the containing feature. */
static void
tdesc_start_reg (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
int ix = 0, length;
char *name, *group;
const char *type;
int bitsize, regnum, save_restore;
length = VEC_length (gdb_xml_value_s, attributes);
name = (char *) attrs[ix++].value;
bitsize = * (ULONGEST *) attrs[ix++].value;
if (ix < length && strcmp (attrs[ix].name, "regnum") == 0)
regnum = * (ULONGEST *) attrs[ix++].value;
else
regnum = data->next_regnum;
if (ix < length && strcmp (attrs[ix].name, "type") == 0)
type = (char *) attrs[ix++].value;
else
type = "int";
if (ix < length && strcmp (attrs[ix].name, "group") == 0)
group = (char *) attrs[ix++].value;
else
group = NULL;
if (ix < length && strcmp (attrs[ix].name, "save-restore") == 0)
save_restore = * (ULONGEST *) attrs[ix++].value;
else
save_restore = 1;
if (strcmp (type, "int") != 0
&& strcmp (type, "float") != 0
&& tdesc_named_type (data->current_feature, type) == NULL)
gdb_xml_error (parser, _("Register \"%s\" has unknown type \"%s\""),
name, type);
tdesc_create_reg (data->current_feature, name, regnum, save_restore, group,
bitsize, type);
data->next_regnum = regnum + 1;
}
/* Handle the start of a <union> element. Initialize the type and
record it with the current feature. */
static void
tdesc_start_union (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
char *id = (char *) xml_find_attribute (attributes, "id")->value;
data->current_type = tdesc_create_union (data->current_feature, id);
data->current_type_size = 0;
}
/* Handle the start of a <struct> element. Initialize the type and
record it with the current feature. */
static void
tdesc_start_struct (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
char *id = (char *) xml_find_attribute (attributes, "id")->value;
struct tdesc_type *type;
struct gdb_xml_value *attr;
type = tdesc_create_struct (data->current_feature, id);
data->current_type = type;
data->current_type_size = 0;
attr = xml_find_attribute (attributes, "size");
if (attr != NULL)
{
ULONGEST size = * (ULONGEST *) attr->value;
if (size > MAX_FIELD_SIZE)
{
gdb_xml_error (parser,
_("Struct size %s is larger than maximum (%d)"),
pulongest (size), MAX_FIELD_SIZE);
}
tdesc_set_struct_size (type, size);
data->current_type_size = size;
}
}
static void
tdesc_start_flags (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
char *id = (char *) xml_find_attribute (attributes, "id")->value;
ULONGEST size = * (ULONGEST *)
xml_find_attribute (attributes, "size")->value;
struct tdesc_type *type;
if (size > MAX_FIELD_SIZE)
{
gdb_xml_error (parser,
_("Flags size %s is larger than maximum (%d)"),
pulongest (size), MAX_FIELD_SIZE);
}
type = tdesc_create_flags (data->current_feature, id, size);
data->current_type = type;
data->current_type_size = size;
}
static void
tdesc_start_enum (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
char *id = (char *) xml_find_attribute (attributes, "id")->value;
int size = * (ULONGEST *)
xml_find_attribute (attributes, "size")->value;
struct tdesc_type *type;
if (size > MAX_FIELD_SIZE)
{
gdb_xml_error (parser,
_("Enum size %s is larger than maximum (%d)"),
pulongest (size), MAX_FIELD_SIZE);
}
type = tdesc_create_enum (data->current_feature, id, size);
data->current_type = type;
data->current_type_size = 0;
}
/* Handle the start of a <field> element. Attach the field to the
current struct, union or flags. */
static void
tdesc_start_field (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
struct gdb_xml_value *attr;
struct tdesc_type *field_type;
char *field_name, *field_type_id;
int start, end;
field_name = (char *) xml_find_attribute (attributes, "name")->value;
attr = xml_find_attribute (attributes, "type");
if (attr != NULL)
{
field_type_id = (char *) attr->value;
field_type = tdesc_named_type (data->current_feature, field_type_id);
}
else
{
field_type_id = NULL;
field_type = NULL;
}
attr = xml_find_attribute (attributes, "start");
if (attr != NULL)
{
ULONGEST ul_start = * (ULONGEST *) attr->value;
if (ul_start > MAX_FIELD_BITSIZE)
{
gdb_xml_error (parser,
_("Field start %s is larger than maximum (%d)"),
pulongest (ul_start), MAX_FIELD_BITSIZE);
}
start = ul_start;
}
else
start = -1;
attr = xml_find_attribute (attributes, "end");
if (attr != NULL)
{
ULONGEST ul_end = * (ULONGEST *) attr->value;
if (ul_end > MAX_FIELD_BITSIZE)
{
gdb_xml_error (parser,
_("Field end %s is larger than maximum (%d)"),
pulongest (ul_end), MAX_FIELD_BITSIZE);
}
end = ul_end;
}
else
end = -1;
if (start != -1)
{
struct tdesc_type *t = data->current_type;
/* Older versions of gdb can't handle elided end values.
Stick with that for now, to help ensure backward compatibility.
E.g., If a newer gdbserver is talking to an older gdb. */
if (end == -1)
gdb_xml_error (parser, _("Missing end value"));
if (data->current_type_size == 0)
gdb_xml_error (parser,
_("Bitfields must live in explicitly sized types"));
if (field_type_id != NULL
&& strcmp (field_type_id, "bool") == 0
&& start != end)
{
gdb_xml_error (parser,
_("Boolean fields must be one bit in size"));
}
if (end >= 64)
gdb_xml_error (parser,
_("Bitfield \"%s\" goes past "
"64 bits (unsupported)"),
field_name);
/* Assume that the bit numbering in XML is "lsb-zero". Most
architectures other than PowerPC use this ordering. In the
future, we can add an XML tag to indicate "msb-zero" numbering. */
if (start > end)
gdb_xml_error (parser, _("Bitfield \"%s\" has start after end"),
field_name);
if (end >= data->current_type_size * TARGET_CHAR_BIT)
gdb_xml_error (parser, _("Bitfield \"%s\" does not fit in struct"),
field_name);
if (field_type != NULL)
tdesc_add_typed_bitfield (t, field_name, start, end, field_type);
else if (start == end)
tdesc_add_flag (t, start, field_name);
else
tdesc_add_bitfield (t, field_name, start, end);
}
else if (start == -1 && end != -1)
gdb_xml_error (parser, _("End specified but not start"));
else if (field_type_id != NULL)
{
/* TDESC_TYPE_FLAGS values are explicitly sized, so the following test
catches adding non-bitfield types to flags as well. */
if (data->current_type_size != 0)
gdb_xml_error (parser,
_("Explicitly sized type cannot "
"contain non-bitfield \"%s\""),
field_name);
if (field_type == NULL)
gdb_xml_error (parser, _("Field \"%s\" references undefined "
"type \"%s\""),
field_name, field_type_id);
tdesc_add_field (data->current_type, field_name, field_type);
}
else
gdb_xml_error (parser, _("Field \"%s\" has neither type nor bit position"),
field_name);
}
/* Handle the start of an <evalue> element. Attach the value to the
current enum. */
static void
tdesc_start_enum_value (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
struct gdb_xml_value *attr;
char *field_name;
ULONGEST ul_value;
int value;
field_name = (char *) xml_find_attribute (attributes, "name")->value;
attr = xml_find_attribute (attributes, "value");
ul_value = * (ULONGEST *) attr->value;
if (ul_value > INT_MAX)
{
gdb_xml_error (parser,
_("Enum value %s is larger than maximum (%d)"),
pulongest (ul_value), INT_MAX);
}
value = ul_value;
tdesc_add_enum_value (data->current_type, value, field_name);
}
/* Handle the start of a <vector> element. Initialize the type and
record it with the current feature. */
static void
tdesc_start_vector (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
struct tdesc_type *field_type;
char *id, *field_type_id;
ULONGEST count;
id = (char *) attrs[0].value;
field_type_id = (char *) attrs[1].value;
count = * (ULONGEST *) attrs[2].value;
if (count > MAX_VECTOR_SIZE)
{
gdb_xml_error (parser,
_("Vector size %s is larger than maximum (%d)"),
pulongest (count), MAX_VECTOR_SIZE);
}
field_type = tdesc_named_type (data->current_feature, field_type_id);
if (field_type == NULL)
gdb_xml_error (parser, _("Vector \"%s\" references undefined type \"%s\""),
id, field_type_id);
tdesc_create_vector (data->current_feature, id, field_type, count);
}
/* The elements and attributes of an XML target description. */
static const struct gdb_xml_attribute field_attributes[] = {
{ "name", GDB_XML_AF_NONE, NULL, NULL },
{ "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
{ "start", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
{ "end", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static const struct gdb_xml_attribute enum_value_attributes[] = {
{ "name", GDB_XML_AF_NONE, NULL, NULL },
{ "value", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static const struct gdb_xml_element struct_union_children[] = {
{ "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE,
tdesc_start_field, NULL },
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
static const struct gdb_xml_element enum_children[] = {
{ "evalue", enum_value_attributes, NULL, GDB_XML_EF_REPEATABLE,
tdesc_start_enum_value, NULL },
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
static const struct gdb_xml_attribute reg_attributes[] = {
{ "name", GDB_XML_AF_NONE, NULL, NULL },
{ "bitsize", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
{ "regnum", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
{ "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
{ "group", GDB_XML_AF_OPTIONAL, NULL, NULL },
{ "save-restore", GDB_XML_AF_OPTIONAL,
gdb_xml_parse_attr_enum, gdb_xml_enums_boolean },
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static const struct gdb_xml_attribute struct_union_attributes[] = {
{ "id", GDB_XML_AF_NONE, NULL, NULL },
{ "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL},
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static const struct gdb_xml_attribute flags_attributes[] = {
{ "id", GDB_XML_AF_NONE, NULL, NULL },
{ "size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL},
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static const struct gdb_xml_attribute enum_attributes[] = {
{ "id", GDB_XML_AF_NONE, NULL, NULL },
{ "size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL},
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static const struct gdb_xml_attribute vector_attributes[] = {
{ "id", GDB_XML_AF_NONE, NULL, NULL },
{ "type", GDB_XML_AF_NONE, NULL, NULL },
{ "count", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static const struct gdb_xml_attribute feature_attributes[] = {
{ "name", GDB_XML_AF_NONE, NULL, NULL },
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static const struct gdb_xml_element feature_children[] = {
{ "reg", reg_attributes, NULL,
GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
tdesc_start_reg, NULL },
{ "struct", struct_union_attributes, struct_union_children,
GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
tdesc_start_struct, NULL },
{ "union", struct_union_attributes, struct_union_children,
GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
tdesc_start_union, NULL },
{ "flags", flags_attributes, struct_union_children,
GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
tdesc_start_flags, NULL },
{ "enum", enum_attributes, enum_children,
GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
tdesc_start_enum, NULL },
{ "vector", vector_attributes, NULL,
GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
tdesc_start_vector, NULL },
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
static const struct gdb_xml_attribute target_attributes[] = {
{ "version", GDB_XML_AF_NONE, NULL, NULL },
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static const struct gdb_xml_element target_children[] = {
{ "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
NULL, tdesc_end_arch },
{ "osabi", NULL, NULL, GDB_XML_EF_OPTIONAL,
NULL, tdesc_end_osabi },
{ "compatible", NULL, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
NULL, tdesc_end_compatible },
{ "feature", feature_attributes, feature_children,
GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
tdesc_start_feature, NULL },
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
static const struct gdb_xml_element tdesc_elements[] = {
{ "target", target_attributes, target_children, GDB_XML_EF_NONE,
tdesc_start_target, NULL },
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
/* Parse DOCUMENT into a target description and return it. */
static struct target_desc *
tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
void *fetcher_baton)
{
struct cleanup *back_to, *result_cleanup;
struct tdesc_parsing_data data;
struct tdesc_xml_cache *cache;
char *expanded_text;
int ix;
/* Expand all XInclude directives. */
expanded_text = xml_process_xincludes (_("target description"),
document, fetcher, fetcher_baton, 0);
if (expanded_text == NULL)
{
warning (_("Could not load XML target description; ignoring"));
return NULL;
}
/* Check for an exact match in the list of descriptions we have
previously parsed. strcmp is a slightly inefficient way to
do this; an SHA-1 checksum would work as well. */
for (ix = 0; VEC_iterate (tdesc_xml_cache_s, xml_cache, ix, cache); ix++)
if (strcmp (cache->xml_document, expanded_text) == 0)
{
xfree (expanded_text);
return cache->tdesc;
}
back_to = make_cleanup (null_cleanup, NULL);
memset (&data, 0, sizeof (struct tdesc_parsing_data));
data.tdesc = allocate_target_description ();
result_cleanup = make_cleanup_free_target_description (data.tdesc);
make_cleanup (xfree, expanded_text);
if (gdb_xml_parse_quick (_("target description"), "gdb-target.dtd",
tdesc_elements, expanded_text, &data) == 0)
{
/* Parsed successfully. */
struct tdesc_xml_cache new_cache;
new_cache.xml_document = expanded_text;
new_cache.tdesc = data.tdesc;
VEC_safe_push (tdesc_xml_cache_s, xml_cache, &new_cache);
discard_cleanups (result_cleanup);
do_cleanups (back_to);
return data.tdesc;
}
else
{
warning (_("Could not load XML target description; ignoring"));
do_cleanups (back_to);
return NULL;
}
}
#endif /* HAVE_LIBEXPAT */
/* Read an XML target description from FILENAME. Parse it, and return
the parsed description. */
const struct target_desc *
file_read_description_xml (const char *filename)
{
struct target_desc *tdesc;
char *tdesc_str;
struct cleanup *back_to;
tdesc_str = xml_fetch_content_from_file (filename, NULL);
if (tdesc_str == NULL)
{
warning (_("Could not open \"%s\""), filename);
return NULL;
}
back_to = make_cleanup (xfree, tdesc_str);
tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file,
(void *) ldirname (filename).c_str ());
do_cleanups (back_to);
return tdesc;
}
/* Read a string representation of available features from the target,
using TARGET_OBJECT_AVAILABLE_FEATURES. The returned string is
malloc allocated and NUL-terminated. NAME should be a non-NULL
string identifying the XML document we want; the top level document
is "target.xml". Other calls may be performed for the DTD or
for <xi:include>. */
static char *
fetch_available_features_from_target (const char *name, void *baton_)
{
struct target_ops *ops = (struct target_ops *) baton_;
/* Read this object as a string. This ensures that a NUL
terminator is added. */
return target_read_stralloc (ops,
TARGET_OBJECT_AVAILABLE_FEATURES,
name);
}
/* Read an XML target description using OPS. Parse it, and return the
parsed description. */
const struct target_desc *
target_read_description_xml (struct target_ops *ops)
{
struct target_desc *tdesc;
char *tdesc_str;
struct cleanup *back_to;
tdesc_str = fetch_available_features_from_target ("target.xml", ops);
if (tdesc_str == NULL)
return NULL;
back_to = make_cleanup (xfree, tdesc_str);
tdesc = tdesc_parse_xml (tdesc_str,
fetch_available_features_from_target,
ops);
do_cleanups (back_to);
return tdesc;
}
/* Fetches an XML target description using OPS, processing
includes, but not parsing it. Used to dump whole tdesc
as a single XML file. */
char *
target_fetch_description_xml (struct target_ops *ops)
{
#if !defined(HAVE_LIBEXPAT)
static int have_warned;
if (!have_warned)
{
have_warned = 1;
warning (_("Can not fetch XML target description; XML support was "
"disabled at compile time"));
}
return NULL;
#else
struct target_desc *tdesc;
char *tdesc_str;
char *expanded_text;
struct cleanup *back_to;
tdesc_str = fetch_available_features_from_target ("target.xml", ops);
if (tdesc_str == NULL)
return NULL;
back_to = make_cleanup (xfree, tdesc_str);
expanded_text = xml_process_xincludes (_("target description"),
tdesc_str,
fetch_available_features_from_target, ops, 0);
do_cleanups (back_to);
if (expanded_text == NULL)
{
warning (_("Could not load XML target description; ignoring"));
return NULL;
}
return expanded_text;
#endif
}