Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135557455
D5976.id15333.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D5976.id15333.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D5976: Fix KGDB backtrace on ARM
Attached
Detach File
Event Timeline
Log In to Comment