$OpenBSD: patch-gdb_avr-tdep_c,v 1.1 2010/06/27 20:58:10 ckuethe Exp $ --- gdb/avr-tdep.c.orig Fri Jan 11 06:19:59 2008 +++ gdb/avr-tdep.c Sat Jun 26 15:31:25 2010 @@ -181,8 +181,10 @@ struct avr_unwind_cache struct gdbarch_tdep { - /* FIXME: TRoth: is there anything to put here? */ - int foo; + /* Size of the PC on the current AVR target. This is equal 2 for + most AVRs except for the ATmega256x devices that have a 3-byte + PC. */ + int pcsize; }; /* Lookup the name of a register given it's number. */ @@ -1030,22 +1032,29 @@ avr_frame_prev_register (struct frame_info *next_frame 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. */ - + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ULONGEST pc; unsigned char tmp; - unsigned char buf[2]; + unsigned char buf[3]; - read_memory (info->saved_regs[regnum].addr, buf, 2); + read_memory (info->saved_regs[regnum].addr, buf, tdep->pcsize); /* Convert the PC read from memory as a big-endian to little-endian order. */ - tmp = buf[0]; - buf[0] = buf[1]; - buf[1] = tmp; + if (tdep->pcsize == 2) + { + tmp = buf[0]; + buf[0] = buf[1]; + buf[1] = tmp; + } + else + { + tmp = buf[0]; + buf[0] = buf[2]; + buf[2] = tmp; + } - pc = (extract_unsigned_integer (buf, 2) * 2); + pc = (extract_unsigned_integer (buf, tdep->pcsize) * 2); store_unsigned_integer (bufferp, register_size (get_frame_arch (next_frame), regnum), pc); @@ -1280,6 +1289,11 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdb case bfd_mach_avr3: case bfd_mach_avr4: case bfd_mach_avr5: + tdep->pcsize = 2; + break; + + case bfd_mach_avr6: + tdep->pcsize = 3; break; }