X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Favr-tdep.c;h=3db8530c14dde88c97518dbf3f6bbf03a9ef6d94;hb=7160c4c357f1e15085c0cd6c9d56b5035f356f6e;hp=aeb901f3117309ed76441efb437ddff72c34c3a9;hpb=dcccef2efbd4ebe18f8a0324076739fb619bd861;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index aeb901f311..3db8530c14 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -1,12 +1,13 @@ /* Target-dependent code for Atmel AVR, for GDB. - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 - Free Software Foundation, Inc. + + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006, 2007 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,9 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ /* Contributed by Theodore A. Roth, troth@openavr.org */ @@ -31,11 +30,13 @@ #include "trad-frame.h" #include "gdbcmd.h" #include "gdbcore.h" +#include "gdbtypes.h" #include "inferior.h" #include "symfile.h" #include "arch-utils.h" #include "regcache.h" #include "gdb_string.h" +#include "dis-asm.h" /* AVR Background: @@ -225,12 +226,6 @@ avr_make_iaddr (CORE_ADDR x) return ((x) | AVR_IMEM_START); } -static int -avr_iaddr_p (CORE_ADDR x) -{ - return (((x) & AVR_MEM_MASK) == AVR_IMEM_START); -} - /* FIXME: TRoth: Really need to use a larger mask for instructions. Some devices are already up to 128KBytes of flash space. @@ -250,12 +245,6 @@ avr_make_saddr (CORE_ADDR x) return ((x) | AVR_SMEM_START); } -static int -avr_saddr_p (CORE_ADDR x) -{ - return (((x) & AVR_MEM_MASK) == AVR_SMEM_START); -} - static CORE_ADDR avr_convert_saddr_to_raw (CORE_ADDR x) { @@ -289,7 +278,7 @@ avr_convert_saddr_to_raw (CORE_ADDR x) /* Convert from address to pointer and vice-versa. */ static void -avr_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr) +avr_address_to_pointer (struct type *type, gdb_byte *buf, CORE_ADDR addr) { /* Is it a code address? */ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC @@ -307,7 +296,7 @@ avr_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr) } static CORE_ADDR -avr_pointer_to_address (struct type *type, const void *buf) +avr_pointer_to_address (struct type *type, const gdb_byte *buf) { CORE_ADDR addr = extract_unsigned_integer (buf, TYPE_LENGTH (type)); @@ -321,35 +310,18 @@ avr_pointer_to_address (struct type *type, const void *buf) } static CORE_ADDR -avr_read_pc (ptid_t ptid) +avr_read_pc (struct regcache *regcache) { - ptid_t save_ptid; - CORE_ADDR pc; - CORE_ADDR retval; - - save_ptid = inferior_ptid; - inferior_ptid = ptid; - pc = (int) read_register (AVR_PC_REGNUM); - inferior_ptid = save_ptid; - retval = avr_make_iaddr (pc); - return retval; + ULONGEST pc; + regcache_cooked_read_unsigned (regcache, AVR_PC_REGNUM, &pc); + return avr_make_iaddr (pc); } static void -avr_write_pc (CORE_ADDR val, ptid_t ptid) -{ - ptid_t save_ptid; - - save_ptid = inferior_ptid; - inferior_ptid = ptid; - write_register (AVR_PC_REGNUM, avr_convert_iaddr_to_raw (val)); - inferior_ptid = save_ptid; -} - -static CORE_ADDR -avr_read_sp (void) +avr_write_pc (struct regcache *regcache, CORE_ADDR val) { - return (avr_make_saddr (read_register (AVR_SP_REGNUM))); + regcache_cooked_write_unsigned (regcache, AVR_PC_REGNUM, + avr_convert_iaddr_to_raw (val)); } static int @@ -596,7 +568,7 @@ avr_scan_prologue (CORE_ADDR pc, struct avr_unwind_cache *info) if (num_pushes > AVR_MAX_PUSHES) { - fprintf_unfiltered (gdb_stderr, "Num pushes too large: %d\n", + fprintf_unfiltered (gdb_stderr, _("Num pushes too large: %d\n"), num_pushes); num_pushes = 0; } @@ -675,7 +647,7 @@ avr_scan_prologue (CORE_ADDR pc, struct avr_unwind_cache *info) if (vpc >= AVR_MAX_PROLOGUE_SIZE) fprintf_unfiltered (gdb_stderr, - "Hit end of prologue while scanning pushes\n"); + _("Hit end of prologue while scanning pushes\n")); /* Second stage of the prologue scanning. Scan: @@ -771,14 +743,6 @@ avr_scan_prologue (CORE_ADDR pc, struct avr_unwind_cache *info) return pc + avr_scan_arg_moves (vpc, prologue);; } -/* Returns the return address for a dummy. */ - -static CORE_ADDR -avr_call_dummy_address (void) -{ - return entry_point_address (); -} - static CORE_ADDR avr_skip_prologue (CORE_ADDR pc) { @@ -801,7 +765,9 @@ avr_skip_prologue (CORE_ADDR pc) prologue_end = avr_scan_prologue (pc, &info); - if (info.prologue_type != AVR_PROLOGUE_NONE) + if (info.prologue_type == AVR_PROLOGUE_NONE) + return pc; + else { sal = find_pc_line (func_addr, 0); @@ -836,7 +802,7 @@ avr_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr) static void avr_extract_return_value (struct type *type, struct regcache *regcache, - void *valbuf) + gdb_byte *valbuf) { ULONGEST r24, r25; ULONGEST c; @@ -861,76 +827,6 @@ avr_extract_return_value (struct type *type, struct regcache *regcache, } } -static void -avr_saved_regs_unwinder (struct frame_info *next_frame, - struct trad_frame_saved_reg *this_saved_regs, - int regnum, int *optimizedp, - enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *bufferp) -{ - if (this_saved_regs[regnum].addr != 0) - { - *optimizedp = 0; - *lvalp = lval_memory; - *addrp = this_saved_regs[regnum].addr; - *realnump = -1; - if (bufferp != NULL) - { - /* Read the value in from memory. */ - - if (regnum == AVR_PC_REGNUM) - { - /* Reading the return PC from the PC register is slightly - abnormal. register_size(AVR_PC_REGNUM) says it is 4 bytes, - but in reality, only two bytes (3 in upcoming mega256) are - stored on the stack. - - Also, note that the value on the stack is an addr to a word - not a byte, so we will need to multiply it by two at some - point. - - And to confuse matters even more, the return address stored - on the stack is in big endian byte order, even though most - everything else about the avr is little endian. Ick! */ - - /* FIXME: number of bytes read here will need updated for the - mega256 when it is available. */ - - ULONGEST pc; - unsigned char tmp; - unsigned char buf[2]; - - read_memory (this_saved_regs[regnum].addr, buf, 2); - - /* Convert the PC read from memory as a big-endian to - little-endian order. */ - tmp = buf[0]; - buf[0] = buf[1]; - buf[1] = tmp; - - pc = (extract_unsigned_integer (buf, 2) * 2); - store_unsigned_integer (bufferp, - register_size (current_gdbarch, regnum), - pc); - } - else - { - read_memory (this_saved_regs[regnum].addr, bufferp, - register_size (current_gdbarch, regnum)); - } - } - - return; - } - - /* No luck, assume this and the next frame have the same register - value. If a value is needed, pass the request on down the chain; - otherwise just return an indication that the value is in the same - register as the next frame. */ - frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp, - realnump, bufferp); -} - /* Put here the code to store, into fi->saved_regs, the addresses of the saved registers of frame described by FRAME_INFO. This includes special registers such as pc and fp saved in special ways @@ -957,12 +853,13 @@ avr_frame_unwind_cache (struct frame_info *next_frame, info->size = 0; info->prologue_type = AVR_PROLOGUE_NONE; - pc = frame_func_unwind (next_frame); + pc = frame_func_unwind (next_frame, NORMAL_FRAME); if ((pc > 0) && (pc < frame_pc_unwind (next_frame))) avr_scan_prologue (pc, info); - if (info->prologue_type != AVR_PROLOGUE_NONE) + if ((info->prologue_type != AVR_PROLOGUE_NONE) + && (info->prologue_type != AVR_PROLOGUE_MAIN)) { ULONGEST high_base; /* High byte of FP */ @@ -992,9 +889,8 @@ avr_frame_unwind_cache (struct frame_info *next_frame, info->base = avr_make_saddr (this_base); /* Adjust all the saved registers so that they contain addresses and not - offsets. We need to add one to the addresses since push ops are post - decrement on the avr. */ - for (i = 0; i < NUM_REGS - 1; i++) + offsets. */ + for (i = 0; i < gdbarch_num_regs (current_gdbarch) - 1; i++) if (info->saved_regs[i].addr) { info->saved_regs[i].addr = (info->prev_sp - info->saved_regs[i].addr); @@ -1008,6 +904,10 @@ avr_frame_unwind_cache (struct frame_info *next_frame, info->saved_regs[AVR_PC_REGNUM].addr = info->prev_sp; } + /* The previous frame's SP needed to be computed. Save the computed + value. */ + trad_frame_set_value (info->saved_regs, AVR_SP_REGNUM, info->prev_sp+1); + return info; } @@ -1021,6 +921,16 @@ avr_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) return avr_make_iaddr (pc); } +static CORE_ADDR +avr_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + ULONGEST sp; + + frame_unwind_unsigned_register (next_frame, AVR_SP_REGNUM, &sp); + + return avr_make_saddr (sp); +} + /* Given a GDB frame, determine the address of the calling function's frame. This will be used to create a new GDB frame struct. */ @@ -1036,12 +946,7 @@ avr_frame_this_id (struct frame_info *next_frame, struct frame_id id; /* The FUNC is easy. */ - func = frame_func_unwind (next_frame); - - /* This is meant to halt the backtrace at "_start". Make sure we - don't halt it at a generic dummy frame. */ - if (inside_entry_file (func)) - return; + func = frame_func_unwind (next_frame, NORMAL_FRAME); /* Hopefully the prologue analysis either correctly determined the frame's base (which is the SP from the previous frame), or set @@ -1051,16 +956,6 @@ avr_frame_this_id (struct frame_info *next_frame, return; id = frame_id_build (base, func); - - /* Check that we're not going round in circles with the same frame - ID (but avoid applying the test to sentinel frames which do go - round in circles). Can't use frame_id_eq() as that doesn't yet - compare the frame's PC value. */ - if (frame_relative_level (next_frame) >= 0 - && get_frame_type (next_frame) != DUMMY_FRAME - && frame_id_eq (get_frame_id (next_frame), id)) - return; - (*this_id) = id; } @@ -1069,13 +964,59 @@ avr_frame_prev_register (struct frame_info *next_frame, void **this_prologue_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *bufferp) + int *realnump, gdb_byte *bufferp) { struct avr_unwind_cache *info = avr_frame_unwind_cache (next_frame, this_prologue_cache); - avr_saved_regs_unwinder (next_frame, info->saved_regs, regnum, optimizedp, - lvalp, addrp, realnump, bufferp); + if (regnum == AVR_PC_REGNUM) + { + if (trad_frame_addr_p (info->saved_regs, regnum)) + { + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = info->saved_regs[regnum].addr; + *realnump = -1; + if (bufferp != NULL) + { + /* Reading the return PC from the PC register is slightly + abnormal. register_size(AVR_PC_REGNUM) says it is 4 bytes, + but in reality, only two bytes (3 in upcoming mega256) are + stored on the stack. + + Also, note that the value on the stack is an addr to a word + not a byte, so we will need to multiply it by two at some + point. + + And to confuse matters even more, the return address stored + on the stack is in big endian byte order, even though most + everything else about the avr is little endian. Ick! */ + + /* FIXME: number of bytes read here will need updated for the + mega256 when it is available. */ + + ULONGEST pc; + unsigned char tmp; + unsigned char buf[2]; + + read_memory (info->saved_regs[regnum].addr, buf, 2); + + /* Convert the PC read from memory as a big-endian to + little-endian order. */ + tmp = buf[0]; + buf[0] = buf[1]; + buf[1] = tmp; + + pc = (extract_unsigned_integer (buf, 2) * 2); + store_unsigned_integer (bufferp, + register_size (current_gdbarch, regnum), + pc); + } + } + } + else + trad_frame_get_prev_register (next_frame, info->saved_regs, regnum, + optimizedp, lvalp, addrp, realnump, bufferp); } static const struct frame_unwind avr_frame_unwind = { @@ -1085,7 +1026,7 @@ static const struct frame_unwind avr_frame_unwind = { }; const struct frame_unwind * -avr_frame_p (CORE_ADDR pc) +avr_frame_sniffer (struct frame_info *next_frame) { return &avr_frame_unwind; } @@ -1130,10 +1071,8 @@ struct stack_item void *data; }; -static struct stack_item *push_stack_item (struct stack_item *prev, - void *contents, int len); static struct stack_item * -push_stack_item (struct stack_item *prev, void *contents, int len) +push_stack_item (struct stack_item *prev, const bfd_byte *contents, int len) { struct stack_item *si; si = xmalloc (sizeof (struct stack_item)); @@ -1195,7 +1134,7 @@ pop_stack_item (struct stack_item *si) registers R0 to R2. */ static CORE_ADDR -avr_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, +avr_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) @@ -1211,8 +1150,8 @@ avr_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, if (struct_return) { fprintf_unfiltered (gdb_stderr, "struct_return: 0x%lx\n", struct_addr); - write_register (argreg--, struct_addr & 0xff); - write_register (argreg--, (struct_addr >>8) & 0xff); + regcache_cooked_write_unsigned (regcache, argreg--, struct_addr & 0xff); + regcache_cooked_write_unsigned (regcache, argreg--, (struct_addr >>8) & 0xff); } #endif @@ -1221,8 +1160,8 @@ avr_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, int last_regnum; int j; struct value *arg = args[i]; - struct type *type = check_typedef (VALUE_TYPE (arg)); - char *contents = VALUE_CONTENTS (arg); + struct type *type = check_typedef (value_type (arg)); + const bfd_byte *contents = value_contents (arg); int len = TYPE_LENGTH (type); /* Calculate the potential last register needed. */ @@ -1312,19 +1251,17 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_addr_bit (gdbarch, 32); - set_gdbarch_bfd_vma_bit (gdbarch, 32); /* FIXME: TRoth/2002-02-18: Is this needed? */ set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT); - set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little); - set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_little); - set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_single_little); + set_gdbarch_float_format (gdbarch, floatformats_ieee_single); + set_gdbarch_double_format (gdbarch, floatformats_ieee_single); + set_gdbarch_long_double_format (gdbarch, floatformats_ieee_single); set_gdbarch_read_pc (gdbarch, avr_read_pc); set_gdbarch_write_pc (gdbarch, avr_write_pc); - set_gdbarch_read_sp (gdbarch, avr_read_sp); set_gdbarch_num_regs (gdbarch, AVR_NUM_REGS); @@ -1337,32 +1274,23 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_extract_return_value (gdbarch, avr_extract_return_value); set_gdbarch_print_insn (gdbarch, print_insn_avr); - set_gdbarch_call_dummy_address (gdbarch, avr_call_dummy_address); set_gdbarch_push_dummy_call (gdbarch, avr_push_dummy_call); set_gdbarch_address_to_pointer (gdbarch, avr_address_to_pointer); set_gdbarch_pointer_to_address (gdbarch, avr_pointer_to_address); - set_gdbarch_use_struct_convention (gdbarch, generic_use_struct_convention); - set_gdbarch_skip_prologue (gdbarch, avr_skip_prologue); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - set_gdbarch_decr_pc_after_break (gdbarch, 0); set_gdbarch_breakpoint_from_pc (gdbarch, avr_breakpoint_from_pc); - set_gdbarch_function_start_offset (gdbarch, 0); - - set_gdbarch_frame_args_skip (gdbarch, 0); - set_gdbarch_frameless_function_invocation (gdbarch, - frameless_look_for_prologue); - - frame_unwind_append_predicate (gdbarch, avr_frame_p); + frame_unwind_append_sniffer (gdbarch, avr_frame_sniffer); frame_base_set_default (gdbarch, &avr_frame_base); set_gdbarch_unwind_dummy_id (gdbarch, avr_unwind_dummy_id); set_gdbarch_unwind_pc (gdbarch, avr_unwind_pc); + set_gdbarch_unwind_sp (gdbarch, avr_unwind_sp); return gdbarch; } @@ -1383,48 +1311,39 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) static void avr_io_reg_read_command (char *args, int from_tty) { - int bufsiz = 0; - char buf[400]; + LONGEST bufsiz = 0; + gdb_byte *buf; char query[400]; char *p; unsigned int nreg = 0; unsigned int val; int i, j, k, step; - if (!current_target.to_query) - { - fprintf_unfiltered (gdb_stderr, - "ERR: info io_registers NOT supported by current " - "target\n"); - return; - } - - /* Just get the maximum buffer size. */ - target_query ((int) 'R', 0, 0, &bufsiz); - if (bufsiz > sizeof (buf)) - bufsiz = sizeof (buf); - /* Find out how many io registers the target has. */ - strcpy (query, "avr.io_reg"); - target_query ((int) 'R', query, buf, &bufsiz); + bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR, + "avr.io_reg", &buf); - if (strncmp (buf, "", bufsiz) == 0) + if (bufsiz <= 0) { fprintf_unfiltered (gdb_stderr, - "info io_registers NOT supported by target\n"); + _("ERR: info io_registers NOT supported " + "by current target\n")); return; } if (sscanf (buf, "%x", &nreg) != 1) { fprintf_unfiltered (gdb_stderr, - "Error fetching number of io registers\n"); + _("Error fetching number of io registers\n")); + xfree (buf); return; } + xfree (buf); + reinitialize_more_filter (); - printf_unfiltered ("Target has %u io registers:\n\n", nreg); + printf_unfiltered (_("Target has %u io registers:\n\n"), nreg); /* only fetch up to 8 registers at a time to keep the buffer small */ step = 8; @@ -1437,7 +1356,8 @@ avr_io_reg_read_command (char *args, int from_tty) j = nreg - i; /* last block is less than 8 registers */ snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j); - target_query ((int) 'R', query, buf, &bufsiz); + bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR, + query, &buf); p = buf; for (k = i; k < (i + j); k++) @@ -1452,6 +1372,8 @@ avr_io_reg_read_command (char *args, int from_tty) break; } } + + xfree (buf); } } @@ -1470,5 +1392,6 @@ _initialize_avr_tdep (void) io_registers' to signify it is not available on other platforms. */ add_cmd ("io_registers", class_info, avr_io_reg_read_command, - "query remote avr target for io space register values", &infolist); + _("query remote avr target for io space register values"), + &infolist); }