diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2018-04-13 20:30:49 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2018-04-13 20:30:49 +0000 |
| commit | d86c1f0dc1b17d94a533b4d3e9228dff9cb3fb31 (patch) | |
| tree | 8ce470882fe1e1e9f05a895ac15e4d6aa42c5da4 /gnu | |
| parent | 1315f9b59f83b4ed83fccfd5a0e696267ede902f (diff) | |
Notes
Diffstat (limited to 'gnu')
| -rw-r--r-- | gnu/usr.bin/gdb/kgdb/trgt_i386.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c index cd0d32b824450..b90eebaaf35e2 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.c @@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/proc.h> +#include <vm/vm.h> +#include <vm/pmap.h> #include <machine/pcb.h> #include <machine/frame.h> #include <machine/segments.h> @@ -279,12 +281,26 @@ kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; char *pname; + CORE_ADDR pcx; + uintptr_t addr, setidt_disp; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; - cache->pc = frame_func_unwind(next_frame); + pcx = frame_pc_unwind(next_frame); + if (pcx >= PMAP_TRM_MIN_ADDRESS) { + addr = kgdb_lookup("setidt_disp"); + if (addr != 0) { + if (kvm_read(kvm, addr, &setidt_disp, + sizeof(setidt_disp)) != + sizeof(setidt_disp)) + warnx("kvm_read: %s", kvm_geterr(kvm)); + else + pcx -= setidt_disp; + } + } + cache->pc = pcx; find_pc_partial_function(cache->pc, &pname, NULL, NULL); if (pname[0] != 'X') cache->frame_type = FT_NORMAL; @@ -373,6 +389,8 @@ kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) CORE_ADDR pc; pc = frame_pc_unwind(next_frame); + if (pc >= PMAP_TRM_MIN_ADDRESS) + return (&kgdb_trgt_trapframe_unwind); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) |
