X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Falpha-tdep.c;h=d75aebc3451d0f456d4e3b18f6ff06fe66baee7d;hb=f33e9acf1b9d497a366d072caee34548fcfdf1cb;hp=44b85d1c300bfa3ff082b0e3a1f41d8d0ea5ff95;hpb=19772a2ce262d4dfd45428ec7b96c76b46c508e3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 44b85d1c30..d75aebc345 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -40,12 +40,20 @@ #include "arch-utils.h" #include "osabi.h" #include "block.h" +#include "infcall.h" #include "elf-bfd.h" #include "alpha-tdep.h" +/* Return the name of the REGNO register. + + An empty name corresponds to a register number that used to + be used for a virtual register. That virtual register has + been removed, but the index is still reserved to maintain + compatibility with existing remote alpha targets. */ + static const char * alpha_register_name (int regno) { @@ -72,13 +80,15 @@ alpha_register_name (int regno) static int alpha_cannot_fetch_register (int regno) { - return regno == ALPHA_ZERO_REGNUM; + return (regno == ALPHA_ZERO_REGNUM + || strlen (alpha_register_name (regno)) == 0); } static int alpha_cannot_store_register (int regno) { - return regno == ALPHA_ZERO_REGNUM; + return (regno == ALPHA_ZERO_REGNUM + || strlen (alpha_register_name (regno)) == 0); } static struct type * @@ -144,18 +154,6 @@ alpha_register_byte (int regno) return (regno * 8); } -static int -alpha_register_raw_size (int regno) -{ - return 8; -} - -static int -alpha_register_virtual_size (int regno) -{ - return 8; -} - /* The following represents exactly the conversion performed by the LDS instruction. This applies to both single-precision floating point and 32-bit integers. */ @@ -226,7 +224,7 @@ alpha_register_to_value (struct frame_info *frame, int regnum, memcpy (out, in, 8); break; default: - error ("Cannot retrieve value from floating point register"); + error (_("Cannot retrieve value from floating point register")); } } @@ -244,7 +242,7 @@ alpha_value_to_register (struct frame_info *frame, int regnum, memcpy (out, in, 8); break; default: - error ("Cannot store value in floating point register"); + error (_("Cannot store value in floating point register")); } put_frame_register (frame, regnum, out); } @@ -263,7 +261,7 @@ alpha_value_to_register (struct frame_info *frame, int regnum, structure to be returned is passed as a hidden first argument. */ static CORE_ADDR -alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, +alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) @@ -281,6 +279,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, struct alpha_arg *m_arg; char arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS]; int required_arg_regs; + CORE_ADDR func_addr = find_function_addr (function, NULL); /* The ABI places the address of the called function in T12. */ regcache_cooked_write_signed (regcache, ALPHA_T12_REGNUM, func_addr); @@ -293,7 +292,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, for (i = 0, m_arg = alpha_args; i < nargs; i++, m_arg++) { struct value *arg = args[i]; - struct type *arg_type = check_typedef (VALUE_TYPE (arg)); + struct type *arg_type = check_typedef (value_type (arg)); /* Cast argument to long if necessary as the compiler does it too. */ switch (TYPE_CODE (arg_type)) @@ -465,7 +464,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache, break; default: - internal_error (__FILE__, __LINE__, "unknown floating point width"); + internal_error (__FILE__, __LINE__, _("unknown floating point width")); } break; @@ -489,7 +488,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache, break; default: - internal_error (__FILE__, __LINE__, "unknown floating point width"); + internal_error (__FILE__, __LINE__, _("unknown floating point width")); } break; @@ -541,10 +540,10 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache, /* FIXME: 128-bit long doubles are returned like structures: by writing into indirect storage provided by the caller as the first argument. */ - error ("Cannot set a 128-bit long double return value."); + error (_("Cannot set a 128-bit long double return value.")); default: - internal_error (__FILE__, __LINE__, "unknown floating point width"); + internal_error (__FILE__, __LINE__, _("unknown floating point width")); } break; @@ -566,10 +565,10 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache, /* FIXME: 128-bit long doubles are returned like structures: by writing into indirect storage provided by the caller as the first argument. */ - error ("Cannot set a 128-bit long double return value."); + error (_("Cannot set a 128-bit long double return value.")); default: - internal_error (__FILE__, __LINE__, "unknown floating point width"); + internal_error (__FILE__, __LINE__, _("unknown floating point width")); } break; @@ -626,7 +625,7 @@ alpha_read_insn (CORE_ADDR pc) char buf[4]; int status; - status = read_memory_nobpt (pc, buf, 4); + status = deprecated_read_memory_nobpt (pc, buf, 4); if (status) memory_error (status, pc); return extract_unsigned_integer (buf, 4); @@ -863,14 +862,20 @@ alpha_sigtramp_frame_sniffer (struct frame_info *next_frame) CORE_ADDR pc = frame_pc_unwind (next_frame); char *name; - /* We shouldn't even bother to try if the OSABI didn't register - a sigcontext_addr handler. */ - if (!gdbarch_tdep (current_gdbarch)->sigcontext_addr) + /* NOTE: cagney/2004-04-30: Do not copy/clone this code. Instead + look at tramp-frame.h and other simplier per-architecture + sigtramp unwinders. */ + + /* We shouldn't even bother to try if the OSABI didn't register a + sigcontext_addr handler or pc_in_sigtramp hander. */ + if (gdbarch_tdep (current_gdbarch)->sigcontext_addr == NULL) + return NULL; + if (gdbarch_tdep (current_gdbarch)->pc_in_sigtramp == NULL) return NULL; /* Otherwise we should be in a signal frame. */ find_pc_partial_function (pc, &name, NULL, NULL); - if (PC_IN_SIGTRAMP (pc, name)) + if (gdbarch_tdep (current_gdbarch)->pc_in_sigtramp (pc, name)) return &alpha_sigtramp_frame_unwind; return NULL; @@ -950,20 +955,21 @@ alpha_heuristic_proc_start (CORE_ADDR pc) static int blurb_printed = 0; if (fence == tdep->vm_min_address) - warning ("Hit beginning of text section without finding"); + warning (_("Hit beginning of text section without finding \ +enclosing function for address 0x%s"), paddr_nz (orig_pc)); else - warning ("Hit heuristic-fence-post without finding"); - warning ("enclosing function for address 0x%s", paddr_nz (orig_pc)); + warning (_("Hit heuristic-fence-post without finding \ +enclosing function for address 0x%s"), paddr_nz (orig_pc)); if (!blurb_printed) { - printf_filtered ("\ + printf_filtered (_("\ This warning occurs if you are debugging a function without any symbols\n\ (for example, in a stripped executable). In that case, you may wish to\n\ increase the size of the search with the `set heuristic-fence-post' command.\n\ \n\ Otherwise, you told GDB there was a function where there isn't one, or\n\ -(more likely) you have encountered a bug in GDB.\n"); +(more likely) you have encountered a bug in GDB.\n")); blurb_printed = 1; } } @@ -1029,6 +1035,16 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame, { reg = (word & 0x03e00000) >> 21; + /* Ignore this instruction if we have already encountered + an instruction saving the same register earlier in the + function code. The current instruction does not tell + us where the original value upon function entry is saved. + All it says is that the function we are scanning reused + that register for some computation of its own, and is now + saving its result. */ + if (info->saved_regs[reg]) + continue; + if (reg == 31) continue; @@ -1184,8 +1200,8 @@ alpha_heuristic_frame_prev_register (struct frame_info *next_frame, } /* Otherwise assume the next frame has the same register value. */ - frame_register (next_frame, regnum, optimizedp, lvalp, addrp, - realnump, bufferp); + frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp, + realnump, bufferp); } static const struct frame_unwind alpha_heuristic_frame_unwind = { @@ -1227,30 +1243,6 @@ reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c) } -/* ALPHA stack frames are almost impenetrable. When execution stops, - we basically have to look at symbol information for the function - that we stopped in, which tells us *which* register (if any) is - the base of the frame pointer, and what offset from that register - the frame itself is at. - - This presents a problem when trying to examine a stack in memory - (that isn't executing at the moment), using the "frame" command. We - don't have a PC, nor do we have any registers except SP. - - This routine takes two arguments, SP and PC, and tries to make the - cached frames look as if these two arguments defined a frame on the - cache. This allows the rest of info frame to extract the important - arguments without difficulty. */ - -struct frame_info * -alpha_setup_arbitrary_frame (int argc, CORE_ADDR *argv) -{ - if (argc != 2) - error ("ALPHA frame specifications require two arguments: sp and pc"); - - return create_new_frame (argv[0], argv[1]); -} - /* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that dummy frame. The frame ID's base needs to match the TOS value saved by save_dummy_frame_tos(), and the PC match the dummy frame's @@ -1285,16 +1277,16 @@ alpha_supply_int_regs (int regno, const void *r0_r30, for (i = 0; i < 31; ++i) if (regno == i || regno == -1) - supply_register (i, (const char *)r0_r30 + i*8); + regcache_raw_supply (current_regcache, i, (const char *)r0_r30 + i*8); if (regno == ALPHA_ZERO_REGNUM || regno == -1) - supply_register (ALPHA_ZERO_REGNUM, NULL); + regcache_raw_supply (current_regcache, ALPHA_ZERO_REGNUM, NULL); if (regno == ALPHA_PC_REGNUM || regno == -1) - supply_register (ALPHA_PC_REGNUM, pc); + regcache_raw_supply (current_regcache, ALPHA_PC_REGNUM, pc); if (regno == ALPHA_UNIQUE_REGNUM || regno == -1) - supply_register (ALPHA_UNIQUE_REGNUM, unique); + regcache_raw_supply (current_regcache, ALPHA_UNIQUE_REGNUM, unique); } void @@ -1304,13 +1296,13 @@ alpha_fill_int_regs (int regno, void *r0_r30, void *pc, void *unique) for (i = 0; i < 31; ++i) if (regno == i || regno == -1) - regcache_collect (i, (char *)r0_r30 + i*8); + regcache_raw_collect (current_regcache, i, (char *)r0_r30 + i*8); if (regno == ALPHA_PC_REGNUM || regno == -1) - regcache_collect (ALPHA_PC_REGNUM, pc); + regcache_raw_collect (current_regcache, ALPHA_PC_REGNUM, pc); if (unique && (regno == ALPHA_UNIQUE_REGNUM || regno == -1)) - regcache_collect (ALPHA_UNIQUE_REGNUM, unique); + regcache_raw_collect (current_regcache, ALPHA_UNIQUE_REGNUM, unique); } void @@ -1320,10 +1312,11 @@ alpha_supply_fp_regs (int regno, const void *f0_f30, const void *fpcr) for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i) if (regno == i || regno == -1) - supply_register (i, (const char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); + regcache_raw_supply (current_regcache, i, + (const char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); if (regno == ALPHA_FPCR_REGNUM || regno == -1) - supply_register (ALPHA_FPCR_REGNUM, fpcr); + regcache_raw_supply (current_regcache, ALPHA_FPCR_REGNUM, fpcr); } void @@ -1333,10 +1326,11 @@ alpha_fill_fp_regs (int regno, void *f0_f30, void *fpcr) for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i) if (regno == i || regno == -1) - regcache_collect (i, (char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); + regcache_raw_collect (current_regcache, i, + (char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); if (regno == ALPHA_FPCR_REGNUM || regno == -1) - regcache_collect (ALPHA_FPCR_REGNUM, fpcr); + regcache_raw_collect (current_regcache, ALPHA_FPCR_REGNUM, fpcr); } @@ -1483,7 +1477,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Lowest text address. This is used by heuristic_proc_start() to decide when to stop looking. */ - tdep->vm_min_address = (CORE_ADDR) 0x120000000; + tdep->vm_min_address = (CORE_ADDR) 0x120000000LL; tdep->dynamic_sigtramp_offset = NULL; tdep->sigcontext_addr = NULL; @@ -1511,8 +1505,6 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_name (gdbarch, alpha_register_name); set_gdbarch_deprecated_register_byte (gdbarch, alpha_register_byte); - set_gdbarch_deprecated_register_raw_size (gdbarch, alpha_register_raw_size); - set_gdbarch_deprecated_register_virtual_size (gdbarch, alpha_register_virtual_size); set_gdbarch_register_type (gdbarch, alpha_register_type); set_gdbarch_cannot_fetch_register (gdbarch, alpha_cannot_fetch_register); @@ -1532,7 +1524,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Call info. */ - set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention); + set_gdbarch_deprecated_use_struct_convention (gdbarch, always_use_struct_convention); set_gdbarch_extract_return_value (gdbarch, alpha_extract_return_value); set_gdbarch_store_return_value (gdbarch, alpha_store_return_value); set_gdbarch_deprecated_extract_struct_value_address (gdbarch, alpha_extract_struct_value_address); @@ -1590,16 +1582,20 @@ _initialize_alpha_tdep (void) /* We really would like to have both "0" and "unlimited" work, but command.c doesn't deal with that. So make it a var_zinteger because the user can always use "999999" or some such for unlimited. */ - c = add_set_cmd ("heuristic-fence-post", class_support, var_zinteger, - (char *) &heuristic_fence_post, - "\ -Set the distance searched for the start of a function.\n\ -If you are debugging a stripped executable, GDB needs to search through the\n\ -program for the start of a function. This command sets the distance of the\n\ -search. The only need to set it is when debugging a stripped executable.", - &setlist); /* We need to throw away the frame cache when we set this, since it might change our ability to get backtraces. */ - set_cmd_sfunc (c, reinit_frame_cache_sfunc); - add_show_from_set (c, &showlist); + add_setshow_zinteger_cmd ("heuristic-fence-post", class_support, + &heuristic_fence_post, + _("\ +Set the distance searched for the start of a function."), + _("\ +Show the distance searched for the start of a function."), + _("\ +If you are debugging a stripped executable, GDB needs to search through the\n\ +program for the start of a function. This command sets the distance of the\n\ +search. The only need to set it is when debugging a stripped executable."), + _("\ +The distance searched for the start of a function is \"%d\"."), + reinit_frame_cache_sfunc, NULL, + &setlist, &showlist); }