Page MenuHomeFreeBSD

D5976.id15333.diff
No OneTemporary

D5976.id15333.diff

Index: contrib/gdb/gdb/arm-tdep.c
===================================================================
--- contrib/gdb/gdb/arm-tdep.c
+++ contrib/gdb/gdb/arm-tdep.c
@@ -678,6 +678,9 @@
cache->framesize = 0;
cache->frameoffset = 0;
+ if (frame_tdep_pc_fixup)
+ frame_tdep_pc_fixup(&prev_pc);
+
/* Check for Thumb prologue. */
if (arm_pc_is_thumb (prev_pc))
{
@@ -914,7 +917,6 @@
cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
arm_scan_prologue (next_frame, cache);
-
unwound_fp = frame_unwind_register_unsigned (next_frame, cache->framereg);
if (unwound_fp == 0)
return cache;
Index: contrib/gdb/gdb/frame.h
===================================================================
--- contrib/gdb/gdb/frame.h
+++ contrib/gdb/gdb/frame.h
@@ -702,4 +702,6 @@
code. */
extern int legacy_frame_p (struct gdbarch *gdbarch);
+extern int (*frame_tdep_pc_fixup)(CORE_ADDR *pc);
+
#endif /* !defined (FRAME_H) */
Index: contrib/gdb/gdb/frame.c
===================================================================
--- contrib/gdb/gdb/frame.c
+++ contrib/gdb/gdb/frame.c
@@ -136,6 +136,7 @@
static int backtrace_past_main;
static unsigned int backtrace_limit = UINT_MAX;
+int (*frame_tdep_pc_fixup)(CORE_ADDR *pc);
void
fprint_frame_id (struct ui_file *file, struct frame_id id)
@@ -2010,6 +2011,9 @@
/* A draft address. */
CORE_ADDR pc = frame_pc_unwind (next_frame);
+ if ((frame_tdep_pc_fixup != NULL) && (frame_tdep_pc_fixup(&pc) == 0))
+ return pc;
+
/* If THIS frame is not inner most (i.e., NEXT isn't the sentinel),
and NEXT is `normal' (i.e., not a sigtramp, dummy, ....) THIS
frame's PC ends up pointing at the instruction fallowing the
Index: gnu/usr.bin/gdb/kgdb/kgdb.h
===================================================================
--- gnu/usr.bin/gdb/kgdb/kgdb.h
+++ gnu/usr.bin/gdb/kgdb/kgdb.h
@@ -75,4 +75,7 @@
#define kgdb_parse(exp) kgdb_parse_1((exp), 0)
#define kgdb_parse_quiet(exp) kgdb_parse_1((exp), 1)
+extern int (*arm_tdep_pc_fixup)(CORE_ADDR *pc);
+int kgdb_trgt_pc_fixup(CORE_ADDR *pc);
+
#endif /* _KGDB_H_ */
Index: gnu/usr.bin/gdb/kgdb/main.c
===================================================================
--- gnu/usr.bin/gdb/kgdb/main.c
+++ gnu/usr.bin/gdb/kgdb/main.c
@@ -474,7 +474,9 @@
add_arg(&args, NULL);
init_ui_hook = kgdb_init;
-
+#if TARGET_CPUARCH == arm
+ frame_tdep_pc_fixup = kgdb_trgt_pc_fixup;
+#endif
kgdb_sniffer_kluge = kgdb_trgt_trapframe_sniffer;
return (gdb_main(&args));
Index: gnu/usr.bin/gdb/kgdb/trgt_arm.c
===================================================================
--- gnu/usr.bin/gdb/kgdb/trgt_arm.c
+++ gnu/usr.bin/gdb/kgdb/trgt_arm.c
@@ -96,6 +96,7 @@
struct kgdb_frame_cache {
CORE_ADDR fp;
CORE_ADDR sp;
+ CORE_ADDR pc;
};
static int kgdb_trgt_frame_offset[26] = {
@@ -135,6 +136,7 @@
frame_unwind_register(next_frame, ARM_FP_REGNUM, buf);
cache->fp = extract_unsigned_integer(buf,
register_size(current_gdbarch, ARM_FP_REGNUM));
+ cache->pc = frame_func_unwind(next_frame);
}
return (cache);
}
@@ -148,7 +150,7 @@
struct kgdb_frame_cache *cache;
cache = kgdb_trgt_frame_cache(next_frame, this_cache);
- *this_id = frame_id_build(cache->fp, 0);
+ *this_id = frame_id_build(cache->sp, cache->pc);
}
static void
@@ -160,6 +162,7 @@
struct kgdb_frame_cache *cache;
int ofs, regsz;
int is_undefined = 0;
+ CORE_ADDR sp;
regsz = register_size(current_gdbarch, regnum);
@@ -177,24 +180,24 @@
return;
cache = kgdb_trgt_frame_cache(next_frame, this_cache);
+ sp = cache->sp;
if (is_undef && (regnum == ARM_SP_REGNUM || regnum == ARM_PC_REGNUM)) {
- *addrp = cache->sp + offsetof(struct trapframe, tf_spsr);
+ *addrp = sp + offsetof(struct trapframe, tf_spsr);
target_read_memory(*addrp, valuep, regsz);
is_undefined = 1;
- ofs = kgdb_trgt_frame_offset[ARM_SP_REGNUM];
-
+ ofs = kgdb_trgt_frame_offset[regnum];
}
- *addrp = cache->sp + ofs;
- *lvalp = lval_memory;
- target_read_memory(*addrp, valuep, regsz);
+ *addrp = sp + ofs;
+
+ if (!is_undefined && (regnum == ARM_LR_REGNUM))
+ *addrp = cache->fp + 4;
- if (is_undefined) {
- *addrp = *(unsigned int *)valuep + (regnum == ARM_SP_REGNUM ?
- 0 : 8);
+ *lvalp = lval_memory;
target_read_memory(*addrp, valuep, regsz);
- }
+ if (!is_undefined && (regnum == ARM_SP_REGNUM))
+ *(int*)valuep = cache->fp - 8;
}
static const struct frame_unwind kgdb_trgt_trapframe_unwind = {
@@ -233,3 +236,64 @@
#endif
return (NULL);
}
+
+/*
+ * This function ensures, that the PC is inside the
+ * function section which is understood by GDB.
+ *
+ * Return 0 when fixup is necessary, -1 otherwise.
+ */
+int
+kgdb_trgt_pc_fixup(CORE_ADDR *pc)
+{
+#ifndef CROSS_DEBUGGER
+ struct minimal_symbol *msymbol;
+ int valpc;
+
+ /*
+ * exception_exit and swi_exit are special. These functions
+ * are artificially injected into the stack to be executed
+ * as the last entry in calling chain when all functions exit.
+ * Treat them differently.
+ */
+ msymbol = lookup_minimal_symbol_by_pc(*pc);
+ if (msymbol != NULL) {
+ if (strcmp(DEPRECATED_SYMBOL_NAME(msymbol), "exception_exit") == 0)
+ return (0);
+ if (strcmp(DEPRECATED_SYMBOL_NAME(msymbol), "swi_exit") == 0)
+ return (0);
+ }
+
+ /*
+ * kdb_enter contains an invalid instruction which is supposed
+ * to generate a trap. BFD does not understand it and treats
+ * this part of function as a separate function. Move PC
+ * two instruction earlier to be inside kdb_enter section.
+ */
+ target_read_memory(*pc - 4, (char*)&valpc, 4);
+ if (valpc == 0xe7ffffff) {
+ *pc = *pc - 8;
+ return (0);
+ }
+
+ /*
+ * When the panic/vpanic is the last (noreturn) function,
+ * the bottom of the calling function looks as below.
+ * mov lr, pc
+ * b panic
+ * Normally, GDB is not able to detect function boundaries,
+ * so move the PC two instruction earlier where it can deal
+ * with it.
+ * Match this pair of instructions: mov lr, pc followed with
+ * non-linked branch.
+ */
+ if ((valpc & 0xff000000) == 0xea000000) {
+ target_read_memory(*pc - 8, (char*)&valpc, 4);
+ if (valpc == 0xe1a0e00f) {
+ *pc -= 8;
+ return (0);
+ }
+ }
+#endif
+ return (-1);
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 11, 7:22 PM (19 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25177967
Default Alt Text
D5976.id15333.diff (6 KB)

Event Timeline