#define VM_MIN_ADDRESS (unsigned)0x400000
\f
+#if 0
static int mips_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
+#endif
/* Some MIPS boards don't support floating point, so we permit the
user to turn it off. */
/* If it is the frame for sigtramp we have a complete sigcontext
immediately below the frame and we get the saved registers from there.
If the stack layout for sigtramp changes we might have to change these
- constants and the companion fixup_sigtramp in mipsread.c */
+ constants and the companion fixup_sigtramp in mdebugread.c */
#ifndef SIGFRAME_BASE
#define SIGFRAME_BASE 0x12c /* sizeof(sigcontext) */
#define SIGFRAME_PC_OFF (-SIGFRAME_BASE + 2 * 4)
#define SIGFRAME_REGSAVE_OFF (-SIGFRAME_BASE + 3 * 4)
+#endif
+#ifndef SIGFRAME_REG_SIZE
+#define SIGFRAME_REG_SIZE 4
#endif
for (; fi; fi = fi->next)
if (in_sigtramp(fi->pc, 0)) {
int offset;
if (regno == PC_REGNUM) offset = SIGFRAME_PC_OFF;
- else if (regno < 32) offset = SIGFRAME_REGSAVE_OFF + regno * 4;
+ else if (regno < 32) offset = (SIGFRAME_REGSAVE_OFF
+ + regno * SIGFRAME_REG_SIZE);
else return 0;
return read_memory_integer(fi->frame + offset, 4);
}
CORE_ADDR cur_pc;
int frame_size;
int has_frame_reg = 0;
- int reg30; /* Value of $r30. Used by gcc for frame-pointer */
+ int reg30 = 0; /* Value of $r30. Used by gcc for frame-pointer */
unsigned long reg_mask = 0;
if (start_pc == 0) return NULL;
- bzero(&temp_proc_desc, sizeof(temp_proc_desc));
- bzero(&temp_saved_regs, sizeof(struct frame_saved_regs));
+ memset(&temp_proc_desc, '\0', sizeof(temp_proc_desc));
+ memset(&temp_saved_regs, '\0', sizeof(struct frame_saved_regs));
PROC_LOW_ADDR(&temp_proc_desc) = start_pc;
if (start_pc + 200 < limit_pc) limit_pc = start_pc + 200;
else if ((word & 0xFFE00000) == 0xafa00000) { /* sw reg,offset($sp) */
int reg = (word & 0x001F0000) >> 16;
reg_mask |= 1 << reg;
- temp_saved_regs.regs[reg] = sp + (short)word;
+ temp_saved_regs.regs[reg] = sp + (word & 0xffff);
}
else if ((word & 0xFFFF0000) == 0x27be0000) { /* addiu $30,$sp,size */
- if ((unsigned short)word != frame_size)
- reg30 = sp + (unsigned short)word;
+ if ((word & 0xffff) != frame_size)
+ reg30 = sp + (word & 0xffff);
else if (!has_frame_reg) {
int alloca_adjust;
has_frame_reg = 1;
reg30 = read_next_frame_reg(next_frame, 30);
- alloca_adjust = reg30 - (sp + (unsigned short)word);
+ alloca_adjust = reg30 - (sp + (word & 0xffff));
if (alloca_adjust > 0) {
/* FP > SP + frame_size. This may be because
- /* of an alloca or somethings similar.
+ * of an alloca or somethings similar.
* Fix sp to "pre-alloca" value, and try again.
*/
sp += alloca_adjust;
else if ((word & 0xFFE00000) == 0xafc00000) { /* sw reg,offset($30) */
int reg = (word & 0x001F0000) >> 16;
reg_mask |= 1 << reg;
- temp_saved_regs.regs[reg] = reg30 + (short)word;
+ temp_saved_regs.regs[reg] = reg30 + (word & 0xffff);
}
}
if (has_frame_reg) {
{
mips_extra_func_info_t proc_desc;
struct block *b = block_for_pc(pc);
- struct symbol *sym =
- b ? lookup_symbol(MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, 0, NULL) : NULL;
+ struct symbol *sym;
+ CORE_ADDR startaddr;
+
+ find_pc_partial_function (pc, NULL, &startaddr, NULL);
+ if (b == NULL)
+ sym = NULL;
+ else
+ {
+ if (startaddr > BLOCK_START (b))
+ /* This is the "pathological" case referred to in a comment in
+ print_frame_info. It might be better to move this check into
+ symbol reading. */
+ sym = NULL;
+ else
+ sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE,
+ 0, NULL);
+ }
if (sym)
{
&& PROC_HIGH_ADDR(&link->info) > pc)
return &link->info;
+ if (startaddr == 0)
+ startaddr = heuristic_proc_start (pc);
+
proc_desc =
- heuristic_proc_desc (heuristic_proc_start (pc), pc, next_frame);
+ heuristic_proc_desc (startaddr, pc, next_frame);
}
return proc_desc;
}
return 0;
cached_proc_desc = proc_desc;
- return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc))
- + PROC_FRAME_OFFSET(proc_desc);
+
+ /* If no frame pointer and frame size is zero, we must be at end
+ of stack (or otherwise hosed). If we don't check frame size,
+ we loop forever if we see a zero size frame. */
+ if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+ && PROC_FRAME_OFFSET (proc_desc) == 0
+ /* The previous frame from a sigtramp frame might be frameless
+ and have frame size zero. */
+ && !frame->signal_handler_caller)
+ return 0;
+ else
+ return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc))
+ + PROC_FRAME_OFFSET(proc_desc);
}
void
{
int ireg;
CORE_ADDR reg_position;
- unsigned long mask;
/* r0 bit means kernel trap */
int kernel_trap = PROC_REG_MASK(proc_desc) & 1;
/* Fixup frame-pointer - only needed for top frame */
- /* This may not be quite right, if proc has a real frame register */
+ /* This may not be quite right, if proc has a real frame register.
+ Get the value of the frame relative sp, procedure might have been
+ interrupted by a signal at it's very start. */
if (fci->pc == PROC_LOW_ADDR(proc_desc) && !PROC_DESC_IS_DUMMY(proc_desc))
- fci->frame = read_register (SP_REGNUM);
+ fci->frame = READ_FRAME_REG(fci, SP_REGNUM);
else
fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc))
+ PROC_FRAME_OFFSET(proc_desc);
- /* If this is the innermost frame, and we are still in the
- prologue (loosely defined), then the registers may not have
- been saved yet. But they haven't been clobbered either, so
- it's fine to say they have not been saved. */
- if (fci->next == NULL
- && mips_in_lenient_prologue (PROC_LOW_ADDR (proc_desc), fci->pc))
- /* We already zeroed the saved regs. */
- ;
- else if (proc_desc == &temp_proc_desc)
+ if (proc_desc == &temp_proc_desc)
*fci->saved_regs = temp_saved_regs;
else
{
- /* find which general-purpose registers were saved */
- reg_position = fci->frame + PROC_REG_OFFSET(proc_desc);
- mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc);
- for (ireg= 31; mask; --ireg, mask <<= 1)
- if (mask & 0x80000000)
+ /* What registers have been saved? Bitmasks. */
+ unsigned long gen_mask, float_mask;
+
+ gen_mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc);
+ float_mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK(proc_desc);
+
+ if (/* In any frame other than the innermost, we assume that all
+ registers have been saved. This assumes that all register
+ saves in a function happen before the first function
+ call. */
+ fci->next == NULL
+
+ /* In a dummy frame we know exactly where things are saved. */
+ && !PROC_DESC_IS_DUMMY (proc_desc)
+
+ /* Not sure exactly what kernel_trap means, but if it means
+ the kernel saves the registers without a prologue doing it,
+ we better not examine the prologue to see whether registers
+ have been saved yet. */
+ && !kernel_trap)
+ {
+ /* We need to figure out whether the registers that the proc_desc
+ claims are saved have been saved yet. */
+
+ CORE_ADDR addr;
+ int status;
+ char buf[4];
+ unsigned long inst;
+
+ /* Bitmasks; set if we have found a save for the register. */
+ unsigned long gen_save_found = 0;
+ unsigned long float_save_found = 0;
+
+ for (addr = PROC_LOW_ADDR (proc_desc);
+ addr < fci->pc && (gen_mask != gen_save_found
+ || float_mask != float_save_found);
+ addr += 4)
+ {
+ status = read_memory_nobpt (addr, buf, 4);
+ if (status)
+ memory_error (status, addr);
+ inst = extract_unsigned_integer (buf, 4);
+ if (/* sw reg,n($sp) */
+ (inst & 0xffe00000) == 0xafa00000
+
+ /* sw reg,n($r30) */
+ || (inst & 0xffe00000) == 0xafc00000)
+ {
+ /* It might be possible to use the instruction to
+ find the offset, rather than the code below which
+ is based on things being in a certain order in the
+ frame, but figuring out what the instruction's offset
+ is relative to might be a little tricky. */
+ int reg = (inst & 0x001f0000) >> 16;
+ gen_save_found |= (1 << reg);
+ }
+ else if (/* swc1 freg,n($sp) */
+ (inst & 0xffe00000) == 0xe7a00000
+
+ /* swc1 freg,n($r30) */
+ || (inst & 0xffe00000) == 0xe7c00000)
+ {
+ int reg = ((inst & 0x001f0000) >> 16);
+ float_save_found |= (1 << reg);
+ }
+ }
+ gen_mask = gen_save_found;
+ float_mask = float_save_found;
+ }
+
+ /* Fill in the offsets for the registers which gen_mask says
+ were saved. */
+ reg_position = fci->frame + PROC_REG_OFFSET (proc_desc);
+ for (ireg= 31; gen_mask; --ireg, gen_mask <<= 1)
+ if (gen_mask & 0x80000000)
{
fci->saved_regs->regs[ireg] = reg_position;
reg_position -= 4;
}
- /* find which floating-point registers were saved */
- reg_position = fci->frame + PROC_FREG_OFFSET(proc_desc);
+ /* Fill in the offsets for the registers which float_mask says
+ were saved. */
+ reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc);
/* The freg_offset points to where the first *double* register
is saved. So skip to the high-order word. */
reg_position += 4;
- mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK(proc_desc);
- for (ireg = 31; mask; --ireg, mask <<= 1)
- if (mask & 0x80000000)
+ for (ireg = 31; float_mask; --ireg, float_mask <<= 1)
+ if (float_mask & 0x80000000)
{
fci->saved_regs->regs[FP0_REGNUM+ireg] = reg_position;
reg_position -= 4;
int struct_return;
CORE_ADDR struct_addr;
{
- CORE_ADDR buf;
register i;
int accumulate_size = struct_return ? 4 : 0;
struct mips_arg { char *contents; int len; int offset; };
sp -= accumulate_size;
for (i = nargs; m_arg--, --i >= 0; )
write_memory(sp + m_arg->offset, m_arg->contents, m_arg->len);
- if (struct_return) {
- buf = struct_addr;
- write_memory(sp, (char *)&buf, sizeof(CORE_ADDR));
- }
+ if (struct_return)
+ {
+ char buf[TARGET_PTR_BIT / HOST_CHAR_BIT];
+
+ store_address (buf, sizeof buf, struct_addr);
+ write_memory (sp, buf, sizeof buf);
+ }
return sp;
}
/* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<31. */
-#define MASK(i,j) ((1 << (j)+1)-1 ^ (1 << (i))-1)
+#define MASK(i,j) (((1 << ((j)+1))-1) ^ ((1 << (i))-1))
void
mips_push_dummy_frame()
{
+ char buffer[MAX_REGISTER_RAW_SIZE];
int ireg;
struct linked_proc_info *link = (struct linked_proc_info*)
xmalloc(sizeof(struct linked_proc_info));
mips_extra_func_info_t proc_desc = &link->info;
CORE_ADDR sp = read_register (SP_REGNUM);
CORE_ADDR save_address;
- REGISTER_TYPE buffer;
link->next = linked_proc_desc_table;
linked_proc_desc_table = link;
#define PUSH_FP_REGNUM 16 /* must be a register preserved across calls */
for (ireg = 32; --ireg >= 0; )
if (PROC_REG_MASK(proc_desc) & (1 << ireg))
{
- buffer = read_register (ireg);
- write_memory (save_address, (char *)&buffer, sizeof(REGISTER_TYPE));
+ store_unsigned_integer (buffer, REGISTER_RAW_SIZE (ireg),
+ read_register (ireg));
+ write_memory (save_address, buffer, REGISTER_RAW_SIZE (ireg));
save_address -= 4;
}
/* save floating-points registers starting with high order word */
for (ireg = 32; --ireg >= 0; )
if (PROC_FREG_MASK(proc_desc) & (1 << ireg))
{
- buffer = read_register (ireg + FP0_REGNUM);
- write_memory (save_address, (char *)&buffer, 4);
+ store_unsigned_integer (buffer, 4, read_register (ireg + FP0_REGNUM));
+ write_memory (save_address, buffer, 4);
save_address -= 4;
}
write_register (PUSH_FP_REGNUM, sp);
PROC_FRAME_REG(proc_desc) = PUSH_FP_REGNUM;
PROC_FRAME_OFFSET(proc_desc) = 0;
- buffer = read_register (PC_REGNUM);
- write_memory (sp - 4, (char *)&buffer, sizeof(REGISTER_TYPE));
- buffer = read_register (HI_REGNUM);
- write_memory (sp - 8, (char *)&buffer, sizeof(REGISTER_TYPE));
- buffer = read_register (LO_REGNUM);
- write_memory (sp - 12, (char *)&buffer, sizeof(REGISTER_TYPE));
- buffer = read_register (mips_fpu ? FCRCS_REGNUM : ZERO_REGNUM);
- write_memory (sp - 16, (char *)&buffer, sizeof(REGISTER_TYPE));
+ store_unsigned_integer (buffer, REGISTER_RAW_SIZE (PC_REGNUM),
+ read_register (PC_REGNUM));
+ write_memory (sp - 4, buffer, REGISTER_RAW_SIZE (PC_REGNUM));
+ store_unsigned_integer (buffer, REGISTER_RAW_SIZE (HI_REGNUM),
+ read_register (HI_REGNUM));
+ write_memory (sp - 8, buffer, REGISTER_RAW_SIZE (HI_REGNUM));
+ store_unsigned_integer (buffer, REGISTER_RAW_SIZE (LO_REGNUM),
+ read_register (LO_REGNUM));
+ write_memory (sp - 12, buffer, REGISTER_RAW_SIZE (LO_REGNUM));
+ store_unsigned_integer
+ (buffer,
+ REGISTER_RAW_SIZE (FCRCS_REGNUM),
+ mips_fpu ? read_register (FCRCS_REGNUM) : 0);
+ write_memory (sp - 16, buffer, REGISTER_RAW_SIZE (FCRCS_REGNUM));
sp -= 4 * (GEN_REG_SAVE_COUNT
+ (mips_fpu ? FLOAT_REG_SAVE_COUNT : 0)
+ SPECIAL_REG_SAVE_COUNT);
/* We let mips_init_extra_frame_info figure out the frame pointer */
set_current_frame (create_new_frame (0, read_pc ()));
- if (PROC_DESC_IS_DUMMY(proc_desc))
+ if (proc_desc && PROC_DESC_IS_DUMMY(proc_desc))
{
struct linked_proc_info *pi_ptr, *prev_ptr;
mips_print_register (regnum, all)
int regnum, all;
{
- unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE];
- REGISTER_TYPE val;
+ unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE];
- /* Get the data in raw format. */
- if (read_relative_register_raw_bytes (regnum, raw_buffer))
- {
- printf_filtered ("%s: [Invalid]", reg_names[regnum]);
- return;
- }
-
- /* If an even floating pointer register, also print as double. */
- if (regnum >= FP0_REGNUM && regnum < FP0_REGNUM+32
- && !((regnum-FP0_REGNUM) & 1)) {
- char dbuffer[MAX_REGISTER_RAW_SIZE];
-
- read_relative_register_raw_bytes (regnum, dbuffer);
- read_relative_register_raw_bytes (regnum+1, dbuffer+4);
+ /* Get the data in raw format. */
+ if (read_relative_register_raw_bytes (regnum, raw_buffer))
+ {
+ printf_filtered ("%s: [Invalid]", reg_names[regnum]);
+ return;
+ }
+
+ /* If an even floating pointer register, also print as double. */
+ if (regnum >= FP0_REGNUM && regnum < FP0_REGNUM+32
+ && !((regnum-FP0_REGNUM) & 1)) {
+ char dbuffer[MAX_REGISTER_RAW_SIZE];
+
+ read_relative_register_raw_bytes (regnum, dbuffer);
+ read_relative_register_raw_bytes (regnum+1, dbuffer+4);
#ifdef REGISTER_CONVERT_TO_TYPE
- REGISTER_CONVERT_TO_TYPE(regnum, builtin_type_double, dbuffer);
+ REGISTER_CONVERT_TO_TYPE(regnum, builtin_type_double, dbuffer);
#endif
- printf_filtered ("(d%d: ", regnum-FP0_REGNUM);
- val_print (builtin_type_double, dbuffer, 0,
- stdout, 0, 1, 0, Val_pretty_default);
- printf_filtered ("); ");
- }
- fputs_filtered (reg_names[regnum], stdout);
-#ifndef NUMERIC_REG_NAMES
- if (regnum < 32)
- printf_filtered ("(r%d): ", regnum);
- else
-#endif
- printf_filtered (": ");
+ printf_filtered ("(d%d: ", regnum-FP0_REGNUM);
+ val_print (builtin_type_double, dbuffer, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ printf_filtered ("); ");
+ }
+ fputs_filtered (reg_names[regnum], gdb_stdout);
+
+ /* The problem with printing numeric register names (r26, etc.) is that
+ the user can't use them on input. Probably the best solution is to
+ fix it so that either the numeric or the funky (a2, etc.) names
+ are accepted on input. */
+ if (regnum < 32)
+ printf_filtered ("(r%d): ", regnum);
+ else
+ printf_filtered (": ");
- /* If virtual format is floating, print it that way. */
- if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
- && ! INVALID_FLOAT (raw_buffer, REGISTER_VIRTUAL_SIZE(regnum))) {
- val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0,
- stdout, 0, 1, 0, Val_pretty_default);
- }
- /* Else print as integer in hex. */
- else
- {
- long val;
+ /* If virtual format is floating, print it that way. */
+ if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
+ && ! INVALID_FLOAT (raw_buffer, REGISTER_VIRTUAL_SIZE(regnum))) {
+ val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0,
+ gdb_stdout, 0, 1, 0, Val_pretty_default);
+ }
+ /* Else print as integer in hex. */
+ else
+ {
+ long val;
- val = extract_signed_integer (raw_buffer,
- REGISTER_RAW_SIZE (regnum));
+ val = extract_signed_integer (raw_buffer,
+ REGISTER_RAW_SIZE (regnum));
- if (val == 0)
- printf_filtered ("0");
- else if (all)
- printf_filtered (local_hex_format(), val);
- else
- printf_filtered ("%s=%d", local_hex_string(val), val);
- }
+ if (val == 0)
+ printf_filtered ("0");
+ else if (all)
+ /* FIXME: We should be printing this in a fixed field width, so that
+ registers line up. */
+ printf_filtered (local_hex_format(), val);
+ else
+ printf_filtered ("%s=%ld", local_hex_string(val), val);
+ }
}
/* Replacement for generic do_registers_info. */
return -1;
}
\f
-/* Does this instruction involve use of a delay slot? */
+#if 0
+/* Is this a branch with a delay slot? */
static int
is_delayed (insn)
unsigned long insn;
if (mips_opcodes[i].pinfo != INSN_MACRO
&& (insn & mips_opcodes[i].mask) == mips_opcodes[i].match)
break;
- return i < NUMOPCODES && (mips_opcodes[i].pinfo & ANY_DELAY);
+ return (i < NUMOPCODES
+ && (mips_opcodes[i].pinfo & (INSN_UNCOND_BRANCH_DELAY
+ | INSN_COND_BRANCH_DELAY
+ | INSN_COND_BRANCH_LIKELY)));
}
+#endif
/* To skip prologues, I use this predicate. Returns either PC itself
if the code at PC does not look like a function prologue; otherwise
CORE_ADDR pc;
int lenient;
{
- struct symbol *f;
- struct block *b;
unsigned long inst;
int offset;
int seen_sp_adjust = 0;
memory_error (status, pc + offset);
inst = extract_unsigned_integer (buf, 4);
+#if 0
if (lenient && is_delayed (inst))
continue;
+#endif
if ((inst & 0xffff0000) == 0x27bd0000) /* addiu $sp,$sp,offset */
seen_sp_adjust = 1;
continue;
else if ((inst & 0xFF9F07FF) == 0x00800021) /* move reg,$a0-$a3 */
continue;
+ else if ((inst & 0xffff0000) == 0x3c1c0000) /* lui $gp,n */
+ continue;
+ else if ((inst & 0xffff0000) == 0x279c0000) /* addiu $gp,$gp,n */
+ continue;
+ else if (inst == 0x0399e021 /* addu $gp,$gp,$t9 */
+ || inst == 0x033ce021) /* addu $gp,$t9,$gp */
+ continue;
else
break;
}
#endif
}
+#if 0
+/* The lenient prologue stuff should be superceded by the code in
+ init_extra_frame_info which looks to see whether the stores mentioned
+ in the proc_desc have actually taken place. */
+
/* Is address PC in the prologue (loosely defined) for function at
STARTADDR? */
CORE_ADDR end_prologue = mips_skip_prologue (startaddr, 1);
return pc >= startaddr && pc < end_prologue;
}
+#endif
/* Given a return value in `regbuf' with a type `valtype',
extract and copy its value into `valbuf'. */
write_register_bytes(REGISTER_BYTE (regnum), raw_buffer, TYPE_LENGTH (valtype));
}
-/* Let the user turn off floating point and set the fence post for
- heuristic_proc_start. */
+/* These exist in mdebugread.c. */
+extern CORE_ADDR sigtramp_address, sigtramp_end;
+extern void fixup_sigtramp PARAMS ((void));
+
+/* Exported procedure: Is PC in the signal trampoline code */
+
+int
+in_sigtramp (pc, ignore)
+ CORE_ADDR pc;
+ char *ignore; /* function name */
+{
+ if (sigtramp_address == 0)
+ fixup_sigtramp ();
+ return (pc >= sigtramp_address && pc < sigtramp_end);
+}
+
+static void reinit_frame_cache_sfunc PARAMS ((char *, int,
+ struct cmd_list_element *));
+
+/* Just like reinit_frame_cache, but with the right arguments to be
+ callable as an sfunc. */
+static void
+reinit_frame_cache_sfunc (args, from_tty, c)
+ char *args;
+ int from_tty;
+ struct cmd_list_element *c;
+{
+ reinit_frame_cache ();
+}
void
_initialize_mips_tdep ()
{
+ struct cmd_list_element *c;
+
+ /* Let the user turn off floating point and set the fence post for
+ heuristic_proc_start. */
+
add_show_from_set
(add_set_cmd ("mipsfpu", class_support, var_boolean,
(char *) &mips_fpu,
or dealing with return values.", &setlist),
&showlist);
- add_show_from_set
- (add_set_cmd ("heuristic-fence-post", class_support, var_uinteger,
- (char *) &heuristic_fence_post,
- "\
+ /* We really would like to have both "0" and "unlimited" work, but
+ command.c doesn't deal with that. So make it a var_zinteger
+ because the user can always use "999999" or some such for unlimited. */
+ c = add_set_cmd ("heuristic-fence-post", class_support, var_zinteger,
+ (char *) &heuristic_fence_post,
+ "\
Set the distance searched for the start of a function.\n\
If you are debugging a stripped executable, GDB needs to search through the\n\
program for the start of a function. This command sets the distance of the\n\
search. The only need to set it is when debugging a stripped executable.",
- &setlist),
- &showlist);
+ &setlist);
+ /* We need to throw away the frame cache when we set this, since it
+ might change our ability to get backtraces. */
+ c->function.sfunc = reinit_frame_cache_sfunc;
+ add_show_from_set (c, &showlist);
}