From 28e97307c863a9285018e912c2e735f1c0e168ee Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Thu, 14 Apr 2005 18:40:26 +0000 Subject: [PATCH] * arm-tdep.c (fp_model_strings): Add terminating NULL. (arm_abi_strings, arm_abi_global, arm_abi_string): New variables. (arm_extract_return_value, arm_store_return_value): Don't use arm_get_fp_model. (arm_get_fp_model, arm_set_fp): Delete. (arm_update_current_architecture): New function. (set_fp_model_sfunc): Call arm_update_current_architecture. (show_fp_model): Update output messages. (arm_set_abi, arm_show_abi): New functions. (arm_elf_osabi_sniffer): Only handle ELFOSABI_ARM. (arm_gdbarch_init): Infer the object's ABI separately from its OSABI. Search for a matching architecture. Honor the global ABI and FPU settings. Set floating point format based on the architecture. (arm_init_abi_eabi_v1, arm_init_abi_eabi_v2, arm_init_abi_apcs): Delete. (_initialize_arm_tdep): Don't call gdbarch_register_osabi. Create "arm set abi" command. * arm-tdep.h (arm_get_fp_model): Delete prototype. (enum arm_abi_kind): New type. (struct gdbarch_tdep): Add arm_abi field. * arm-linux-tdep.c (arm_linux_init_abi): Only override tdep->fp_model if it is ARM_FLOAT_AUTO. * armnbsd-tdep.c (arm_netbsd_aout_init_abi): Likewise. (arm_netbsd_elf_init_abi): Likewise. * defs.h (enum gdb_osabi): Delete ARM-specific OSABIs. * osabi.c (gdb_osabi_name): Likewise. --- gdb/ChangeLog | 31 +++++ gdb/arm-linux-tdep.c | 3 +- gdb/arm-tdep.c | 332 +++++++++++++++++++++++++++++---------------------- gdb/arm-tdep.h | 14 ++- gdb/armnbsd-tdep.c | 6 +- gdb/defs.h | 3 - gdb/osabi.c | 3 - 7 files changed, 239 insertions(+), 153 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 482b9b7..b120c83 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,34 @@ +2005-04-14 Daniel Jacobowitz + + * arm-tdep.c (fp_model_strings): Add terminating NULL. + (arm_abi_strings, arm_abi_global, arm_abi_string): New + variables. + (arm_extract_return_value, arm_store_return_value): Don't use + arm_get_fp_model. + (arm_get_fp_model, arm_set_fp): Delete. + (arm_update_current_architecture): New function. + (set_fp_model_sfunc): Call arm_update_current_architecture. + (show_fp_model): Update output messages. + (arm_set_abi, arm_show_abi): New functions. + (arm_elf_osabi_sniffer): Only handle ELFOSABI_ARM. + (arm_gdbarch_init): Infer the object's ABI separately from its + OSABI. Search for a matching architecture. Honor the global + ABI and FPU settings. Set floating point format based on the + architecture. + (arm_init_abi_eabi_v1, arm_init_abi_eabi_v2, arm_init_abi_apcs): + Delete. + (_initialize_arm_tdep): Don't call gdbarch_register_osabi. + Create "arm set abi" command. + * arm-tdep.h (arm_get_fp_model): Delete prototype. + (enum arm_abi_kind): New type. + (struct gdbarch_tdep): Add arm_abi field. + * arm-linux-tdep.c (arm_linux_init_abi): Only override + tdep->fp_model if it is ARM_FLOAT_AUTO. + * armnbsd-tdep.c (arm_netbsd_aout_init_abi): Likewise. + (arm_netbsd_elf_init_abi): Likewise. + * defs.h (enum gdb_osabi): Delete ARM-specific OSABIs. + * osabi.c (gdb_osabi_name): Likewise. + 2005-04-11 Daniel Jacobowitz * config/djgpp/fnchange.lst: Remove entries for gdb.gdbserver. diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index fe39c21..6fe363f 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -480,7 +480,8 @@ arm_linux_init_abi (struct gdbarch_info info, tdep->arm_breakpoint_size = sizeof (arm_linux_arm_le_breakpoint); tdep->thumb_breakpoint_size = sizeof (arm_linux_thumb_le_breakpoint); - tdep->fp_model = ARM_FLOAT_FPA; + if (tdep->fp_model == ARM_FLOAT_AUTO) + tdep->fp_model = ARM_FLOAT_FPA; tdep->jb_pc = ARM_LINUX_JB_PC; tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE; diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index fc7e8fe..44af314 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -107,13 +107,27 @@ static const char *fp_model_strings[] = "softfpa", "fpa", "softvfp", - "vfp" + "vfp", + NULL }; /* A variable that can be configured by the user. */ static enum arm_float_model arm_fp_model = ARM_FLOAT_AUTO; static const char *current_fp_model = "auto"; +/* The ABI to use. Keep this in sync with arm_abi_kind. */ +static const char *arm_abi_strings[] = +{ + "auto", + "APCS", + "AAPCS", + NULL +}; + +/* A variable that can be configured by the user. */ +static enum arm_abi_kind arm_abi_global = ARM_ABI_AUTO; +static const char *arm_abi_string = "auto"; + /* Number of different reg name sets (options). */ static int num_disassembly_options; @@ -2007,7 +2021,7 @@ arm_extract_return_value (struct type *type, if (TYPE_CODE_FLT == TYPE_CODE (type)) { - switch (arm_get_fp_model (current_gdbarch)) + switch (gdbarch_tdep (current_gdbarch)->fp_model) { case ARM_FLOAT_FPA: { @@ -2204,7 +2218,7 @@ arm_store_return_value (struct type *type, struct regcache *regs, { char buf[MAX_REGISTER_SIZE]; - switch (arm_get_fp_model (current_gdbarch)) + switch (gdbarch_tdep (current_gdbarch)->fp_model) { case ARM_FLOAT_FPA: @@ -2361,34 +2375,20 @@ show_arm_command (char *args, int from_tty) cmd_show_list (showarmcmdlist, from_tty, ""); } -enum arm_float_model -arm_get_fp_model (struct gdbarch *gdbarch) +static void +arm_update_current_architecture (void) { - if (arm_fp_model == ARM_FLOAT_AUTO) - return gdbarch_tdep (gdbarch)->fp_model; + struct gdbarch_info info; - return arm_fp_model; -} + /* If the current architecture is not ARM, we have nothing to do. */ + if (gdbarch_bfd_arch_info (current_gdbarch)->arch != bfd_arch_arm) + return; -static void -arm_set_fp (struct gdbarch *gdbarch) -{ - enum arm_float_model fp_model = arm_get_fp_model (gdbarch); + /* Update the architecture. */ + gdbarch_info_init (&info); - if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE - && (fp_model == ARM_FLOAT_SOFT_FPA || fp_model == ARM_FLOAT_FPA)) - { - set_gdbarch_double_format (gdbarch, - &floatformat_ieee_double_littlebyte_bigword); - set_gdbarch_long_double_format - (gdbarch, &floatformat_ieee_double_littlebyte_bigword); - } - else - { - set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little); - set_gdbarch_long_double_format (gdbarch, - &floatformat_ieee_double_little); - } + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, "could not update architecture"); } static void @@ -2408,8 +2408,7 @@ set_fp_model_sfunc (char *args, int from_tty, internal_error (__FILE__, __LINE__, _("Invalid fp model accepted: %s."), current_fp_model); - if (gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_arm) - arm_set_fp (current_gdbarch); + arm_update_current_architecture (); } static void @@ -2418,12 +2417,51 @@ show_fp_model (struct ui_file *file, int from_tty, { struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - deprecated_show_value_hack (file, from_tty, c, value); - if (arm_fp_model == ARM_FLOAT_AUTO + if (arm_fp_model == ARM_FLOAT_AUTO && gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_arm) - /* i18n: "the default [floating point model] for the current ABI..." */ - printf_filtered (_(" - the default for the current ABI is \"%s\".\n"), - fp_model_strings[tdep->fp_model]); + fprintf_filtered (file, _("\ +The current ARM floating point model is \"auto\" (currently \"%s\").\n"), + fp_model_strings[tdep->fp_model]); + else + fprintf_filtered (file, _("\ +The current ARM floating point model is \"%s\".\n"), + fp_model_strings[arm_fp_model]); +} + +static void +arm_set_abi (char *args, int from_tty, + struct cmd_list_element *c) +{ + enum arm_abi_kind arm_abi; + + for (arm_abi = ARM_ABI_AUTO; arm_abi != ARM_ABI_LAST; arm_abi++) + if (strcmp (arm_abi_string, arm_abi_strings[arm_abi]) == 0) + { + arm_abi_global = arm_abi; + break; + } + + if (arm_abi == ARM_ABI_LAST) + internal_error (__FILE__, __LINE__, _("Invalid ABI accepted: %s."), + arm_abi_string); + + arm_update_current_architecture (); +} + +static void +arm_show_abi (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + if (arm_abi_global == ARM_ABI_AUTO + && gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_arm) + fprintf_filtered (file, _("\ +The current ARM ABI is \"auto\" (currently \"%s\").\n"), + arm_abi_strings[tdep->arm_abi]); + else + fprintf_filtered (file, _("The current ARM ABI is \"%s\".\n"), + arm_abi_string); } /* If the user changes the register disassembly style used for info @@ -2540,71 +2578,14 @@ arm_elf_osabi_sniffer (bfd *abfd) elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; - switch (elfosabi) - { - case ELFOSABI_NONE: - /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the - file are conforming to the base specification for that machine - (there are no OS-specific extensions). In order to determine the - real OS in use we must look for OS notes that have been added. */ - bfd_map_over_sections (abfd, - generic_elf_osabi_sniff_abi_tag_sections, - &osabi); - if (osabi == GDB_OSABI_UNKNOWN) - { - /* Existing ARM tools don't set this field, so look at the EI_FLAGS - field for more information. */ - eflags = EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags); - switch (eflags) - { - case EF_ARM_EABI_VER1: - osabi = GDB_OSABI_ARM_EABI_V1; - break; - - case EF_ARM_EABI_VER2: - osabi = GDB_OSABI_ARM_EABI_V2; - break; - - case EF_ARM_EABI_UNKNOWN: - /* Assume GNU tools. */ - osabi = GDB_OSABI_ARM_APCS; - break; - - default: - internal_error (__FILE__, __LINE__, - _("\ -arm_elf_osabi_sniffer: Unknown ARM EABI version 0x%x"), - eflags); - } - } - break; - - case ELFOSABI_ARM: - /* GNU tools use this value. Check note sections in this case, - as well. */ - bfd_map_over_sections (abfd, - generic_elf_osabi_sniff_abi_tag_sections, - &osabi); - if (osabi == GDB_OSABI_UNKNOWN) - { - /* Assume APCS ABI. */ - osabi = GDB_OSABI_ARM_APCS; - } - break; - - case ELFOSABI_FREEBSD: - osabi = GDB_OSABI_FREEBSD_ELF; - break; - - case ELFOSABI_NETBSD: - osabi = GDB_OSABI_NETBSD_ELF; - break; - - case ELFOSABI_LINUX: - osabi = GDB_OSABI_LINUX; - break; - } + if (elfosabi == ELFOSABI_ARM) + /* GNU tools use this value. Check note sections in this case, + as well. */ + bfd_map_over_sections (abfd, + generic_elf_osabi_sniff_abi_tag_sections, + &osabi); + /* Anything else will be handled by the generic ELF sniffer. */ return osabi; } @@ -2621,42 +2602,120 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch_tdep *tdep; struct gdbarch *gdbarch; + struct gdbarch_list *best_arch; + enum arm_abi_kind arm_abi = arm_abi_global; + enum arm_float_model fp_model = arm_fp_model; - /* Try to deterimine the ABI of the object we are loading. */ + /* If we have an object to base this architecture on, try to determine + its ABI. */ - if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN) + if (arm_abi == ARM_ABI_AUTO && info.abfd != NULL) { + int ei_osabi; + switch (bfd_get_flavour (info.abfd)) { case bfd_target_aout_flavour: /* Assume it's an old APCS-style ABI. */ - info.osabi = GDB_OSABI_ARM_APCS; + arm_abi = ARM_ABI_APCS; break; case bfd_target_coff_flavour: /* Assume it's an old APCS-style ABI. */ /* XXX WinCE? */ - info.osabi = GDB_OSABI_ARM_APCS; + arm_abi = ARM_ABI_APCS; + break; + + case bfd_target_elf_flavour: + ei_osabi = elf_elfheader (info.abfd)->e_ident[EI_OSABI]; + if (ei_osabi == ELFOSABI_ARM) + { + /* GNU tools used to use this value, but do not for EABI + objects. There's nowhere to tag an EABI version anyway, + so assume APCS. */ + arm_abi = ARM_ABI_APCS; + } + else if (ei_osabi == ELFOSABI_NONE) + { + int e_flags, eabi_ver; + + e_flags = elf_elfheader (info.abfd)->e_flags; + eabi_ver = EF_ARM_EABI_VERSION (e_flags); + + switch (eabi_ver) + { + case EF_ARM_EABI_UNKNOWN: + /* Assume GNU tools. */ + arm_abi = ARM_ABI_APCS; + break; + + case EF_ARM_EABI_VER4: + arm_abi = ARM_ABI_AAPCS; + break; + + default: + warning (_("unknown ARM EABI version 0x%x"), eabi_ver); + arm_abi = ARM_ABI_APCS; + break; + } + } break; default: - /* Leave it as "unknown". */ + /* Leave it as "auto". */ break; } } - /* If there is already a candidate, use it. */ - arches = gdbarch_list_lookup_by_info (arches, &info); + /* Now that we have inferred any architecture settings that we + can, try to inherit from the last ARM ABI. */ if (arches != NULL) - return arches->gdbarch; + { + if (arm_abi == ARM_ABI_AUTO) + arm_abi = gdbarch_tdep (arches->gdbarch)->arm_abi; + + if (fp_model == ARM_FLOAT_AUTO) + fp_model = gdbarch_tdep (arches->gdbarch)->fp_model; + } + else + { + /* There was no prior ARM architecture; fill in default values. */ + + if (arm_abi == ARM_ABI_AUTO) + arm_abi = ARM_ABI_APCS; + + /* We used to default to FPA for generic ARM, but almost nobody + uses that now, and we now provide a way for the user to force + the model. So default to the most useful variant. */ + if (fp_model == ARM_FLOAT_AUTO) + fp_model = ARM_FLOAT_SOFT_FPA; + } + + /* If there is already a candidate, use it. */ + for (best_arch = gdbarch_list_lookup_by_info (arches, &info); + best_arch != NULL; + best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info)) + { + if (arm_abi != gdbarch_tdep (best_arch->gdbarch)->arm_abi) + continue; + + if (fp_model != gdbarch_tdep (best_arch->gdbarch)->fp_model) + continue; + + /* Found a match. */ + break; + } - tdep = xmalloc (sizeof (struct gdbarch_tdep)); + if (best_arch != NULL) + return best_arch->gdbarch; + + tdep = xcalloc (1, sizeof (struct gdbarch_tdep)); gdbarch = gdbarch_alloc (&info, tdep); - /* We used to default to FPA for generic ARM, but almost nobody uses that - now, and we now provide a way for the user to force the model. So - default to the most useful variant. */ - tdep->fp_model = ARM_FLOAT_SOFT_FPA; + /* Record additional information about the architecture we are defining. + These are gdbarch discriminators, like the OSABI. */ + tdep->arm_abi = arm_abi; + tdep->fp_model = fp_model; /* Breakpoints. */ switch (info.byte_order) @@ -2772,12 +2831,23 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big); set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big); set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); - break; case BFD_ENDIAN_LITTLE: set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little); - arm_set_fp (gdbarch); + if (fp_model == ARM_FLOAT_SOFT_FPA || fp_model == ARM_FLOAT_FPA) + { + set_gdbarch_double_format + (gdbarch, &floatformat_ieee_double_littlebyte_bigword); + set_gdbarch_long_double_format + (gdbarch, &floatformat_ieee_double_littlebyte_bigword); + } + else + { + set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little); + set_gdbarch_long_double_format (gdbarch, + &floatformat_ieee_double_little); + } break; default: @@ -2800,27 +2870,6 @@ arm_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) (unsigned long) tdep->lowest_pc); } -static void -arm_init_abi_eabi_v1 (struct gdbarch_info info, - struct gdbarch *gdbarch) -{ - /* Place-holder. */ -} - -static void -arm_init_abi_eabi_v2 (struct gdbarch_info info, - struct gdbarch *gdbarch) -{ - /* Place-holder. */ -} - -static void -arm_init_abi_apcs (struct gdbarch_info info, - struct gdbarch *gdbarch) -{ - /* Place-holder. */ -} - extern initialize_file_ftype _initialize_arm_tdep; /* -Wmissing-prototypes */ void @@ -2844,14 +2893,6 @@ _initialize_arm_tdep (void) bfd_target_elf_flavour, arm_elf_osabi_sniffer); - /* Register some ABI variants for embedded systems. */ - gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_ARM_EABI_V1, - arm_init_abi_eabi_v1); - gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_ARM_EABI_V2, - arm_init_abi_eabi_v2); - gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_ARM_APCS, - arm_init_abi_apcs); - /* Get the number of possible sets of register names defined in opcodes. */ num_disassembly_options = get_arm_regname_num_options (); @@ -2929,6 +2970,13 @@ vfp - VFP co-processor."), set_fp_model_sfunc, show_fp_model, &setarmcmdlist, &showarmcmdlist); + /* Add a command to allow the user to force the ABI. */ + add_setshow_enum_cmd ("abi", class_support, arm_abi_strings, &arm_abi_string, + _("Set the ABI."), + _("Show the ABI."), + NULL, arm_set_abi, arm_show_abi, + &setarmcmdlist, &showarmcmdlist); + /* Debugging flag. */ add_setshow_boolean_cmd ("arm", class_maintenance, &arm_debug, _("Set ARM debugging."), diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index bb30455..5217ff6 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -113,12 +113,22 @@ enum arm_float_model ARM_FLOAT_LAST /* Keep at end. */ }; -/* A method to the setting based on user's choice and ABI setting. */ -enum arm_float_model arm_get_fp_model (struct gdbarch *); +/* ABI used by the inferior. */ +enum arm_abi_kind +{ + ARM_ABI_AUTO, + ARM_ABI_APCS, + ARM_ABI_AAPCS, + ARM_ABI_LAST +}; /* Target-dependent structure in gdbarch. */ struct gdbarch_tdep { + /* The ABI for this architecture. It should never be set to + ARM_ABI_AUTO. */ + enum arm_abi_kind arm_abi; + enum arm_float_model fp_model; /* Floating point calling conventions. */ CORE_ADDR lowest_pc; /* Lowest address at which instructions diff --git a/gdb/armnbsd-tdep.c b/gdb/armnbsd-tdep.c index d5ac9e8..9f2a346 100644 --- a/gdb/armnbsd-tdep.c +++ b/gdb/armnbsd-tdep.c @@ -78,7 +78,8 @@ arm_netbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); arm_netbsd_init_abi_common (info, gdbarch); - tdep->fp_model = ARM_FLOAT_SOFT_FPA; + if (tdep->fp_model == ARM_FLOAT_AUTO) + tdep->fp_model = ARM_FLOAT_SOFT_FPA; } static void @@ -92,7 +93,8 @@ arm_netbsd_elf_init_abi (struct gdbarch_info info, set_solib_svr4_fetch_link_map_offsets (gdbarch, nbsd_ilp32_solib_svr4_fetch_link_map_offsets); - tdep->fp_model = ARM_FLOAT_SOFT_VFP; + if (tdep->fp_model == ARM_FLOAT_AUTO) + tdep->fp_model = ARM_FLOAT_SOFT_VFP; } static enum gdb_osabi diff --git a/gdb/defs.h b/gdb/defs.h index fa012a4..30178a4 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -952,9 +952,6 @@ enum gdb_osabi GDB_OSABI_HPUX_ELF, GDB_OSABI_HPUX_SOM, - GDB_OSABI_ARM_EABI_V1, - GDB_OSABI_ARM_EABI_V2, - GDB_OSABI_ARM_APCS, GDB_OSABI_QNXNTO, GDB_OSABI_CYGWIN, diff --git a/gdb/osabi.c b/gdb/osabi.c index 698e941..7b4698a 100644 --- a/gdb/osabi.c +++ b/gdb/osabi.c @@ -71,9 +71,6 @@ static const char * const gdb_osabi_names[] = "HP/UX ELF", "HP/UX SOM", - "ARM EABI v1", - "ARM EABI v2", - "ARM APCS", "QNX Neutrino", "Cygwin", -- 2.7.4