From: Tom Tromey Date: Tue, 14 Dec 2021 23:33:56 +0000 (-0700) Subject: Move ordinary gdbarch code to arch-utils X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=74fcd19c514f7beb24ab842381453efb74a8ac58;p=binutils-gdb.git Move ordinary gdbarch code to arch-utils While I think it makes sense to generate gdbarch.c, at the same time I think it is better for ordinary code to be editable in a C file -- not as a hunk of C code embedded in the generator. This patch moves this sort of code out of gdbarch.sh and gdbarch.c and into arch-utils.c, then has arch-utils.c include gdbarch.c. --- diff --git a/gdb/Makefile.in b/gdb/Makefile.in index f2966cf6c00..d9db4245f40 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1075,7 +1075,6 @@ COMMON_SFILES = \ gdb_bfd.c \ gdb_obstack.c \ gdb_regex.c \ - gdbarch.c \ gdbtypes.c \ gmp-utils.c \ gnu-v2-abi.c \ diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 6c6dca22d63..4442ec9b82f 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -31,6 +31,11 @@ #include "objfiles.h" #include "language.h" #include "symtab.h" +#include "dummy-frame.h" +#include "frame-unwind.h" +#include "reggroups.h" +#include "auxv.h" +#include "observable.h" #include "gdbsupport/version.h" @@ -1083,6 +1088,482 @@ default_read_core_file_mappings { } +/* Static function declarations */ + +static void alloc_gdbarch_data (struct gdbarch *); + +/* Non-zero if we want to trace architecture code. */ + +#ifndef GDBARCH_DEBUG +#define GDBARCH_DEBUG 0 +#endif +unsigned int gdbarch_debug = GDBARCH_DEBUG; +static void +show_gdbarch_debug (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Architecture debugging is %s.\n"), value); +} + +static const char * +pformat (const struct floatformat **format) +{ + if (format == NULL) + return "(null)"; + else + /* Just print out one of them - this is only for diagnostics. */ + return format[0]->name; +} + +static const char * +pstring (const char *string) +{ + if (string == NULL) + return "(null)"; + return string; +} + +static const char * +pstring_ptr (char **string) +{ + if (string == NULL || *string == NULL) + return "(null)"; + return *string; +} + +/* Helper function to print a list of strings, represented as "const + char *const *". The list is printed comma-separated. */ + +static const char * +pstring_list (const char *const *list) +{ + static char ret[100]; + const char *const *p; + size_t offset = 0; + + if (list == NULL) + return "(null)"; + + ret[0] = '\0'; + for (p = list; *p != NULL && offset < sizeof (ret); ++p) + { + size_t s = xsnprintf (ret + offset, sizeof (ret) - offset, "%s, ", *p); + offset += 2 + s; + } + + if (offset > 0) + { + gdb_assert (offset - 2 < sizeof (ret)); + ret[offset - 2] = '\0'; + } + + return ret; +} + +#include "gdbarch.c" + +obstack *gdbarch_obstack (gdbarch *arch) +{ + return arch->obstack; +} + +/* See gdbarch.h. */ + +char * +gdbarch_obstack_strdup (struct gdbarch *arch, const char *string) +{ + return obstack_strdup (arch->obstack, string); +} + + +/* Free a gdbarch struct. This should never happen in normal + operation --- once you've created a gdbarch, you keep it around. + However, if an architecture's init function encounters an error + building the structure, it may need to clean up a partially + constructed gdbarch. */ + +void +gdbarch_free (struct gdbarch *arch) +{ + struct obstack *obstack; + + gdb_assert (arch != NULL); + gdb_assert (!arch->initialized_p); + obstack = arch->obstack; + obstack_free (obstack, 0); /* Includes the ARCH. */ + xfree (obstack); +} + +struct gdbarch_tdep * +gdbarch_tdep (struct gdbarch *gdbarch) +{ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_tdep called\n"); + return gdbarch->tdep; +} + +/* Keep a registry of per-architecture data-pointers required by GDB + modules. */ + +struct gdbarch_data +{ + unsigned index; + int init_p; + gdbarch_data_pre_init_ftype *pre_init; + gdbarch_data_post_init_ftype *post_init; +}; + +struct gdbarch_data_registration +{ + struct gdbarch_data *data; + struct gdbarch_data_registration *next; +}; + +struct gdbarch_data_registry +{ + unsigned nr; + struct gdbarch_data_registration *registrations; +}; + +static struct gdbarch_data_registry gdbarch_data_registry = +{ + 0, NULL, +}; + +static struct gdbarch_data * +gdbarch_data_register (gdbarch_data_pre_init_ftype *pre_init, + gdbarch_data_post_init_ftype *post_init) +{ + struct gdbarch_data_registration **curr; + + /* Append the new registration. */ + for (curr = &gdbarch_data_registry.registrations; + (*curr) != NULL; + curr = &(*curr)->next); + (*curr) = XNEW (struct gdbarch_data_registration); + (*curr)->next = NULL; + (*curr)->data = XNEW (struct gdbarch_data); + (*curr)->data->index = gdbarch_data_registry.nr++; + (*curr)->data->pre_init = pre_init; + (*curr)->data->post_init = post_init; + (*curr)->data->init_p = 1; + return (*curr)->data; +} + +struct gdbarch_data * +gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *pre_init) +{ + return gdbarch_data_register (pre_init, NULL); +} + +struct gdbarch_data * +gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *post_init) +{ + return gdbarch_data_register (NULL, post_init); +} + +/* Create/delete the gdbarch data vector. */ + +static void +alloc_gdbarch_data (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch->data == NULL); + gdbarch->nr_data = gdbarch_data_registry.nr; + gdbarch->data = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, void *); +} + +/* Return the current value of the specified per-architecture + data-pointer. */ + +void * +gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data) +{ + gdb_assert (data->index < gdbarch->nr_data); + if (gdbarch->data[data->index] == NULL) + { + /* The data-pointer isn't initialized, call init() to get a + value. */ + if (data->pre_init != NULL) + /* Mid architecture creation: pass just the obstack, and not + the entire architecture, as that way it isn't possible for + pre-init code to refer to undefined architecture + fields. */ + gdbarch->data[data->index] = data->pre_init (gdbarch->obstack); + else if (gdbarch->initialized_p + && data->post_init != NULL) + /* Post architecture creation: pass the entire architecture + (as all fields are valid), but be careful to also detect + recursive references. */ + { + gdb_assert (data->init_p); + data->init_p = 0; + gdbarch->data[data->index] = data->post_init (gdbarch); + data->init_p = 1; + } + else + internal_error (__FILE__, __LINE__, + _("gdbarch post-init data field can only be used " + "after gdbarch is fully initialised")); + gdb_assert (gdbarch->data[data->index] != NULL); + } + return gdbarch->data[data->index]; +} + + +/* Keep a registry of the architectures known by GDB. */ + +struct gdbarch_registration +{ + enum bfd_architecture bfd_architecture; + gdbarch_init_ftype *init; + gdbarch_dump_tdep_ftype *dump_tdep; + struct gdbarch_list *arches; + struct gdbarch_registration *next; +}; + +static struct gdbarch_registration *gdbarch_registry = NULL; + +std::vector +gdbarch_printable_names () +{ + /* Accumulate a list of names based on the registed list of + architectures. */ + std::vector arches; + + for (gdbarch_registration *rego = gdbarch_registry; + rego != nullptr; + rego = rego->next) + { + const struct bfd_arch_info *ap + = bfd_lookup_arch (rego->bfd_architecture, 0); + if (ap == nullptr) + internal_error (__FILE__, __LINE__, + _("gdbarch_architecture_names: multi-arch unknown")); + do + { + arches.push_back (ap->printable_name); + ap = ap->next; + } + while (ap != NULL); + } + + return arches; +} + + +void +gdbarch_register (enum bfd_architecture bfd_architecture, + gdbarch_init_ftype *init, + gdbarch_dump_tdep_ftype *dump_tdep) +{ + struct gdbarch_registration **curr; + const struct bfd_arch_info *bfd_arch_info; + + /* Check that BFD recognizes this architecture */ + bfd_arch_info = bfd_lookup_arch (bfd_architecture, 0); + if (bfd_arch_info == NULL) + { + internal_error (__FILE__, __LINE__, + _("gdbarch: Attempt to register " + "unknown architecture (%d)"), + bfd_architecture); + } + /* Check that we haven't seen this architecture before. */ + for (curr = &gdbarch_registry; + (*curr) != NULL; + curr = &(*curr)->next) + { + if (bfd_architecture == (*curr)->bfd_architecture) + internal_error (__FILE__, __LINE__, + _("gdbarch: Duplicate registration " + "of architecture (%s)"), + bfd_arch_info->printable_name); + } + /* log it */ + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "register_gdbarch_init (%s, %s)\n", + bfd_arch_info->printable_name, + host_address_to_string (init)); + /* Append it */ + (*curr) = XNEW (struct gdbarch_registration); + (*curr)->bfd_architecture = bfd_architecture; + (*curr)->init = init; + (*curr)->dump_tdep = dump_tdep; + (*curr)->arches = NULL; + (*curr)->next = NULL; +} + +void +register_gdbarch_init (enum bfd_architecture bfd_architecture, + gdbarch_init_ftype *init) +{ + gdbarch_register (bfd_architecture, init, NULL); +} + + +/* Look for an architecture using gdbarch_info. */ + +struct gdbarch_list * +gdbarch_list_lookup_by_info (struct gdbarch_list *arches, + const struct gdbarch_info *info) +{ + for (; arches != NULL; arches = arches->next) + { + if (info->bfd_arch_info != arches->gdbarch->bfd_arch_info) + continue; + if (info->byte_order != arches->gdbarch->byte_order) + continue; + if (info->osabi != arches->gdbarch->osabi) + continue; + if (info->target_desc != arches->gdbarch->target_desc) + continue; + return arches; + } + return NULL; +} + + +/* Find an architecture that matches the specified INFO. Create a new + architecture if needed. Return that new architecture. */ + +struct gdbarch * +gdbarch_find_by_info (struct gdbarch_info info) +{ + struct gdbarch *new_gdbarch; + struct gdbarch_registration *rego; + + /* Fill in missing parts of the INFO struct using a number of + sources: "set ..."; INFOabfd supplied; and the global + defaults. */ + gdbarch_info_fill (&info); + + /* Must have found some sort of architecture. */ + gdb_assert (info.bfd_arch_info != NULL); + + if (gdbarch_debug) + { + fprintf_unfiltered (gdb_stdlog, + "gdbarch_find_by_info: info.bfd_arch_info %s\n", + (info.bfd_arch_info != NULL + ? info.bfd_arch_info->printable_name + : "(null)")); + fprintf_unfiltered (gdb_stdlog, + "gdbarch_find_by_info: info.byte_order %d (%s)\n", + info.byte_order, + (info.byte_order == BFD_ENDIAN_BIG ? "big" + : info.byte_order == BFD_ENDIAN_LITTLE ? "little" + : "default")); + fprintf_unfiltered (gdb_stdlog, + "gdbarch_find_by_info: info.osabi %d (%s)\n", + info.osabi, gdbarch_osabi_name (info.osabi)); + fprintf_unfiltered (gdb_stdlog, + "gdbarch_find_by_info: info.abfd %s\n", + host_address_to_string (info.abfd)); + } + + /* Find the tdep code that knows about this architecture. */ + for (rego = gdbarch_registry; + rego != NULL; + rego = rego->next) + if (rego->bfd_architecture == info.bfd_arch_info->arch) + break; + if (rego == NULL) + { + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " + "No matching architecture\n"); + return 0; + } + + /* Ask the tdep code for an architecture that matches "info". */ + new_gdbarch = rego->init (info, rego->arches); + + /* Did the tdep code like it? No. Reject the change and revert to + the old architecture. */ + if (new_gdbarch == NULL) + { + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " + "Target rejected architecture\n"); + return NULL; + } + + /* Is this a pre-existing architecture (as determined by already + being initialized)? Move it to the front of the architecture + list (keeping the list sorted Most Recently Used). */ + if (new_gdbarch->initialized_p) + { + struct gdbarch_list **list; + struct gdbarch_list *self; + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " + "Previous architecture %s (%s) selected\n", + host_address_to_string (new_gdbarch), + new_gdbarch->bfd_arch_info->printable_name); + /* Find the existing arch in the list. */ + for (list = ®o->arches; + (*list) != NULL && (*list)->gdbarch != new_gdbarch; + list = &(*list)->next); + /* It had better be in the list of architectures. */ + gdb_assert ((*list) != NULL && (*list)->gdbarch == new_gdbarch); + /* Unlink SELF. */ + self = (*list); + (*list) = self->next; + /* Insert SELF at the front. */ + self->next = rego->arches; + rego->arches = self; + /* Return it. */ + return new_gdbarch; + } + + /* It's a new architecture. */ + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " + "New architecture %s (%s) selected\n", + host_address_to_string (new_gdbarch), + new_gdbarch->bfd_arch_info->printable_name); + + /* Insert the new architecture into the front of the architecture + list (keep the list sorted Most Recently Used). */ + { + struct gdbarch_list *self = XNEW (struct gdbarch_list); + self->next = rego->arches; + self->gdbarch = new_gdbarch; + rego->arches = self; + } + + /* Check that the newly installed architecture is valid. Plug in + any post init values. */ + new_gdbarch->dump_tdep = rego->dump_tdep; + verify_gdbarch (new_gdbarch); + new_gdbarch->initialized_p = 1; + + if (gdbarch_debug) + gdbarch_dump (new_gdbarch, gdb_stdlog); + + return new_gdbarch; +} + +/* Make the specified architecture current. */ + +void +set_target_gdbarch (struct gdbarch *new_gdbarch) +{ + gdb_assert (new_gdbarch != NULL); + gdb_assert (new_gdbarch->initialized_p); + current_inferior ()->gdbarch = new_gdbarch; + gdb::observers::architecture_changed.notify (new_gdbarch); + registers_changed (); +} + +/* Return the current inferior's arch. */ + +struct gdbarch * +target_gdbarch (void) +{ + return current_inferior ()->gdbarch; +} + void _initialize_gdbarch_utils (); void _initialize_gdbarch_utils () @@ -1093,4 +1574,11 @@ _initialize_gdbarch_utils () _("Show endianness of target."), NULL, set_endian, show_endian, &setlist, &showlist); + add_setshow_zuinteger_cmd ("arch", class_maintenance, &gdbarch_debug, _("\ +Set architecture debugging."), _("\ +Show architecture debugging."), _("\ +When non-zero, architecture debugging is enabled."), + NULL, + show_gdbarch_debug, + &setdebuglist, &showdebuglist); } diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 689187f8b1e..f4460a6e616 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -23,97 +23,6 @@ /* This file was created with the aid of ``gdbarch.sh''. */ -#include "defs.h" -#include "arch-utils.h" - -#include "gdbcmd.h" -#include "inferior.h" -#include "symcat.h" - -#include "floatformat.h" -#include "reggroups.h" -#include "osabi.h" -#include "gdb_obstack.h" -#include "observable.h" -#include "regcache.h" -#include "objfiles.h" -#include "auxv.h" -#include "frame-unwind.h" -#include "dummy-frame.h" - -/* Static function declarations */ - -static void alloc_gdbarch_data (struct gdbarch *); - -/* Non-zero if we want to trace architecture code. */ - -#ifndef GDBARCH_DEBUG -#define GDBARCH_DEBUG 0 -#endif -unsigned int gdbarch_debug = GDBARCH_DEBUG; -static void -show_gdbarch_debug (struct ui_file *file, int from_tty, - struct cmd_list_element *c, const char *value) -{ - fprintf_filtered (file, _("Architecture debugging is %s.\n"), value); -} - -static const char * -pformat (const struct floatformat **format) -{ - if (format == NULL) - return "(null)"; - else - /* Just print out one of them - this is only for diagnostics. */ - return format[0]->name; -} - -static const char * -pstring (const char *string) -{ - if (string == NULL) - return "(null)"; - return string; -} - -static const char * -pstring_ptr (char **string) -{ - if (string == NULL || *string == NULL) - return "(null)"; - return *string; -} - -/* Helper function to print a list of strings, represented as "const - char *const *". The list is printed comma-separated. */ - -static const char * -pstring_list (const char *const *list) -{ - static char ret[100]; - const char *const *p; - size_t offset = 0; - - if (list == NULL) - return "(null)"; - - ret[0] = '\0'; - for (p = list; *p != NULL && offset < sizeof (ret); ++p) - { - size_t s = xsnprintf (ret + offset, sizeof (ret) - offset, "%s, ", *p); - offset += 2 + s; - } - - if (offset > 0) - { - gdb_assert (offset - 2 < sizeof (ret)); - ret[offset - 2] = '\0'; - } - - return ret; -} - - /* Maintain the struct gdbarch object. */ struct gdbarch @@ -490,39 +399,6 @@ gdbarch_alloc (const struct gdbarch_info *info, -obstack *gdbarch_obstack (gdbarch *arch) -{ - return arch->obstack; -} - -/* See gdbarch.h. */ - -char * -gdbarch_obstack_strdup (struct gdbarch *arch, const char *string) -{ - return obstack_strdup (arch->obstack, string); -} - - -/* Free a gdbarch struct. This should never happen in normal - operation --- once you've created a gdbarch, you keep it around. - However, if an architecture's init function encounters an error - building the structure, it may need to clean up a partially - constructed gdbarch. */ - -void -gdbarch_free (struct gdbarch *arch) -{ - struct obstack *obstack; - - gdb_assert (arch != NULL); - gdb_assert (!arch->initialized_p); - obstack = arch->obstack; - obstack_free (obstack, 0); /* Includes the ARCH. */ - xfree (obstack); -} - - /* Ensure that all values in a GDBARCH are reasonable. */ static void @@ -1565,14 +1441,6 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) gdbarch->dump_tdep (gdbarch, file); } -struct gdbarch_tdep * -gdbarch_tdep (struct gdbarch *gdbarch) -{ - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_tdep called\n"); - return gdbarch->tdep; -} - const struct bfd_arch_info * gdbarch_bfd_arch_info (struct gdbarch *gdbarch) @@ -5426,379 +5294,3 @@ set_gdbarch_read_core_file_mappings (struct gdbarch *gdbarch, { gdbarch->read_core_file_mappings = read_core_file_mappings; } - - -/* Keep a registry of per-architecture data-pointers required by GDB - modules. */ - -struct gdbarch_data -{ - unsigned index; - int init_p; - gdbarch_data_pre_init_ftype *pre_init; - gdbarch_data_post_init_ftype *post_init; -}; - -struct gdbarch_data_registration -{ - struct gdbarch_data *data; - struct gdbarch_data_registration *next; -}; - -struct gdbarch_data_registry -{ - unsigned nr; - struct gdbarch_data_registration *registrations; -}; - -static struct gdbarch_data_registry gdbarch_data_registry = -{ - 0, NULL, -}; - -static struct gdbarch_data * -gdbarch_data_register (gdbarch_data_pre_init_ftype *pre_init, - gdbarch_data_post_init_ftype *post_init) -{ - struct gdbarch_data_registration **curr; - - /* Append the new registration. */ - for (curr = &gdbarch_data_registry.registrations; - (*curr) != NULL; - curr = &(*curr)->next); - (*curr) = XNEW (struct gdbarch_data_registration); - (*curr)->next = NULL; - (*curr)->data = XNEW (struct gdbarch_data); - (*curr)->data->index = gdbarch_data_registry.nr++; - (*curr)->data->pre_init = pre_init; - (*curr)->data->post_init = post_init; - (*curr)->data->init_p = 1; - return (*curr)->data; -} - -struct gdbarch_data * -gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *pre_init) -{ - return gdbarch_data_register (pre_init, NULL); -} - -struct gdbarch_data * -gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *post_init) -{ - return gdbarch_data_register (NULL, post_init); -} - -/* Create/delete the gdbarch data vector. */ - -static void -alloc_gdbarch_data (struct gdbarch *gdbarch) -{ - gdb_assert (gdbarch->data == NULL); - gdbarch->nr_data = gdbarch_data_registry.nr; - gdbarch->data = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, void *); -} - -/* Return the current value of the specified per-architecture - data-pointer. */ - -void * -gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data) -{ - gdb_assert (data->index < gdbarch->nr_data); - if (gdbarch->data[data->index] == NULL) - { - /* The data-pointer isn't initialized, call init() to get a - value. */ - if (data->pre_init != NULL) - /* Mid architecture creation: pass just the obstack, and not - the entire architecture, as that way it isn't possible for - pre-init code to refer to undefined architecture - fields. */ - gdbarch->data[data->index] = data->pre_init (gdbarch->obstack); - else if (gdbarch->initialized_p - && data->post_init != NULL) - /* Post architecture creation: pass the entire architecture - (as all fields are valid), but be careful to also detect - recursive references. */ - { - gdb_assert (data->init_p); - data->init_p = 0; - gdbarch->data[data->index] = data->post_init (gdbarch); - data->init_p = 1; - } - else - internal_error (__FILE__, __LINE__, - _("gdbarch post-init data field can only be used " - "after gdbarch is fully initialised")); - gdb_assert (gdbarch->data[data->index] != NULL); - } - return gdbarch->data[data->index]; -} - - -/* Keep a registry of the architectures known by GDB. */ - -struct gdbarch_registration -{ - enum bfd_architecture bfd_architecture; - gdbarch_init_ftype *init; - gdbarch_dump_tdep_ftype *dump_tdep; - struct gdbarch_list *arches; - struct gdbarch_registration *next; -}; - -static struct gdbarch_registration *gdbarch_registry = NULL; - -std::vector -gdbarch_printable_names () -{ - /* Accumulate a list of names based on the registed list of - architectures. */ - std::vector arches; - - for (gdbarch_registration *rego = gdbarch_registry; - rego != nullptr; - rego = rego->next) - { - const struct bfd_arch_info *ap - = bfd_lookup_arch (rego->bfd_architecture, 0); - if (ap == nullptr) - internal_error (__FILE__, __LINE__, - _("gdbarch_architecture_names: multi-arch unknown")); - do - { - arches.push_back (ap->printable_name); - ap = ap->next; - } - while (ap != NULL); - } - - return arches; -} - - -void -gdbarch_register (enum bfd_architecture bfd_architecture, - gdbarch_init_ftype *init, - gdbarch_dump_tdep_ftype *dump_tdep) -{ - struct gdbarch_registration **curr; - const struct bfd_arch_info *bfd_arch_info; - - /* Check that BFD recognizes this architecture */ - bfd_arch_info = bfd_lookup_arch (bfd_architecture, 0); - if (bfd_arch_info == NULL) - { - internal_error (__FILE__, __LINE__, - _("gdbarch: Attempt to register " - "unknown architecture (%d)"), - bfd_architecture); - } - /* Check that we haven't seen this architecture before. */ - for (curr = &gdbarch_registry; - (*curr) != NULL; - curr = &(*curr)->next) - { - if (bfd_architecture == (*curr)->bfd_architecture) - internal_error (__FILE__, __LINE__, - _("gdbarch: Duplicate registration " - "of architecture (%s)"), - bfd_arch_info->printable_name); - } - /* log it */ - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "register_gdbarch_init (%s, %s)\n", - bfd_arch_info->printable_name, - host_address_to_string (init)); - /* Append it */ - (*curr) = XNEW (struct gdbarch_registration); - (*curr)->bfd_architecture = bfd_architecture; - (*curr)->init = init; - (*curr)->dump_tdep = dump_tdep; - (*curr)->arches = NULL; - (*curr)->next = NULL; -} - -void -register_gdbarch_init (enum bfd_architecture bfd_architecture, - gdbarch_init_ftype *init) -{ - gdbarch_register (bfd_architecture, init, NULL); -} - - -/* Look for an architecture using gdbarch_info. */ - -struct gdbarch_list * -gdbarch_list_lookup_by_info (struct gdbarch_list *arches, - const struct gdbarch_info *info) -{ - for (; arches != NULL; arches = arches->next) - { - if (info->bfd_arch_info != arches->gdbarch->bfd_arch_info) - continue; - if (info->byte_order != arches->gdbarch->byte_order) - continue; - if (info->osabi != arches->gdbarch->osabi) - continue; - if (info->target_desc != arches->gdbarch->target_desc) - continue; - return arches; - } - return NULL; -} - - -/* Find an architecture that matches the specified INFO. Create a new - architecture if needed. Return that new architecture. */ - -struct gdbarch * -gdbarch_find_by_info (struct gdbarch_info info) -{ - struct gdbarch *new_gdbarch; - struct gdbarch_registration *rego; - - /* Fill in missing parts of the INFO struct using a number of - sources: "set ..."; INFOabfd supplied; and the global - defaults. */ - gdbarch_info_fill (&info); - - /* Must have found some sort of architecture. */ - gdb_assert (info.bfd_arch_info != NULL); - - if (gdbarch_debug) - { - fprintf_unfiltered (gdb_stdlog, - "gdbarch_find_by_info: info.bfd_arch_info %s\n", - (info.bfd_arch_info != NULL - ? info.bfd_arch_info->printable_name - : "(null)")); - fprintf_unfiltered (gdb_stdlog, - "gdbarch_find_by_info: info.byte_order %d (%s)\n", - info.byte_order, - (info.byte_order == BFD_ENDIAN_BIG ? "big" - : info.byte_order == BFD_ENDIAN_LITTLE ? "little" - : "default")); - fprintf_unfiltered (gdb_stdlog, - "gdbarch_find_by_info: info.osabi %d (%s)\n", - info.osabi, gdbarch_osabi_name (info.osabi)); - fprintf_unfiltered (gdb_stdlog, - "gdbarch_find_by_info: info.abfd %s\n", - host_address_to_string (info.abfd)); - } - - /* Find the tdep code that knows about this architecture. */ - for (rego = gdbarch_registry; - rego != NULL; - rego = rego->next) - if (rego->bfd_architecture == info.bfd_arch_info->arch) - break; - if (rego == NULL) - { - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " - "No matching architecture\n"); - return 0; - } - - /* Ask the tdep code for an architecture that matches "info". */ - new_gdbarch = rego->init (info, rego->arches); - - /* Did the tdep code like it? No. Reject the change and revert to - the old architecture. */ - if (new_gdbarch == NULL) - { - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " - "Target rejected architecture\n"); - return NULL; - } - - /* Is this a pre-existing architecture (as determined by already - being initialized)? Move it to the front of the architecture - list (keeping the list sorted Most Recently Used). */ - if (new_gdbarch->initialized_p) - { - struct gdbarch_list **list; - struct gdbarch_list *self; - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " - "Previous architecture %s (%s) selected\n", - host_address_to_string (new_gdbarch), - new_gdbarch->bfd_arch_info->printable_name); - /* Find the existing arch in the list. */ - for (list = ®o->arches; - (*list) != NULL && (*list)->gdbarch != new_gdbarch; - list = &(*list)->next); - /* It had better be in the list of architectures. */ - gdb_assert ((*list) != NULL && (*list)->gdbarch == new_gdbarch); - /* Unlink SELF. */ - self = (*list); - (*list) = self->next; - /* Insert SELF at the front. */ - self->next = rego->arches; - rego->arches = self; - /* Return it. */ - return new_gdbarch; - } - - /* It's a new architecture. */ - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " - "New architecture %s (%s) selected\n", - host_address_to_string (new_gdbarch), - new_gdbarch->bfd_arch_info->printable_name); - - /* Insert the new architecture into the front of the architecture - list (keep the list sorted Most Recently Used). */ - { - struct gdbarch_list *self = XNEW (struct gdbarch_list); - self->next = rego->arches; - self->gdbarch = new_gdbarch; - rego->arches = self; - } - - /* Check that the newly installed architecture is valid. Plug in - any post init values. */ - new_gdbarch->dump_tdep = rego->dump_tdep; - verify_gdbarch (new_gdbarch); - new_gdbarch->initialized_p = 1; - - if (gdbarch_debug) - gdbarch_dump (new_gdbarch, gdb_stdlog); - - return new_gdbarch; -} - -/* Make the specified architecture current. */ - -void -set_target_gdbarch (struct gdbarch *new_gdbarch) -{ - gdb_assert (new_gdbarch != NULL); - gdb_assert (new_gdbarch->initialized_p); - current_inferior ()->gdbarch = new_gdbarch; - gdb::observers::architecture_changed.notify (new_gdbarch); - registers_changed (); -} - -/* Return the current inferior's arch. */ - -struct gdbarch * -target_gdbarch (void) -{ - return current_inferior ()->gdbarch; -} - -void _initialize_gdbarch (); -void -_initialize_gdbarch () -{ - add_setshow_zuinteger_cmd ("arch", class_maintenance, &gdbarch_debug, _("\ -Set architecture debugging."), _("\ -Show architecture debugging."), _("\ -When non-zero, architecture debugging is enabled."), - NULL, - show_gdbarch_debug, - &setdebuglist, &showdebuglist); -} diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 83a359b4f59..0d63462d7bb 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -1729,99 +1729,6 @@ rm -f new-gdbarch.h exec > new-gdbarch.c copyright -cat <name; -} - -static const char * -pstring (const char *string) -{ - if (string == NULL) - return "(null)"; - return string; -} - -static const char * -pstring_ptr (char **string) -{ - if (string == NULL || *string == NULL) - return "(null)"; - return *string; -} - -/* Helper function to print a list of strings, represented as "const - char *const *". The list is printed comma-separated. */ - -static const char * -pstring_list (const char *const *list) -{ - static char ret[100]; - const char *const *p; - size_t offset = 0; - - if (list == NULL) - return "(null)"; - - ret[0] = '\0'; - for (p = list; *p != NULL && offset < sizeof (ret); ++p) - { - size_t s = xsnprintf (ret + offset, sizeof (ret) - offset, "%s, ", *p); - offset += 2 + s; - } - - if (offset > 0) - { - gdb_assert (offset - 2 < sizeof (ret)); - ret[offset - 2] = '\0'; - } - - return ret; -} - -EOF # gdbarch open the gdbarch object printf "\n" @@ -1944,41 +1851,6 @@ EOF # Free a gdbarch struct. printf "\n" -printf "\n" -cat <obstack; -} - -/* See gdbarch.h. */ - -char * -gdbarch_obstack_strdup (struct gdbarch *arch, const char *string) -{ - return obstack_strdup (arch->obstack, string); -} - - -/* Free a gdbarch struct. This should never happen in normal - operation --- once you've created a gdbarch, you keep it around. - However, if an architecture's init function encounters an error - building the structure, it may need to clean up a partially - constructed gdbarch. */ - -void -gdbarch_free (struct gdbarch *arch) -{ - struct obstack *obstack; - - gdb_assert (arch != NULL); - gdb_assert (!arch->initialized_p); - obstack = arch->obstack; - obstack_free (obstack, 0); /* Includes the ARCH. */ - xfree (obstack); -} -EOF # verify a new architecture cat <= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_tdep called\\n"); - return gdbarch->tdep; -} -EOF printf "\n" function_list | while do_read do @@ -2218,386 +2079,6 @@ do fi done -# All the trailing guff -cat <next); - (*curr) = XNEW (struct gdbarch_data_registration); - (*curr)->next = NULL; - (*curr)->data = XNEW (struct gdbarch_data); - (*curr)->data->index = gdbarch_data_registry.nr++; - (*curr)->data->pre_init = pre_init; - (*curr)->data->post_init = post_init; - (*curr)->data->init_p = 1; - return (*curr)->data; -} - -struct gdbarch_data * -gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *pre_init) -{ - return gdbarch_data_register (pre_init, NULL); -} - -struct gdbarch_data * -gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *post_init) -{ - return gdbarch_data_register (NULL, post_init); -} - -/* Create/delete the gdbarch data vector. */ - -static void -alloc_gdbarch_data (struct gdbarch *gdbarch) -{ - gdb_assert (gdbarch->data == NULL); - gdbarch->nr_data = gdbarch_data_registry.nr; - gdbarch->data = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, void *); -} - -/* Return the current value of the specified per-architecture - data-pointer. */ - -void * -gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data) -{ - gdb_assert (data->index < gdbarch->nr_data); - if (gdbarch->data[data->index] == NULL) - { - /* The data-pointer isn't initialized, call init() to get a - value. */ - if (data->pre_init != NULL) - /* Mid architecture creation: pass just the obstack, and not - the entire architecture, as that way it isn't possible for - pre-init code to refer to undefined architecture - fields. */ - gdbarch->data[data->index] = data->pre_init (gdbarch->obstack); - else if (gdbarch->initialized_p - && data->post_init != NULL) - /* Post architecture creation: pass the entire architecture - (as all fields are valid), but be careful to also detect - recursive references. */ - { - gdb_assert (data->init_p); - data->init_p = 0; - gdbarch->data[data->index] = data->post_init (gdbarch); - data->init_p = 1; - } - else - internal_error (__FILE__, __LINE__, - _("gdbarch post-init data field can only be used " - "after gdbarch is fully initialised")); - gdb_assert (gdbarch->data[data->index] != NULL); - } - return gdbarch->data[data->index]; -} - - -/* Keep a registry of the architectures known by GDB. */ - -struct gdbarch_registration -{ - enum bfd_architecture bfd_architecture; - gdbarch_init_ftype *init; - gdbarch_dump_tdep_ftype *dump_tdep; - struct gdbarch_list *arches; - struct gdbarch_registration *next; -}; - -static struct gdbarch_registration *gdbarch_registry = NULL; - -std::vector -gdbarch_printable_names () -{ - /* Accumulate a list of names based on the registed list of - architectures. */ - std::vector arches; - - for (gdbarch_registration *rego = gdbarch_registry; - rego != nullptr; - rego = rego->next) - { - const struct bfd_arch_info *ap - = bfd_lookup_arch (rego->bfd_architecture, 0); - if (ap == nullptr) - internal_error (__FILE__, __LINE__, - _("gdbarch_architecture_names: multi-arch unknown")); - do - { - arches.push_back (ap->printable_name); - ap = ap->next; - } - while (ap != NULL); - } - - return arches; -} - - -void -gdbarch_register (enum bfd_architecture bfd_architecture, - gdbarch_init_ftype *init, - gdbarch_dump_tdep_ftype *dump_tdep) -{ - struct gdbarch_registration **curr; - const struct bfd_arch_info *bfd_arch_info; - - /* Check that BFD recognizes this architecture */ - bfd_arch_info = bfd_lookup_arch (bfd_architecture, 0); - if (bfd_arch_info == NULL) - { - internal_error (__FILE__, __LINE__, - _("gdbarch: Attempt to register " - "unknown architecture (%d)"), - bfd_architecture); - } - /* Check that we haven't seen this architecture before. */ - for (curr = &gdbarch_registry; - (*curr) != NULL; - curr = &(*curr)->next) - { - if (bfd_architecture == (*curr)->bfd_architecture) - internal_error (__FILE__, __LINE__, - _("gdbarch: Duplicate registration " - "of architecture (%s)"), - bfd_arch_info->printable_name); - } - /* log it */ - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "register_gdbarch_init (%s, %s)\n", - bfd_arch_info->printable_name, - host_address_to_string (init)); - /* Append it */ - (*curr) = XNEW (struct gdbarch_registration); - (*curr)->bfd_architecture = bfd_architecture; - (*curr)->init = init; - (*curr)->dump_tdep = dump_tdep; - (*curr)->arches = NULL; - (*curr)->next = NULL; -} - -void -register_gdbarch_init (enum bfd_architecture bfd_architecture, - gdbarch_init_ftype *init) -{ - gdbarch_register (bfd_architecture, init, NULL); -} - - -/* Look for an architecture using gdbarch_info. */ - -struct gdbarch_list * -gdbarch_list_lookup_by_info (struct gdbarch_list *arches, - const struct gdbarch_info *info) -{ - for (; arches != NULL; arches = arches->next) - { - if (info->bfd_arch_info != arches->gdbarch->bfd_arch_info) - continue; - if (info->byte_order != arches->gdbarch->byte_order) - continue; - if (info->osabi != arches->gdbarch->osabi) - continue; - if (info->target_desc != arches->gdbarch->target_desc) - continue; - return arches; - } - return NULL; -} - - -/* Find an architecture that matches the specified INFO. Create a new - architecture if needed. Return that new architecture. */ - -struct gdbarch * -gdbarch_find_by_info (struct gdbarch_info info) -{ - struct gdbarch *new_gdbarch; - struct gdbarch_registration *rego; - - /* Fill in missing parts of the INFO struct using a number of - sources: "set ..."; INFOabfd supplied; and the global - defaults. */ - gdbarch_info_fill (&info); - - /* Must have found some sort of architecture. */ - gdb_assert (info.bfd_arch_info != NULL); - - if (gdbarch_debug) - { - fprintf_unfiltered (gdb_stdlog, - "gdbarch_find_by_info: info.bfd_arch_info %s\n", - (info.bfd_arch_info != NULL - ? info.bfd_arch_info->printable_name - : "(null)")); - fprintf_unfiltered (gdb_stdlog, - "gdbarch_find_by_info: info.byte_order %d (%s)\n", - info.byte_order, - (info.byte_order == BFD_ENDIAN_BIG ? "big" - : info.byte_order == BFD_ENDIAN_LITTLE ? "little" - : "default")); - fprintf_unfiltered (gdb_stdlog, - "gdbarch_find_by_info: info.osabi %d (%s)\n", - info.osabi, gdbarch_osabi_name (info.osabi)); - fprintf_unfiltered (gdb_stdlog, - "gdbarch_find_by_info: info.abfd %s\n", - host_address_to_string (info.abfd)); - } - - /* Find the tdep code that knows about this architecture. */ - for (rego = gdbarch_registry; - rego != NULL; - rego = rego->next) - if (rego->bfd_architecture == info.bfd_arch_info->arch) - break; - if (rego == NULL) - { - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " - "No matching architecture\n"); - return 0; - } - - /* Ask the tdep code for an architecture that matches "info". */ - new_gdbarch = rego->init (info, rego->arches); - - /* Did the tdep code like it? No. Reject the change and revert to - the old architecture. */ - if (new_gdbarch == NULL) - { - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " - "Target rejected architecture\n"); - return NULL; - } - - /* Is this a pre-existing architecture (as determined by already - being initialized)? Move it to the front of the architecture - list (keeping the list sorted Most Recently Used). */ - if (new_gdbarch->initialized_p) - { - struct gdbarch_list **list; - struct gdbarch_list *self; - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " - "Previous architecture %s (%s) selected\n", - host_address_to_string (new_gdbarch), - new_gdbarch->bfd_arch_info->printable_name); - /* Find the existing arch in the list. */ - for (list = ®o->arches; - (*list) != NULL && (*list)->gdbarch != new_gdbarch; - list = &(*list)->next); - /* It had better be in the list of architectures. */ - gdb_assert ((*list) != NULL && (*list)->gdbarch == new_gdbarch); - /* Unlink SELF. */ - self = (*list); - (*list) = self->next; - /* Insert SELF at the front. */ - self->next = rego->arches; - rego->arches = self; - /* Return it. */ - return new_gdbarch; - } - - /* It's a new architecture. */ - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_find_by_info: " - "New architecture %s (%s) selected\n", - host_address_to_string (new_gdbarch), - new_gdbarch->bfd_arch_info->printable_name); - - /* Insert the new architecture into the front of the architecture - list (keep the list sorted Most Recently Used). */ - { - struct gdbarch_list *self = XNEW (struct gdbarch_list); - self->next = rego->arches; - self->gdbarch = new_gdbarch; - rego->arches = self; - } - - /* Check that the newly installed architecture is valid. Plug in - any post init values. */ - new_gdbarch->dump_tdep = rego->dump_tdep; - verify_gdbarch (new_gdbarch); - new_gdbarch->initialized_p = 1; - - if (gdbarch_debug) - gdbarch_dump (new_gdbarch, gdb_stdlog); - - return new_gdbarch; -} - -/* Make the specified architecture current. */ - -void -set_target_gdbarch (struct gdbarch *new_gdbarch) -{ - gdb_assert (new_gdbarch != NULL); - gdb_assert (new_gdbarch->initialized_p); - current_inferior ()->gdbarch = new_gdbarch; - gdb::observers::architecture_changed.notify (new_gdbarch); - registers_changed (); -} - -/* Return the current inferior's arch. */ - -struct gdbarch * -target_gdbarch (void) -{ - return current_inferior ()->gdbarch; -} - -void _initialize_gdbarch (); -void -_initialize_gdbarch () -{ - add_setshow_zuinteger_cmd ("arch", class_maintenance, &gdbarch_debug, _("\\ -Set architecture debugging."), _("\\ -Show architecture debugging."), _("\\ -When non-zero, architecture debugging is enabled."), - NULL, - show_gdbarch_debug, - &setdebuglist, &showdebuglist); -} -EOF - # close things off exec 1>&2 ../move-if-change new-gdbarch.c gdbarch.c