diff options
author | David Taylor <taylor@redhat.com> | 1997-12-16 07:43:26 +0000 |
---|---|---|
committer | David Taylor <taylor@redhat.com> | 1997-12-16 07:43:26 +0000 |
commit | 7ae2b4337a08580658720dd758d36e80eba1ac0e (patch) | |
tree | 1ac6951f250357749dcbfb260822c3378e6be96e /gdb | |
parent | eae435160e165737504d5f423a885a6ca8267fc5 (diff) | |
download | gdb-7ae2b4337a08580658720dd758d36e80eba1ac0e.zip gdb-7ae2b4337a08580658720dd758d36e80eba1ac0e.tar.gz gdb-7ae2b4337a08580658720dd758d36e80eba1ac0e.tar.bz2 |
back trace now works when using external memory and frameless functions; all
arguments are passed in args registers until we run out; finding saved regs
now has two offsets not just one doing double duty.
TARGET_READ_SP / TARGET_WRITE_SP are (temporarily?) commented out.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 15 | ||||
-rw-r--r-- | gdb/config/d30v/tm-d30v.h | 13 | ||||
-rw-r--r-- | gdb/d30v-tdep.c | 52 |
3 files changed, 58 insertions, 22 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2df0bba..5596c8b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +Tue Dec 16 10:29:16 1997 David Taylor <taylor@texas.cygnus.com> + + * d30v-tdep.c (d30v_frame_chain): don't or in DMEM_START to + FP_REGNUM value before return; (prologue_find_regs): two sets + of offsets -- frame pointer and stack pointer, not just one that + tries to do double duty; (d30v_frame_find_saved_regs): stop once + we hit pc (in case we're stopped in the middle of the prologue) + and improve handling of frameless prologues; (d30v_push_arguments): + *ALL* arguments go on the stack until we run out of args registers, + force sp to be 8 byte aligned. + + * config/tm-d30v.h (EXTRACT_STRUCT_VALUE_ADDRESS): fix, it's r2, + not r0; (FRAME_CHAIN_VALID): handle use of external memory; + (STACK_ALIGN): define. + Mon Dec 15 15:13:57 1997 Andrew Cagney <cagney@b1.cygnus.com> * remote-sim.c (gdbsim_wait): When HAVE_SIGACTION and SA_RESTART diff --git a/gdb/config/d30v/tm-d30v.h b/gdb/config/d30v/tm-d30v.h index 931c032..a1a5b58 100644 --- a/gdb/config/d30v/tm-d30v.h +++ b/gdb/config/d30v/tm-d30v.h @@ -191,8 +191,7 @@ void d30v_do_registers_info PARAMS ((int regnum, int fpregs)); /* Extract from an array REGBUF containing the (raw) register state the address in which a function should return its structure value, as a CORE_ADDR (or an expression that can be used as one). */ - -#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(CORE_ADDR *)(REGBUF)) +#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (((CORE_ADDR *)(REGBUF))[2]) /* Define other aspects of the stack frame. @@ -222,8 +221,13 @@ extern void d30v_init_extra_frame_info PARAMS (( int fromleaf, struct frame_info #define FRAME_CHAIN_VALID(chain,frame) \ ((chain) != 0 && (frame) != 0 && (frame)->pc > IMEM_START) #else +#if 0 #define FRAME_CHAIN_VALID(chain,fi) \ ((chain) != 0 && (fi) != 0 && (fi)->frame <= STACK_START) +#else +#define FRAME_CHAIN_VALID(chain,fi) \ + ((chain) != 0 && (fi) != 0 && (fi)->return_pc != 0) +#endif #endif #define FRAME_SAVED_PC(FRAME) ((FRAME)->return_pc) #define FRAME_ARGS_ADDRESS(fi) (fi)->frame @@ -311,7 +315,7 @@ extern void d30v_pop_frame PARAMS((void)); #define REGISTER_SIZE 4 /* Need to handle SP special, as we need to select between spu and spi. */ - +#if 0 /* XXX until the simulator is fixed */ #define TARGET_READ_SP() ((read_register (PSW_REGNUM) & PSW_SM) \ ? read_register (SPU_REGNUM) \ : read_register (SPI_REGNUM)) @@ -319,6 +323,9 @@ extern void d30v_pop_frame PARAMS((void)); #define TARGET_WRITE_SP(val) ((read_register (PSW_REGNUM) & PSW_SM) \ ? write_register (SPU_REGNUM, (val)) \ : write_register (SPI_REGNUM, (val))) +#endif + +#define STACK_ALIGN(len) (((len) + 7 ) & ~7) /* Turn this on to cause remote-sim.c to use sim_set/clear_breakpoint. */ diff --git a/gdb/d30v-tdep.c b/gdb/d30v-tdep.c index 50b3d0d..09cd9e3 100644 --- a/gdb/d30v-tdep.c +++ b/gdb/d30v-tdep.c @@ -320,7 +320,7 @@ d30v_frame_chain (frame) if (!read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4)) return (CORE_ADDR)0; - return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4)| DMEM_START; + return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4); } static int next_addr, uses_frame; @@ -440,16 +440,16 @@ prologue_find_regs (op, fsr, addr) if ((op & OP_MASK_ALL_BUT_IMM) == OP_SUB_SP_IMM) { offset = EXTRACT_IMM6(op); - next_addr -= offset; + frame_size += -offset; return 1; } - /* st rn, @(sp,0) */ + /* st rn, @(sp,0) -- observed */ if (((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_R0) || ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_IMM0)) { n = EXTRACT_RA(op); - fsr->regs[n] = next_addr; + fsr->regs[n] = (- frame_size); return 1; } @@ -458,8 +458,8 @@ prologue_find_regs (op, fsr, addr) ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_IMM0)) { n = EXTRACT_RA(op); - fsr->regs[n] = next_addr; - fsr->regs[n+1] = next_addr+4; + fsr->regs[n] = (- frame_size); + fsr->regs[n+1] = (- frame_size) + 4; return 1; } @@ -490,7 +490,7 @@ d30v_frame_find_saved_regs (fi, fsr) pc = get_pc_function_start (fi->pc); uses_frame = 0; - while (1) + while (pc < fi->pc) { opl = (unsigned long)read_memory_integer (pc, 4); opr = (unsigned long)read_memory_integer (pc+4, 4); @@ -554,7 +554,7 @@ d30v_frame_find_saved_regs (fi, fsr) } fi->size = frame_size; - if (!fp) + if (!fp || !uses_frame) #if 0 fp = read_register(SP_REGNUM) | DMEM_START; #else @@ -571,7 +571,7 @@ d30v_frame_find_saved_regs (fi, fsr) else fi->return_pc = read_register(LR_REGNUM); - /* th SP is not normally (ever?) saved, but check anyway */ + /* the SP is not normally (ever?) saved, but check anyway */ if (!fsr->regs[SP_REGNUM]) { /* if the FP was saved, that means the current FP is valid, */ @@ -861,27 +861,37 @@ d30v_push_arguments (nargs, args, sp, struct_return, struct_addr) struct type *arg_type = check_typedef (VALUE_TYPE (arg)); len = TYPE_LENGTH (arg_type); contents = VALUE_CONTENTS(arg); - val = extract_signed_integer (contents, len); if (len > 4) { /* we need multiple registers */ int ndx; - for (ndx = 0; ndx < len; ndx += 4, len -= 4) + for (ndx = 0; len > 0; ndx += 8, len -= 8) { + if (regnum & 1) + regnum++; /* all args > 4 bytes start in even register */ + if (regnum < 18) { - if (len > 4) - val = extract_signed_integer (&contents[ndx], 4); - else - val = extract_signed_integer (&contents[ndx], len); + val = extract_signed_integer (&contents[ndx], 4); + write_register (regnum++, val); + if (len >= 8) + val = extract_signed_integer (&contents[ndx+4], 4); + else + val = extract_signed_integer (&contents[ndx+4], len-4); write_register (regnum++, val); } else { /* no more registers available. put it on the stack */ - sp -= len; + + /* all args > 4 bytes are padded to a multiple of 8 bytes + and start on an 8 byte boundary */ + if (sp & 7) + sp -= (sp & 7); /* align it */ + + sp -= ((len + 7) & ~7); /* allocate space */ write_memory (sp, &contents[ndx], len); break; } @@ -891,16 +901,20 @@ d30v_push_arguments (nargs, args, sp, struct_return, struct_addr) { if (regnum < 18 ) { + val = extract_signed_integer (contents, len); write_register (regnum++, val); } else { - sp -= len; - store_address (buffer, len, val); - write_memory (sp, buffer, len); + /* all args are padded to a multiple of 4 bytes (at least) */ + sp -= ((len + 3) & ~3); + write_memory (sp, contents, len); } } } + if (sp & 7) + /* stack pointer is not on an 8 byte boundary -- align it */ + sp -= (sp & 7); return sp; } |