This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project. See the GDB home page for more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
This patch fixes some problems in the support for m68k targets. 1999-01-24 Andreas Schwab <schwab@issan.cs.uni-dortmund.de> * config/m68k/tm-m68k.h (PUSH_ARGUMENTS): New definition. * m68k-tdep.c (m68k_push_arguments): New function. (m68k_find_saved_regs): Correctly extract opcodes bytes. Ignore failures to read target memory, and just assume the worst in this case. (m68k_skip_prologue): Likewise. Recognize more opcodes. --- gdb-19990121/gdb/config/m68k/tm-m68k.h.~1~ Fri Dec 18 20:33:37 1998 +++ gdb-19990121/gdb/config/m68k/tm-m68k.h Sun Jan 24 16:20:52 1999 @@ -45,6 +45,7 @@ #ifdef __STDC__ struct frame_info; struct frame_saved_regs; +struct value; #endif extern CORE_ADDR m68k_saved_pc_after_call PARAMS ((struct frame_info *)); @@ -59,7 +60,7 @@ /* Stack must be kept short aligned when doing function calls. */ -#define STACK_ALIGN(ADDR) (((ADDR) + 1) & ~1) +#define STACK_ALIGN(LEN) (((LEN) + 1) & ~1) /* Sequence of bytes for breakpoint instruction. This is a TRAP instruction. The last 4 bits (0xf below) is the @@ -385,6 +386,13 @@ /* Discard from the stack the innermost frame, restoring all registers. */ #define POP_FRAME { m68k_pop_frame (); } + +/* Push the function arguments on the stack. */ + +#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \ + ((SP) = m68k_push_arguments (NARGS, ARGS, SP)) + +extern CORE_ADDR m68k_push_arguments PARAMS ((int, struct value **, CORE_ADDR)); /* Offset from SP to first arg on stack at first instruction of a function */ --- gdb-19990121/gdb/m68k-tdep.c.~1~ Wed Apr 29 18:26:03 1998 +++ gdb-19990121/gdb/m68k-tdep.c Sun Jan 24 16:32:45 1999 @@ -93,6 +93,32 @@ flush_cached_frames (); } +/* Push the arguments for a function call. */ + +CORE_ADDR +m68k_push_arguments (nargs, args, sp) + int nargs; + value_ptr *args; + CORE_ADDR sp; +{ + int i; + + for (i = nargs - 1; i >= 0; i--) + { + int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i])); + /* Small integers and structures are packed into the low bits of an + int, otherwise they are aligned at a word boundary. */ + if (len > 4) + sp -= (len + 3) & ~3; + else + sp -= len; + write_memory (sp, VALUE_CONTENTS_ALL (args[i]), len); + if (len < 4) + sp -= -len & 3; + } + return sp; +} + /* Given an ip value corresponding to the start of a function, return the ip of the first instruction after the function @@ -114,10 +140,12 @@ A movm instruction to preserve integer regs: movm.l &M%1,(4,%sp) 48ef XXXX XXXX + movm.l &M%1,-(%sp) 48e7 XXXX A fmovm instruction to preserve float regs: fmovm &FPM%1,(FPO%1,%sp) f237 XXXX XXXX XXXX XXXX + fmovm &FPM%1,-(%sp) f227 XXXX Some profiling setup code (FIXME, not recognized yet): @@ -152,8 +180,12 @@ while (ip < limit) { - op = read_memory_integer (ip, 2); - op &= 0xFFFF; + char buf[2]; + + /* Ignore errors from accessing target memory. */ + if (target_read_memory (ip, buf, 2)) + break; + op = extract_unsigned_integer (buf, 2); if (op == P_LINK_W) { @@ -175,6 +207,10 @@ { ip += 10; /* Skip fmovm */ } + else if (op == 0x48e7 || op == 0xf227) + { + ip += 4; /* Skip movem.l/fmovem.x */ + } else { break; /* Found unknown code, bail out. */ @@ -195,12 +231,12 @@ /* First possible address for a pc in a call dummy for this frame. */ CORE_ADDR possible_call_dummy_start = - (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4 - 8*12; + frame_info->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4 - 8*12; int nextinsn; memset (saved_regs, 0, sizeof (*saved_regs)); - if ((frame_info)->pc >= possible_call_dummy_start - && (frame_info)->pc <= (frame_info)->frame) + if (frame_info->pc >= possible_call_dummy_start + && frame_info->pc <= frame_info->frame) { /* It is a call dummy. We could just stop now, since we know @@ -208,15 +244,21 @@ to parse the "prologue" which is part of the call dummy. This is needlessly complex and confusing. FIXME. */ - next_addr = (frame_info)->frame; + next_addr = frame_info->frame; pc = possible_call_dummy_start; } else { - pc = get_pc_function_start ((frame_info)->pc); + char buf[2]; + + pc = get_pc_function_start (frame_info->pc); + + /* Check whether memory at PC is accessible at all. */ + if (target_read_memory (pc, buf, 2)) + goto lose; - if (0x4856 == read_memory_integer (pc, 2) - && 0x2c4f == read_memory_integer (pc + 2, 2)) + if (0x4856 == read_memory_unsigned_integer (pc, 2) + && 0x2c4f == read_memory_unsigned_integer (pc + 2, 2)) { /* pea %fp @@ -224,80 +266,119 @@ pc += 4; next_addr = frame_info->frame; + } + else if (044016 == read_memory_unsigned_integer (pc, 2)) + { + /* link.l %fp */ + /* Find the address above the saved + regs using the amount of storage from the link instruction. */ + pc += 2; + next_addr = frame_info->frame + read_memory_integer (pc, 4); + pc += 4; } - else if (044016 == read_memory_integer (pc, 2)) - /* link.l %fp */ - /* Find the address above the saved - regs using the amount of storage from the link instruction. */ - next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; - else if (047126 == read_memory_integer (pc, 2)) - /* link.w %fp */ - /* Find the address above the saved - regs using the amount of storage from the link instruction. */ - next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; - else goto lose; - - /* If have an addal #-n, sp next, adjust next_addr. */ - if ((0177777 & read_memory_integer (pc, 2)) == 0157774) - next_addr += read_memory_integer (pc += 2, 4), pc += 4; - } - regmask = read_memory_integer (pc + 2, 2); - - /* Here can come an fmovem. Check for it. */ - nextinsn = 0xffff & read_memory_integer (pc, 2); - if (0xf227 == nextinsn - && (regmask & 0xff00) == 0xe000) - { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ - for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) - if (regmask & 1) - saved_regs->regs[regnum] = (next_addr -= 12); - regmask = read_memory_integer (pc + 2, 2); } - - /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ - if (0044327 == read_memory_integer (pc, 2)) - { pc += 4; /* Regmask's low bit is for register 0, the first written */ - for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) - if (regmask & 1) - saved_regs->regs[regnum] = (next_addr += 4) - 4; } - else if (0044347 == read_memory_integer (pc, 2)) - { - pc += 4; /* Regmask's low bit is for register 15, the first pushed */ - for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) - if (regmask & 1) - saved_regs->regs[regnum] = (next_addr -= 4); + else if (047126 == read_memory_unsigned_integer (pc, 2)) + { + /* link.w %fp */ + /* Find the address above the saved + regs using the amount of storage from the link instruction. */ + pc += 2; + next_addr = frame_info->frame + read_memory_integer (pc, 2); + pc += 2; + } + else + goto lose; + + /* If have an addal #-n, sp next, adjust next_addr. */ + if (read_memory_unsigned_integer (pc, 2) == 0157774) + { + pc += 2; + next_addr += read_memory_integer (pc, 4); + pc += 4; + } + } + regmask = read_memory_unsigned_integer (pc + 2, 2); + + /* Here can come an fmovem. Check for it. */ + nextinsn = read_memory_unsigned_integer (pc, 2); + if (0xf227 == nextinsn + && (regmask & 0xff00) == 0xe000) + { + pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ + for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; + regnum--, regmask >>= 1) + if (regmask & 1) + { + next_addr -= 12; + saved_regs->regs[regnum] = next_addr; + } + regmask = read_memory_unsigned_integer (pc + 2, 2); } - else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2))) + + /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ + if (0044327 == read_memory_unsigned_integer (pc, 2)) + { + pc += 4; /* Regmask's low bit is for register 0, the first written */ + for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) + if (regmask & 1) + { + saved_regs->regs[regnum] = next_addr; + next_addr += 4; + } + } + else if (0044347 == read_memory_unsigned_integer (pc, 2)) + { + pc += 4; /* Regmask's low bit is for register 15, the first pushed */ + for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) + if (regmask & 1) + { + next_addr -= 4; + saved_regs->regs[regnum] = next_addr; + } + } + else if (0x2f00 == (0xfff0 & read_memory_unsigned_integer (pc, 2))) { - regnum = 0xf & read_memory_integer (pc, 2); pc += 2; - saved_regs->regs[regnum] = (next_addr -= 4); + regnum = 0xf & read_memory_unsigned_integer (pc, 2); + pc += 2; + next_addr -= 4; + saved_regs->regs[regnum] = next_addr; /* gcc, at least, may use a pair of movel instructions when saving exactly 2 registers. */ - if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2))) + if (0x2f00 == (0xfff0 & read_memory_unsigned_integer (pc, 2))) { regnum = 0xf & read_memory_integer (pc, 2); pc += 2; - saved_regs->regs[regnum] = (next_addr -= 4); + next_addr -= 4; + saved_regs->regs[regnum] = next_addr; } } - /* fmovemx to index of sp may follow. */ - regmask = read_memory_integer (pc + 2, 2); - nextinsn = 0xffff & read_memory_integer (pc, 2); - if (0xf236 == nextinsn - && (regmask & 0xff00) == 0xf000) - { pc += 10; /* Regmask's low bit is for register fp0, the first written */ - for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) - if (regmask & 1) - saved_regs->regs[regnum] = (next_addr += 12) - 12; - regmask = read_memory_integer (pc + 2, 2); } - - /* clrw -(sp); movw ccr,-(sp) may follow. */ - if (0x426742e7 == read_memory_integer (pc, 4)) - saved_regs->regs[PS_REGNUM] = (next_addr -= 4); - lose: ; - saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8; - saved_regs->regs[FP_REGNUM] = (frame_info)->frame; - saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4; + /* fmovemx to index of sp may follow. */ + regmask = read_memory_unsigned_integer (pc + 2, 2); + nextinsn = read_memory_unsigned_integer (pc, 2); + if (0xf236 == nextinsn + && (regmask & 0xff00) == 0xf000) + { + pc += 10; /* Regmask's low bit is for register fp0, the first written */ + for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; + regnum--, regmask >>= 1) + if (regmask & 1) + { + saved_regs->regs[regnum] = next_addr; + next_addr += 12; + } + regmask = read_memory_unsigned_integer (pc + 2, 2); + } + + /* clrw -(sp); movw ccr,-(sp) may follow. */ + if (0x426742e7 == read_memory_unsigned_integer (pc, 4)) + { + next_addr -= 4; + saved_regs->regs[PS_REGNUM] = next_addr; + } + lose: + saved_regs->regs[SP_REGNUM] = frame_info->frame + 8; + saved_regs->regs[FP_REGNUM] = frame_info->frame; + saved_regs->regs[PC_REGNUM] = frame_info->frame + 4; #ifdef SIG_SP_FP_OFFSET /* Adjust saved SP_REGNUM for fake _sigtramp frames. */ if (frame_info->signal_handler_caller && frame_info->next) -- Andreas Schwab "And now for something schwab@issan.cs.uni-dortmund.de completely different" schwab@gnu.org