X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Favr-tdep.c;h=563ecf204e8c7736c529a932024682aae62100a2;hb=d3e05d0da824adbd10f0fb0647d9773c6d22e56e;hp=3e3d26446ea604dce3cdd18a874eb8210ae7c5d6;hpb=336d1bba0aa5fa96bab6d7fb23317be1374ad151;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index 3e3d26446e..563ecf204e 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -1,5 +1,5 @@ /* Target-dependent code for Atmel AVR, for GDB. - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -36,6 +36,7 @@ #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) { @@ -796,7 +785,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); @@ -856,76 +847,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,7 +878,8 @@ avr_frame_unwind_cache (struct frame_info *next_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 */ @@ -987,8 +909,7 @@ 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. */ + offsets. */ for (i = 0; i < NUM_REGS - 1; i++) if (info->saved_regs[i].addr) { @@ -1003,6 +924,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; } @@ -1033,11 +958,6 @@ avr_frame_this_id (struct frame_info *next_frame, /* 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; - /* Hopefully the prologue analysis either correctly determined the frame's base (which is the SP from the previous frame), or set that base to "NULL". */ @@ -1046,16 +966,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,8 +979,54 @@ avr_frame_prev_register (struct frame_info *next_frame, 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 = { @@ -1190,7 +1146,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) @@ -1336,20 +1292,11 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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_sniffer (gdbarch, avr_frame_sniffer); frame_base_set_default (gdbarch, &avr_frame_base); @@ -1376,7 +1323,7 @@ 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; + LONGEST bufsiz = 0; char buf[400]; char query[400]; char *p; @@ -1384,22 +1331,23 @@ avr_io_reg_read_command (char *args, int from_tty) unsigned int val; int i, j, k, step; - if (!current_target.to_query) + /* Just get the maximum buffer size. */ + bufsiz = target_read_partial (¤t_target, TARGET_OBJECT_AVR, + NULL, NULL, 0, 0); + if (bufsiz < 0) { 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); + target_read_partial (¤t_target, TARGET_OBJECT_AVR, query, buf, 0, + bufsiz); if (strncmp (buf, "", bufsiz) == 0) { @@ -1430,7 +1378,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); + target_read_partial (¤t_target, TARGET_OBJECT_AVR, query, buf, + 0, bufsiz); p = buf; for (k = i; k < (i + j); k++)