void gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine, enum gdb_osabi osabi, void (*init_osabi)(struct gdbarch_info, struct gdbarch *)) { struct gdb_osabi_handler **handler_p; const struct bfd_arch_info *arch_info = bfd_lookup_arch (arch, machine); const char **name_ptr; /* Registering an OS ABI handler for "unknown" is not allowed. */ if (osabi == GDB_OSABI_UNKNOWN) { internal_error (__FILE__, __LINE__, _("gdbarch_register_osabi: An attempt to register a handler for " "OS ABI \"%s\" for architecture %s was made. The handler will " "not be registered"), gdbarch_osabi_name (osabi), bfd_printable_arch_mach (arch, machine)); return; } gdb_assert (arch_info); for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL; handler_p = &(*handler_p)->next) { if ((*handler_p)->arch_info == arch_info && (*handler_p)->osabi == osabi) { internal_error (__FILE__, __LINE__, _("gdbarch_register_osabi: A handler for OS ABI \"%s\" " "has already been registered for architecture %s"), gdbarch_osabi_name (osabi), arch_info->printable_name); /* If user wants to continue, override previous definition. */ (*handler_p)->init_osabi = init_osabi; return; } } (*handler_p) = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler)); (*handler_p)->next = NULL; (*handler_p)->arch_info = arch_info; (*handler_p)->osabi = osabi; (*handler_p)->init_osabi = init_osabi; /* Add this OS ABI to the list of enum values for "set osabi", if it isn't already there. */ for (name_ptr = gdb_osabi_available_names; *name_ptr; name_ptr ++) { if (*name_ptr == gdbarch_osabi_name (osabi)) return; } *name_ptr++ = gdbarch_osabi_name (osabi); *name_ptr = NULL; }
static void show_osabi (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { if (user_osabi_state == osabi_auto) fprintf_filtered (file, _("The current OS ABI is \"auto\" " "(currently \"%s\").\n"), gdbarch_osabi_name (gdbarch_osabi (get_current_arch ()))); else fprintf_filtered (file, _("The current OS ABI is \"%s\".\n"), gdbarch_osabi_name (user_selected_osabi)); if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN) fprintf_filtered (file, _("The default OS ABI is \"%s\".\n"), gdbarch_osabi_name (GDB_OSABI_DEFAULT)); }
void gdbarch_register_osabi (enum bfd_architecture arch, enum gdb_osabi osabi, void (*init_osabi)(struct gdbarch_info, struct gdbarch *)) { struct gdb_osabi_handler **handler_p; /* Registering an OS ABI handler for "unknown" is not allowed. */ if (osabi == GDB_OSABI_UNKNOWN) { internal_error (__FILE__, __LINE__, "gdbarch_register_osabi: An attempt to register a handler for " "OS ABI \"%s\" for architecture %s was made. The handler will " "not be registered", gdbarch_osabi_name (osabi), bfd_printable_arch_mach (arch, 0)); return; } for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL; handler_p = &(*handler_p)->next) { if ((*handler_p)->arch == arch && (*handler_p)->osabi == osabi) { internal_error (__FILE__, __LINE__, "gdbarch_register_osabi: A handler for OS ABI \"%s\" " "has already been registered for architecture %s", gdbarch_osabi_name (osabi), bfd_printable_arch_mach (arch, 0)); /* If user wants to continue, override previous definition. */ (*handler_p)->init_osabi = init_osabi; return; } } (*handler_p) = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler)); (*handler_p)->next = NULL; (*handler_p)->arch = arch; (*handler_p)->osabi = osabi; (*handler_p)->init_osabi = init_osabi; }
void gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdb_osabi_handler *handler; if (info.osabi == GDB_OSABI_UNKNOWN) { /* Don't complain about an unknown OSABI. Assume the user knows what they are doing. */ return; } for (handler = gdb_osabi_handler_list; handler != NULL; handler = handler->next) { if (handler->osabi != info.osabi) continue; /* If the architecture described by ARCH_INFO can run code for the architcture we registered the handler for, then the handler is applicable. Note, though, that if the handler is for an architecture that is a superset of ARCH_INFO, we can't use that --- it would be perfectly correct for it to install gdbarch methods that refer to registers / instructions / other facilities ARCH_INFO doesn't have. NOTE: kettenis/20021027: There may be more than one machine type that is compatible with the desired machine type. Right now we simply return the first match, which is fine for now. However, we might want to do something smarter in the future. */ /* NOTE: cagney/2003-10-23: The code for "a can_run_code_for b" is implemented using BFD's compatible method (a->compatible (b) == a -- the lowest common denominator between a and b is a). That method's definition of compatible may not be as you expect. For instance the test "amd64 can run code for i386" (or more generally "64-bit ISA can run code for the 32-bit ISA"). BFD doesn't normally consider 32-bit and 64-bit "compatible" so it doesn't succeed. */ if (can_run_code_for (info.bfd_arch_info, handler->arch_info)) { (*handler->init_osabi) (info, gdbarch); return; } } warning ("A handler for the OS ABI \"%s\" is not built into this configuration\n" "of GDB. Attempting to continue with the default %s settings.\n", gdbarch_osabi_name (info.osabi), info.bfd_arch_info->printable_name); }
static void set_osabi (char *args, int from_tty, struct cmd_list_element *c) { struct gdbarch_info info; if (strcmp (set_osabi_string, "auto") == 0) user_osabi_state = osabi_auto; else if (strcmp (set_osabi_string, "default") == 0) { user_selected_osabi = GDB_OSABI_DEFAULT; user_osabi_state = osabi_user; } else if (strcmp (set_osabi_string, "none") == 0) { user_selected_osabi = GDB_OSABI_UNKNOWN; user_osabi_state = osabi_user; } else { int i; for (i = 1; i < GDB_OSABI_INVALID; i++) if (strcmp (set_osabi_string, gdbarch_osabi_name (i)) == 0) { user_selected_osabi = i; user_osabi_state = osabi_user; break; } if (i == GDB_OSABI_INVALID) internal_error (__FILE__, __LINE__, _("Invalid OS ABI \"%s\" passed to command handler."), set_osabi_string); } /* NOTE: At some point (true multiple architectures) we'll need to be more graceful here. */ gdbarch_info_init (&info); if (! gdbarch_update_p (info)) internal_error (__FILE__, __LINE__, _("Updating OS ABI failed.")); }
void gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch, enum gdb_osabi osabi) { struct gdb_osabi_handler *handler; bfd *abfd = info.abfd; const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch); if (osabi == GDB_OSABI_UNKNOWN) { /* Don't complain about an unknown OSABI. Assume the user knows what they are doing. */ return; } for (handler = gdb_osabi_handler_list; handler != NULL; handler = handler->next) { if (handler->arch == bfd_get_arch (abfd) && handler->osabi == osabi) { (*handler->init_osabi) (info, gdbarch); return; } } /* We assume that if GDB_MULTI_ARCH is less than GDB_MULTI_ARCH_TM that an ABI variant can be supported by overriding definitions in the tm-file. */ if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) fprintf_filtered (gdb_stderr, "A handler for the OS ABI \"%s\" is not built into this " "configuration of GDB. " "Attempting to continue with the default %s settings", gdbarch_osabi_name (osabi), bfd_printable_arch_mach (arch_info->arch, arch_info->mach)); }
enum gdb_osabi gdbarch_lookup_osabi (bfd *abfd) { struct gdb_osabi_sniffer *sniffer; enum gdb_osabi osabi, match; int match_specific; /* If we aren't in "auto" mode, return the specified OS ABI. */ if (user_osabi_state == osabi_user) return user_selected_osabi; /* If we don't have a binary, just return unknown. The caller may have other sources the OSABI can be extracted from, e.g., the target description. */ if (abfd == NULL) return GDB_OSABI_UNKNOWN; match = GDB_OSABI_UNKNOWN; match_specific = 0; for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL; sniffer = sniffer->next) { if ((sniffer->arch == bfd_arch_unknown /* wildcard */ || sniffer->arch == bfd_get_arch (abfd)) && sniffer->flavour == bfd_get_flavour (abfd)) { osabi = (*sniffer->sniffer) (abfd); if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID) { internal_error (__FILE__, __LINE__, _("gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer " "for architecture %s flavour %d"), (int) osabi, bfd_printable_arch_mach (bfd_get_arch (abfd), 0), (int) bfd_get_flavour (abfd)); } else if (osabi != GDB_OSABI_UNKNOWN) { /* A specific sniffer always overrides a generic sniffer. Croak on multiple match if the two matches are of the same class. If the user wishes to continue, we'll use the first match. */ if (match != GDB_OSABI_UNKNOWN) { if ((match_specific && sniffer->arch != bfd_arch_unknown) || (!match_specific && sniffer->arch == bfd_arch_unknown)) { internal_error (__FILE__, __LINE__, _("gdbarch_lookup_osabi: multiple %sspecific OS ABI " "match for architecture %s flavour %d: first " "match \"%s\", second match \"%s\""), match_specific ? "" : "non-", bfd_printable_arch_mach (bfd_get_arch (abfd), 0), (int) bfd_get_flavour (abfd), gdbarch_osabi_name (match), gdbarch_osabi_name (osabi)); } else if (sniffer->arch != bfd_arch_unknown) { match = osabi; match_specific = 1; } } else { match = osabi; if (sniffer->arch != bfd_arch_unknown) match_specific = 1; } } } } return match; }
enum gdb_osabi gdbarch_lookup_osabi (bfd *abfd) { struct gdb_osabi_sniffer *sniffer; enum gdb_osabi osabi, match; int match_specific; match = GDB_OSABI_UNKNOWN; match_specific = 0; for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL; sniffer = sniffer->next) { if ((sniffer->arch == bfd_arch_unknown /* wildcard */ || sniffer->arch == bfd_get_arch (abfd)) && sniffer->flavour == bfd_get_flavour (abfd)) { osabi = (*sniffer->sniffer) (abfd); if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID) { internal_error (__FILE__, __LINE__, "gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer " "for architecture %s flavour %d", (int) osabi, bfd_printable_arch_mach (bfd_get_arch (abfd), 0), (int) bfd_get_flavour (abfd)); } else if (osabi != GDB_OSABI_UNKNOWN) { /* A specific sniffer always overrides a generic sniffer. Croak on multiple match if the two matches are of the same class. If the user wishes to continue, we'll use the first match. */ if (match != GDB_OSABI_UNKNOWN) { if ((match_specific && sniffer->arch != bfd_arch_unknown) || (!match_specific && sniffer->arch == bfd_arch_unknown)) { internal_error (__FILE__, __LINE__, "gdbarch_lookup_osabi: multiple %sspecific OS ABI " "match for architecture %s flavour %d: first " "match \"%s\", second match \"%s\"", match_specific ? "" : "non-", bfd_printable_arch_mach (bfd_get_arch (abfd), 0), (int) bfd_get_flavour (abfd), gdbarch_osabi_name (match), gdbarch_osabi_name (osabi)); } else if (sniffer->arch != bfd_arch_unknown) { match = osabi; match_specific = 1; } } else { match = osabi; if (sniffer->arch != bfd_arch_unknown) match_specific = 1; } } } } return match; }