gdb/arch-utils.c - gdb
Global variables defined
Data types defined
Functions defined
Source code
- #include "defs.h"
- #include "arch-utils.h"
- #include "buildsym.h"
- #include "gdbcmd.h"
- #include "inferior.h"
- #include "infrun.h"
- #include "regcache.h"
- #include "sim-regno.h"
- #include "gdbcore.h"
- #include "osabi.h"
- #include "target-descriptions.h"
- #include "objfiles.h"
- #include "language.h"
- #include "symtab.h"
- #include "version.h"
- #include "floatformat.h"
- struct displaced_step_closure *
- simple_displaced_step_copy_insn (struct gdbarch *gdbarch,
- CORE_ADDR from, CORE_ADDR to,
- struct regcache *regs)
- {
- size_t len = gdbarch_max_insn_length (gdbarch);
- gdb_byte *buf = xmalloc (len);
- read_memory (from, buf, len);
- write_memory (to, buf, len);
- if (debug_displaced)
- {
- fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ",
- paddress (gdbarch, from), paddress (gdbarch, to));
- displaced_step_dump_bytes (gdb_stdlog, buf, len);
- }
- return (struct displaced_step_closure *) buf;
- }
- void
- simple_displaced_step_free_closure (struct gdbarch *gdbarch,
- struct displaced_step_closure *closure)
- {
- xfree (closure);
- }
- int
- default_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
- struct displaced_step_closure *closure)
- {
- return !gdbarch_software_single_step_p (gdbarch);
- }
- CORE_ADDR
- displaced_step_at_entry_point (struct gdbarch *gdbarch)
- {
- CORE_ADDR addr;
- int bp_len;
- addr = entry_point_address ();
-
- gdbarch_breakpoint_from_pc (gdbarch, &addr, &bp_len);
- addr += bp_len * 2;
- return addr;
- }
- int
- legacy_register_sim_regno (struct gdbarch *gdbarch, int regnum)
- {
-
- gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch));
-
- if (gdbarch_register_name (gdbarch, regnum) != NULL
- && gdbarch_register_name (gdbarch, regnum)[0] != '\0')
- return regnum;
- else
- return LEGACY_SIM_REGNO_IGNORE;
- }
- CORE_ADDR
- generic_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
- {
- return 0;
- }
- CORE_ADDR
- generic_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
- {
- return 0;
- }
- int
- generic_in_solib_return_trampoline (struct gdbarch *gdbarch,
- CORE_ADDR pc, const char *name)
- {
- return 0;
- }
- int
- generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
- {
- return 0;
- }
- int
- core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs)
- {
- return (lhs < rhs);
- }
- int
- core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs)
- {
- return (lhs > rhs);
- }
- CORE_ADDR
- core_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr)
- {
- return addr;
- }
- CORE_ADDR
- convert_from_func_ptr_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr,
- struct target_ops *targ)
- {
- return addr;
- }
- int
- no_op_reg_to_regnum (struct gdbarch *gdbarch, int reg)
- {
- return reg;
- }
- void
- default_coff_make_msymbol_special (int val, struct minimal_symbol *msym)
- {
- return;
- }
- void
- default_make_symbol_special (struct symbol *sym, struct objfile *objfile)
- {
- return;
- }
- CORE_ADDR
- default_adjust_dwarf2_addr (CORE_ADDR pc)
- {
- return pc;
- }
- CORE_ADDR
- default_adjust_dwarf2_line (CORE_ADDR addr, int rel)
- {
- return addr;
- }
- int
- cannot_register_not (struct gdbarch *gdbarch, int regnum)
- {
- return 0;
- }
- void
- legacy_virtual_frame_pointer (struct gdbarch *gdbarch,
- CORE_ADDR pc,
- int *frame_regnum,
- LONGEST *frame_offset)
- {
- FIXME
- if (gdbarch_deprecated_fp_regnum (gdbarch) >= 0
- && gdbarch_deprecated_fp_regnum (gdbarch)
- < gdbarch_num_regs (gdbarch))
- *frame_regnum = gdbarch_deprecated_fp_regnum (gdbarch);
- else if (gdbarch_sp_regnum (gdbarch) >= 0
- && gdbarch_sp_regnum (gdbarch)
- < gdbarch_num_regs (gdbarch))
- *frame_regnum = gdbarch_sp_regnum (gdbarch);
- else
-
- internal_error (__FILE__, __LINE__,
- _("No virtual frame pointer available"));
- *frame_offset = 0;
- }
- int
- generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
- struct type *type)
- {
- return 0;
- }
- int
- default_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
- {
- return 0;
- }
- int
- generic_instruction_nullified (struct gdbarch *gdbarch,
- struct regcache *regcache)
- {
- return 0;
- }
- int
- default_remote_register_number (struct gdbarch *gdbarch,
- int regno)
- {
- return regno;
- }
- int
- default_vsyscall_range (struct gdbarch *gdbarch, struct mem_range *range)
- {
- return 0;
- }
- static int target_byte_order_user = BFD_ENDIAN_UNKNOWN;
- static const char endian_big[] = "big";
- static const char endian_little[] = "little";
- static const char endian_auto[] = "auto";
- static const char *const endian_enum[] =
- {
- endian_big,
- endian_little,
- endian_auto,
- NULL,
- };
- static const char *set_endian_string;
- enum bfd_endian
- selected_byte_order (void)
- {
- return target_byte_order_user;
- }
- static void
- show_endian (struct ui_file *file, int from_tty, struct cmd_list_element *c,
- const char *value)
- {
- if (target_byte_order_user == BFD_ENDIAN_UNKNOWN)
- if (gdbarch_byte_order (get_current_arch ()) == BFD_ENDIAN_BIG)
- fprintf_unfiltered (file, _("The target endianness is set automatically "
- "(currently big endian)\n"));
- else
- fprintf_unfiltered (file, _("The target endianness is set automatically "
- "(currently little endian)\n"));
- else
- if (target_byte_order_user == BFD_ENDIAN_BIG)
- fprintf_unfiltered (file,
- _("The target is assumed to be big endian\n"));
- else
- fprintf_unfiltered (file,
- _("The target is assumed to be little endian\n"));
- }
- static void
- set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
- {
- struct gdbarch_info info;
- gdbarch_info_init (&info);
- if (set_endian_string == endian_auto)
- {
- target_byte_order_user = BFD_ENDIAN_UNKNOWN;
- if (! gdbarch_update_p (info))
- internal_error (__FILE__, __LINE__,
- _("set_endian: architecture update failed"));
- }
- else if (set_endian_string == endian_little)
- {
- info.byte_order = BFD_ENDIAN_LITTLE;
- if (! gdbarch_update_p (info))
- printf_unfiltered (_("Little endian target not supported by GDB\n"));
- else
- target_byte_order_user = BFD_ENDIAN_LITTLE;
- }
- else if (set_endian_string == endian_big)
- {
- info.byte_order = BFD_ENDIAN_BIG;
- if (! gdbarch_update_p (info))
- printf_unfiltered (_("Big endian target not supported by GDB\n"));
- else
- target_byte_order_user = BFD_ENDIAN_BIG;
- }
- else
- internal_error (__FILE__, __LINE__,
- _("set_endian: bad value"));
- show_endian (gdb_stdout, from_tty, NULL, NULL);
- }
- static const struct bfd_arch_info *
- choose_architecture_for_target (const struct target_desc *target_desc,
- const struct bfd_arch_info *selected)
- {
- const struct bfd_arch_info *from_target = tdesc_architecture (target_desc);
- const struct bfd_arch_info *compat1, *compat2;
- if (selected == NULL)
- return from_target;
- if (from_target == NULL)
- return selected;
-
- if (from_target == selected)
- return selected;
-
- compat1 = selected->compatible (selected, from_target);
- compat2 = from_target->compatible (from_target, selected);
- if (compat1 == NULL && compat2 == NULL)
- {
-
- if (tdesc_compatible_p (target_desc, selected))
- return from_target;
- warning (_("Selected architecture %s is not compatible "
- "with reported target architecture %s"),
- selected->printable_name, from_target->printable_name);
- return selected;
- }
- if (compat1 == NULL)
- return compat2;
- if (compat2 == NULL)
- return compat1;
- if (compat1 == compat2)
- return compat1;
-
- if (compat1->the_default)
- return compat2;
- if (compat2->the_default)
- return compat1;
-
- warning (_("Selected architecture %s is ambiguous with "
- "reported target architecture %s"),
- selected->printable_name, from_target->printable_name);
- return selected;
- }
- enum set_arch { set_arch_auto, set_arch_manual };
- static const struct bfd_arch_info *target_architecture_user;
- static const char *set_architecture_string;
- const char *
- selected_architecture_name (void)
- {
- if (target_architecture_user == NULL)
- return NULL;
- else
- return set_architecture_string;
- }
- static void
- show_architecture (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
- {
- if (target_architecture_user == NULL)
- fprintf_filtered (file, _("The target architecture is set "
- "automatically (currently %s)\n"),
- gdbarch_bfd_arch_info (get_current_arch ())->printable_name);
- else
- fprintf_filtered (file, _("The target architecture is assumed to be %s\n"),
- set_architecture_string);
- }
- static void
- set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c)
- {
- struct gdbarch_info info;
- gdbarch_info_init (&info);
- if (strcmp (set_architecture_string, "auto") == 0)
- {
- target_architecture_user = NULL;
- if (!gdbarch_update_p (info))
- internal_error (__FILE__, __LINE__,
- _("could not select an architecture automatically"));
- }
- else
- {
- info.bfd_arch_info = bfd_scan_arch (set_architecture_string);
- if (info.bfd_arch_info == NULL)
- internal_error (__FILE__, __LINE__,
- _("set_architecture: bfd_scan_arch failed"));
- if (gdbarch_update_p (info))
- target_architecture_user = info.bfd_arch_info;
- else
- printf_unfiltered (_("Architecture `%s' not recognized.\n"),
- set_architecture_string);
- }
- show_architecture (gdb_stdout, from_tty, NULL, NULL);
- }
- int
- gdbarch_update_p (struct gdbarch_info info)
- {
- struct gdbarch *new_gdbarch;
-
- if (info.abfd == NULL)
- info.abfd = exec_bfd;
- if (info.abfd == NULL)
- info.abfd = core_bfd;
-
- if (info.target_desc == NULL)
- info.target_desc = target_current_description ();
- new_gdbarch = gdbarch_find_by_info (info);
-
- if (new_gdbarch == NULL)
- {
- if (gdbarch_debug)
- fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: "
- "Architecture not found\n");
- return 0;
- }
-
- if (new_gdbarch == target_gdbarch ())
- {
- if (gdbarch_debug)
- fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: "
- "Architecture %s (%s) unchanged\n",
- host_address_to_string (new_gdbarch),
- gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
- return 1;
- }
-
- if (gdbarch_debug)
- fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: "
- "New architecture %s (%s) selected\n",
- host_address_to_string (new_gdbarch),
- gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
- set_target_gdbarch (new_gdbarch);
- return 1;
- }
- struct gdbarch *
- gdbarch_from_bfd (bfd *abfd)
- {
- struct gdbarch_info info;
- gdbarch_info_init (&info);
- info.abfd = abfd;
- return gdbarch_find_by_info (info);
- }
- void
- set_gdbarch_from_file (bfd *abfd)
- {
- struct gdbarch_info info;
- struct gdbarch *gdbarch;
- gdbarch_info_init (&info);
- info.abfd = abfd;
- info.target_desc = target_current_description ();
- gdbarch = gdbarch_find_by_info (info);
- if (gdbarch == NULL)
- error (_("Architecture of file not recognized."));
- set_target_gdbarch (gdbarch);
- }
- #ifdef DEFAULT_BFD_ARCH
- extern const bfd_arch_info_type DEFAULT_BFD_ARCH;
- static const bfd_arch_info_type *default_bfd_arch = &DEFAULT_BFD_ARCH;
- #else
- static const bfd_arch_info_type *default_bfd_arch;
- #endif
- #ifdef DEFAULT_BFD_VEC
- extern const bfd_target DEFAULT_BFD_VEC;
- static const bfd_target *default_bfd_vec = &DEFAULT_BFD_VEC;
- #else
- static const bfd_target *default_bfd_vec;
- #endif
- static int default_byte_order = BFD_ENDIAN_UNKNOWN;
- void
- initialize_current_architecture (void)
- {
- const char **arches = gdbarch_printable_names ();
- struct gdbarch_info info;
-
- gdbarch_info_init (&info);
-
- if (default_bfd_arch == NULL)
- {
-
- const char *chosen = arches[0];
- const char **arch;
- for (arch = arches; *arch != NULL; arch++)
- {
- if (strcmp (*arch, chosen) < 0)
- chosen = *arch;
- }
- if (chosen == NULL)
- internal_error (__FILE__, __LINE__,
- _("initialize_current_architecture: No arch"));
- default_bfd_arch = bfd_scan_arch (chosen);
- if (default_bfd_arch == NULL)
- internal_error (__FILE__, __LINE__,
- _("initialize_current_architecture: Arch not found"));
- }
- info.bfd_arch_info = default_bfd_arch;
-
- if (default_byte_order == BFD_ENDIAN_UNKNOWN
- && default_bfd_vec != NULL)
- {
-
- switch (default_bfd_vec->byteorder)
- {
- case BFD_ENDIAN_BIG:
- default_byte_order = BFD_ENDIAN_BIG;
- break;
- case BFD_ENDIAN_LITTLE:
- default_byte_order = BFD_ENDIAN_LITTLE;
- break;
- default:
- break;
- }
- }
- if (default_byte_order == BFD_ENDIAN_UNKNOWN)
- {
-
- const char *chp;
- chp = strchr (target_name, '-');
- if (chp != NULL
- && chp - 2 >= target_name
- && strncmp (chp - 2, "el", 2) == 0)
- default_byte_order = BFD_ENDIAN_LITTLE;
- }
- if (default_byte_order == BFD_ENDIAN_UNKNOWN)
- {
-
- default_byte_order = BFD_ENDIAN_BIG;
- }
- info.byte_order = default_byte_order;
- info.byte_order_for_code = info.byte_order;
- if (! gdbarch_update_p (info))
- internal_error (__FILE__, __LINE__,
- _("initialize_current_architecture: Selection of "
- "initial architecture failed"));
-
- {
-
- int nr;
- for (nr = 0; arches[nr] != NULL; nr++);
- arches = xrealloc (arches, sizeof (char*) * (nr + 2));
- arches[nr + 0] = "auto";
- arches[nr + 1] = NULL;
- add_setshow_enum_cmd ("architecture", class_support,
- arches, &set_architecture_string,
- _("Set architecture of target."),
- _("Show architecture of target."), NULL,
- set_architecture, show_architecture,
- &setlist, &showlist);
- add_alias_cmd ("processor", "architecture", class_support, 1, &setlist);
- }
- }
- void
- gdbarch_info_init (struct gdbarch_info *info)
- {
- memset (info, 0, sizeof (struct gdbarch_info));
- info->byte_order = BFD_ENDIAN_UNKNOWN;
- info->byte_order_for_code = info->byte_order;
- info->osabi = GDB_OSABI_UNINITIALIZED;
- }
- void
- gdbarch_info_fill (struct gdbarch_info *info)
- {
-
- if (info->bfd_arch_info == NULL
- && target_architecture_user)
- info->bfd_arch_info = target_architecture_user;
-
- if (info->bfd_arch_info == NULL
- && info->abfd != NULL
- && bfd_get_arch (info->abfd) != bfd_arch_unknown
- && bfd_get_arch (info->abfd) != bfd_arch_obscure)
- info->bfd_arch_info = bfd_get_arch_info (info->abfd);
-
- if (info->target_desc != NULL)
- info->bfd_arch_info = choose_architecture_for_target
- (info->target_desc, info->bfd_arch_info);
-
- if (info->bfd_arch_info == NULL)
- info->bfd_arch_info = default_bfd_arch;
-
- if (info->byte_order == BFD_ENDIAN_UNKNOWN
- && target_byte_order_user != BFD_ENDIAN_UNKNOWN)
- info->byte_order = target_byte_order_user;
-
- if (info->byte_order == BFD_ENDIAN_UNKNOWN
- && info->abfd != NULL)
- info->byte_order = (bfd_big_endian (info->abfd) ? BFD_ENDIAN_BIG
- : bfd_little_endian (info->abfd) ? BFD_ENDIAN_LITTLE
- : BFD_ENDIAN_UNKNOWN);
-
- if (info->byte_order == BFD_ENDIAN_UNKNOWN)
- info->byte_order = default_byte_order;
- info->byte_order_for_code = info->byte_order;
-
-
- if (info->osabi == GDB_OSABI_UNINITIALIZED)
- info->osabi = gdbarch_lookup_osabi (info->abfd);
-
- if (info->osabi == GDB_OSABI_UNKNOWN && info->target_desc != NULL)
- info->osabi = tdesc_osabi (info->target_desc);
-
- #ifdef GDB_OSABI_DEFAULT
- if (info->osabi == GDB_OSABI_UNKNOWN)
- info->osabi = GDB_OSABI_DEFAULT;
- #endif
-
- gdb_assert (info->bfd_arch_info != NULL);
- }
- struct gdbarch *
- get_current_arch (void)
- {
- if (has_stack_frames ())
- return get_frame_arch (get_selected_frame (NULL));
- else
- return target_gdbarch ();
- }
- int
- default_has_shared_address_space (struct gdbarch *gdbarch)
- {
-
- return 0;
- }
- int
- default_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
- CORE_ADDR addr, int *isize, char **msg)
- {
-
- if (msg)
- *msg = NULL;
- return 1;
- }
- void
- default_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *kindptr)
- {
- gdbarch_breakpoint_from_pc (gdbarch, pcptr, kindptr);
- }
- void
- default_gen_return_address (struct gdbarch *gdbarch,
- struct agent_expr *ax, struct axs_value *value,
- CORE_ADDR scope)
- {
- error (_("This architecture has no method to collect a return address."));
- }
- int
- default_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
- struct type *type)
- {
-
- return language_pass_by_reference (type);
- }
- int default_insn_is_call (struct gdbarch *gdbarch, CORE_ADDR addr)
- {
- return 0;
- }
- int default_insn_is_ret (struct gdbarch *gdbarch, CORE_ADDR addr)
- {
- return 0;
- }
- int default_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr)
- {
- return 0;
- }
- void
- default_skip_permanent_breakpoint (struct regcache *regcache)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- CORE_ADDR current_pc = regcache_read_pc (regcache);
- const gdb_byte *bp_insn;
- int bp_len;
- bp_insn = gdbarch_breakpoint_from_pc (gdbarch, ¤t_pc, &bp_len);
- current_pc += bp_len;
- regcache_write_pc (regcache, current_pc);
- }
- CORE_ADDR
- default_infcall_mmap (CORE_ADDR size, unsigned prot)
- {
- error (_("This target does not support inferior memory allocation by mmap."));
- }
- char *
- default_gcc_target_options (struct gdbarch *gdbarch)
- {
- return xstrprintf ("-m%d%s", gdbarch_ptr_bit (gdbarch),
- gdbarch_ptr_bit (gdbarch) == 64 ? " -mcmodel=large" : "");
- }
- const char *
- default_gnu_triplet_regexp (struct gdbarch *gdbarch)
- {
- return gdbarch_bfd_arch_info (gdbarch)->arch_name;
- }
- extern initialize_file_ftype _initialize_gdbarch_utils;
- void
- _initialize_gdbarch_utils (void)
- {
- add_setshow_enum_cmd ("endian", class_support,
- endian_enum, &set_endian_string,
- _("Set endianness of target."),
- _("Show endianness of target."),
- NULL, set_endian, show_endian,
- &setlist, &showlist);
- }