X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Farch-utils.c;h=c3d78024131235e7a8b6ac2fd3983852089c4203;hb=484b3c325d8182cd7b7da4ceeaedc238c7f80b5c;hp=55011754bcd9cc39139749bb79dfb37603a6e6f7;hpb=7a697b8dd7ac3c14e35ae3026d955aeae3ecc054;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 55011754bc..c3d7802413 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -1,7 +1,6 @@ /* Dynamic architecture support for GDB, the GNU debugger. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 1998-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -23,15 +22,16 @@ #include "arch-utils.h" #include "buildsym.h" #include "gdbcmd.h" -#include "inferior.h" /* enum CALL_DUMMY_LOCATION et.al. */ -#include "gdb_string.h" +#include "inferior.h" /* enum CALL_DUMMY_LOCATION et al. */ +#include "infrun.h" #include "regcache.h" -#include "gdb_assert.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" @@ -44,7 +44,7 @@ simple_displaced_step_copy_insn (struct gdbarch *gdbarch, struct regcache *regs) { size_t len = gdbarch_max_insn_length (gdbarch); - gdb_byte *buf = xmalloc (len); + gdb_byte *buf = (gdb_byte *) xmalloc (len); read_memory (from, buf, len); write_memory (to, buf, len); @@ -121,13 +121,13 @@ generic_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) int generic_in_solib_return_trampoline (struct gdbarch *gdbarch, - CORE_ADDR pc, char *name) + CORE_ADDR pc, const char *name) { return 0; } int -generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +generic_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) { return 0; } @@ -146,7 +146,7 @@ core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs) return (lhs > rhs); } -/* Misc helper functions for targets. */ +/* Misc helper functions for targets. */ CORE_ADDR core_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr) @@ -168,17 +168,35 @@ no_op_reg_to_regnum (struct gdbarch *gdbarch, int reg) } void -default_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym) +default_coff_make_msymbol_special (int val, struct minimal_symbol *msym) { return; } +/* See arch-utils.h. */ + void -default_coff_make_msymbol_special (int val, struct minimal_symbol *msym) +default_make_symbol_special (struct symbol *sym, struct objfile *objfile) { return; } +/* See arch-utils.h. */ + +CORE_ADDR +default_adjust_dwarf2_addr (CORE_ADDR pc) +{ + return pc; +} + +/* See arch-utils.h. */ + +CORE_ADDR +default_adjust_dwarf2_line (CORE_ADDR addr, int rel) +{ + return addr; +} + int cannot_register_not (struct gdbarch *gdbarch, int regnum) { @@ -186,8 +204,8 @@ cannot_register_not (struct gdbarch *gdbarch, int regnum) } /* Legacy version of target_virtual_frame_pointer(). Assumes that - there is an gdbarch_deprecated_fp_regnum and that it is the same, cooked or - raw. */ + there is an gdbarch_deprecated_fp_regnum and that it is the same, + cooked or raw. */ void legacy_virtual_frame_pointer (struct gdbarch *gdbarch, @@ -211,7 +229,8 @@ legacy_virtual_frame_pointer (struct gdbarch *gdbarch, else /* Should this be an internal error? I guess so, it is reflecting an architectural limitation in the current design. */ - internal_error (__FILE__, __LINE__, _("No virtual frame pointer available")); + internal_error (__FILE__, __LINE__, + _("No virtual frame pointer available")); *frame_offset = 0; } @@ -243,15 +262,23 @@ default_remote_register_number (struct gdbarch *gdbarch, return regno; } +/* See arch-utils.h. */ + +int +default_vsyscall_range (struct gdbarch *gdbarch, struct mem_range *range) +{ + return 0; +} + /* Functions to manipulate the endianness of the target. */ -static int target_byte_order_user = BFD_ENDIAN_UNKNOWN; +static enum bfd_endian 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 *endian_enum[] = +static const char *const endian_enum[] = { endian_big, endian_little, @@ -278,7 +305,7 @@ show_endian (struct ui_file *file, int from_tty, struct cmd_list_element *c, "(currently big endian)\n")); else fprintf_unfiltered (file, _("The target endianness is set automatically " - "(currently little endian)\n")); + "(currently little endian)\n")); else if (target_byte_order_user == BFD_ENDIAN_BIG) fprintf_unfiltered (file, @@ -373,8 +400,9 @@ choose_architecture_for_target (const struct target_desc *target_desc, if (compat1 == NULL && compat2 == NULL) { - /* BFD considers the architectures incompatible. Check our target - description whether it accepts SELECTED as compatible anyway. */ + /* BFD considers the architectures incompatible. Check our + target description whether it accepts SELECTED as compatible + anyway. */ if (tdesc_compatible_p (target_desc, selected)) return from_target; @@ -391,10 +419,10 @@ choose_architecture_for_target (const struct target_desc *target_desc, if (compat1 == compat2) return compat1; - /* If the two didn't match, but one of them was a default architecture, - assume the more specific one is correct. This handles the case - where an executable or target description just says "mips", but - the other knows which MIPS variant. */ + /* If the two didn't match, but one of them was a default + architecture, assume the more specific one is correct. This + handles the case where an executable or target description just + says "mips", but the other knows which MIPS variant. */ if (compat1->the_default) return compat2; if (compat2->the_default) @@ -408,7 +436,7 @@ choose_architecture_for_target (const struct target_desc *target_desc, return selected; } -/* Functions to manipulate the architecture of the target */ +/* Functions to manipulate the architecture of the target. */ enum set_arch { set_arch_auto, set_arch_manual }; @@ -426,24 +454,24 @@ selected_architecture_name (void) } /* Called if the user enters ``show architecture'' without an - argument. */ + argument. */ 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); + 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); + fprintf_filtered (file, _("The target architecture is assumed to be %s\n"), + set_architecture_string); } /* Called if the user enters ``set architecture'' with or without an - argument. */ + argument. */ static void set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c) @@ -475,7 +503,7 @@ set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c) } /* Try to select a global architecture that matches "info". Return - non-zero if the attempt succeds. */ + non-zero if the attempt succeeds. */ int gdbarch_update_p (struct gdbarch_info info) { @@ -504,7 +532,7 @@ gdbarch_update_p (struct gdbarch_info info) /* If it is the same old architecture, accept the request (but don't swap anything). */ - if (new_gdbarch == target_gdbarch) + if (new_gdbarch == target_gdbarch ()) { if (gdbarch_debug) fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: " @@ -520,7 +548,7 @@ gdbarch_update_p (struct gdbarch_info info) "New architecture %s (%s) selected\n", host_address_to_string (new_gdbarch), gdbarch_bfd_arch_info (new_gdbarch)->printable_name); - deprecated_target_gdbarch_select_hack (new_gdbarch); + set_target_gdbarch (new_gdbarch); return 1; } @@ -533,6 +561,7 @@ gdbarch_from_bfd (bfd *abfd) { struct gdbarch_info info; gdbarch_info_init (&info); + info.abfd = abfd; return gdbarch_find_by_info (info); } @@ -553,7 +582,7 @@ set_gdbarch_from_file (bfd *abfd) if (gdbarch == NULL) error (_("Architecture of file not recognized.")); - deprecated_target_gdbarch_select_hack (gdbarch); + set_target_gdbarch (gdbarch); } /* Initialize the current architecture. Update the ``set @@ -574,22 +603,22 @@ static const bfd_target *default_bfd_vec = &DEFAULT_BFD_VEC; static const bfd_target *default_bfd_vec; #endif -static int default_byte_order = BFD_ENDIAN_UNKNOWN; +static enum bfd_endian default_byte_order = BFD_ENDIAN_UNKNOWN; void initialize_current_architecture (void) { const char **arches = gdbarch_printable_names (); - - /* determine a default architecture and byte order. */ struct gdbarch_info info; + + /* determine a default architecture and byte order. */ gdbarch_info_init (&info); - /* Find a default architecture. */ + /* Find a default architecture. */ if (default_bfd_arch == NULL) { /* Choose the architecture by taking the first one - alphabetically. */ + alphabetically. */ const char *chosen = arches[0]; const char **arch; for (arch = arches; *arch != NULL; arch++) @@ -612,7 +641,7 @@ initialize_current_architecture (void) if (default_byte_order == BFD_ENDIAN_UNKNOWN && default_bfd_vec != NULL) { - /* Extract BFD's default vector's byte order. */ + /* Extract BFD's default vector's byte order. */ switch (default_bfd_vec->byteorder) { case BFD_ENDIAN_BIG: @@ -627,12 +656,12 @@ initialize_current_architecture (void) } if (default_byte_order == BFD_ENDIAN_UNKNOWN) { - /* look for ``*el-*'' in the target name. */ + /* look for ``*el-*'' in the target name. */ const char *chp; chp = strchr (target_name, '-'); if (chp != NULL && chp - 2 >= target_name - && strncmp (chp - 2, "el", 2) == 0) + && startswith (chp - 2, "el")) default_byte_order = BFD_ENDIAN_LITTLE; } if (default_byte_order == BFD_ENDIAN_UNKNOWN) @@ -650,19 +679,18 @@ initialize_current_architecture (void) "initial architecture failed")); /* Create the ``set architecture'' command appending ``auto'' to the - list of architectures. */ + list of architectures. */ { - struct cmd_list_element *c; - /* Append ``auto''. */ + /* Append ``auto''. */ int nr; for (nr = 0; arches[nr] != NULL; nr++); - arches = xrealloc (arches, sizeof (char*) * (nr + 2)); + arches = XRESIZEVEC (const char *, arches, 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, + 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); @@ -742,19 +770,20 @@ gdbarch_info_fill (struct gdbarch_info *info) gdb_assert (info->bfd_arch_info != NULL); } -/* Return "current" architecture. If the target is running, this is the - architecture of the selected frame. Otherwise, the "current" architecture - defaults to the target architecture. +/* Return "current" architecture. If the target is running, this is + the architecture of the selected frame. Otherwise, the "current" + architecture defaults to the target architecture. - This function should normally be called solely by the command interpreter - routines to determine the architecture to execute a command in. */ + This function should normally be called solely by the command + interpreter routines to determine the architecture to execute a + command in. */ struct gdbarch * get_current_arch (void) { if (has_stack_frames ()) return get_frame_arch (get_selected_frame (NULL)); else - return target_gdbarch; + return target_gdbarch (); } int @@ -766,8 +795,8 @@ default_has_shared_address_space (struct gdbarch *gdbarch) } int -default_fast_tracepoint_valid_at (struct gdbarch *gdbarch, - CORE_ADDR addr, int *isize, char **msg) +default_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr, + char **msg) { /* We don't know if maybe the target has some way to do fast tracepoints that doesn't need gdbarch, so always say yes. */ @@ -776,18 +805,131 @@ default_fast_tracepoint_valid_at (struct gdbarch *gdbarch, 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) +{ + /* Usually, the return value's address is stored the in the "first hidden" + parameter if the return value should be passed by reference, as + specified in ABI. */ + 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.")); +} + +void +default_infcall_munmap (CORE_ADDR addr, CORE_ADDR size) +{ + /* Memory reserved by inferior mmap is kept leaked. */ +} + +/* -mcmodel=large is used so that no GOT (Global Offset Table) is needed to be + created in inferior memory by GDB (normally it is set by ld.so). */ + +char * +default_gcc_target_options (struct gdbarch *gdbarch) +{ + return xstrprintf ("-m%d%s", gdbarch_ptr_bit (gdbarch), + gdbarch_ptr_bit (gdbarch) == 64 ? " -mcmodel=large" : ""); +} + +/* gdbarch gnu_triplet_regexp method. */ + +const char * +default_gnu_triplet_regexp (struct gdbarch *gdbarch) +{ + return gdbarch_bfd_arch_info (gdbarch)->arch_name; +} + +/* Default method for gdbarch_addressable_memory_unit_size. By default, a memory byte has + a size of 1 octet. */ + +int +default_addressable_memory_unit_size (struct gdbarch *gdbarch) +{ + return 1; +} + +void +default_guess_tracepoint_registers (struct gdbarch *gdbarch, + struct regcache *regcache, + CORE_ADDR addr) +{ + int pc_regno = gdbarch_pc_regnum (gdbarch); + gdb_byte *regs; + + /* This guessing code below only works if the PC register isn't + a pseudo-register. The value of a pseudo-register isn't stored + in the (non-readonly) regcache -- instead it's recomputed + (probably from some other cached raw register) whenever the + register is read. In this case, a custom method implementation + should be used by the architecture. */ + if (pc_regno < 0 || pc_regno >= gdbarch_num_regs (gdbarch)) + return; + + regs = (gdb_byte *) alloca (register_size (gdbarch, pc_regno)); + store_unsigned_integer (regs, register_size (gdbarch, pc_regno), + gdbarch_byte_order (gdbarch), addr); + regcache_raw_supply (regcache, pc_regno, regs); +} -extern initialize_file_ftype _initialize_gdbarch_utils; /* -Wmissing-prototypes */ +/* -Wmissing-prototypes */ +extern initialize_file_ftype _initialize_gdbarch_utils; void _initialize_gdbarch_utils (void) { - struct cmd_list_element *c; 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, + endian_enum, &set_endian_string, + _("Set endianness of target."), + _("Show endianness of target."), + NULL, set_endian, show_endian, &setlist, &showlist); }