Index: stable/6/gnu/usr.bin/gdb/kgdb/kthr.c =================================================================== --- stable/6/gnu/usr.bin/gdb/kgdb/kthr.c (revision 178878) +++ stable/6/gnu/usr.bin/gdb/kgdb/kthr.c (revision 178879) @@ -1,228 +1,232 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include +#include #include #include #include "kgdb.h" #include static uintptr_t dumppcb; static int dumptid; static uintptr_t stoppcbs; static __cpumask_t stopped_cpus; static struct kthr *first; struct kthr *curkthr; uintptr_t kgdb_lookup(const char *sym) { struct nlist nl[2]; nl[0].n_name = (char *)(uintptr_t)sym; nl[1].n_name = NULL; if (kvm_nlist(kvm, nl) != 0) return (0); return (nl[0].n_value); } struct kthr * kgdb_thr_first(void) { return (first); } struct kthr * kgdb_thr_init(void) { struct proc p; struct thread td; struct kthr *kt; uintptr_t addr, paddr; while (first != NULL) { kt = first; first = kt->next; free(kt); } addr = kgdb_lookup("_allproc"); if (addr == 0) { warnx("kvm_nlist(_allproc): %s", kvm_geterr(kvm)); return (NULL); } kvm_read(kvm, addr, &paddr, sizeof(paddr)); dumppcb = kgdb_lookup("_dumppcb"); if (dumppcb == 0) { warnx("kvm_nlist(_dumppcb): %s", kvm_geterr(kvm)); return (NULL); } addr = kgdb_lookup("_dumptid"); if (addr != 0) kvm_read(kvm, addr, &dumptid, sizeof(dumptid)); else dumptid = -1; addr = kgdb_lookup("_stopped_cpus"); if (addr != 0) kvm_read(kvm, addr, &stopped_cpus, sizeof(stopped_cpus)); else stopped_cpus = 0; stoppcbs = kgdb_lookup("_stoppcbs"); while (paddr != 0) { if (kvm_read(kvm, paddr, &p, sizeof(p)) != sizeof(p)) { warnx("kvm_read: %s", kvm_geterr(kvm)); break; } addr = (uintptr_t)TAILQ_FIRST(&p.p_threads); while (addr != 0) { if (kvm_read(kvm, addr, &td, sizeof(td)) != sizeof(td)) { warnx("kvm_read: %s", kvm_geterr(kvm)); break; } kt = malloc(sizeof(*kt)); kt->next = first; kt->kaddr = addr; if (td.td_tid == dumptid) kt->pcb = dumppcb; else if (td.td_state == TDS_RUNNING && ((1 << td.td_oncpu) & stopped_cpus) && stoppcbs != 0) kt->pcb = (uintptr_t) stoppcbs + sizeof(struct pcb) * td.td_oncpu; else kt->pcb = (uintptr_t)td.td_pcb; kt->kstack = td.td_kstack; kt->tid = td.td_tid; kt->pid = p.p_pid; kt->paddr = paddr; kt->cpu = td.td_oncpu; first = kt; addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); } paddr = (uintptr_t)LIST_NEXT(&p, p_list); } curkthr = kgdb_thr_lookup_tid(dumptid); if (curkthr == NULL) curkthr = first; return (first); } struct kthr * kgdb_thr_lookup_tid(int tid) { struct kthr *kt; kt = first; while (kt != NULL && kt->tid != tid) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_taddr(uintptr_t taddr) { struct kthr *kt; kt = first; while (kt != NULL && kt->kaddr != taddr) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_pid(int pid) { struct kthr *kt; kt = first; while (kt != NULL && kt->pid != pid) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_paddr(uintptr_t paddr) { struct kthr *kt; kt = first; while (kt != NULL && kt->paddr != paddr) kt = kt->next; return (kt); } struct kthr * kgdb_thr_next(struct kthr *kt) { return (kt->next); } struct kthr * kgdb_thr_select(struct kthr *kt) { struct kthr *pcur; pcur = curkthr; curkthr = kt; return (pcur); } char * kgdb_thr_extra_thread_info(int tid) { + char comm[MAXCOMLEN + 1]; struct kthr *kt; struct proc *p; - static char comm[MAXCOMLEN + 1]; + static char buf[64]; kt = kgdb_thr_lookup_tid(tid); if (kt == NULL) - return (NULL); + return (NULL); + snprintf(buf, sizeof(buf), "PID=%d", kt->pid); p = (struct proc *)kt->paddr; if (kvm_read(kvm, (uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) != sizeof(comm)) - return (NULL); - - return (comm); + return (buf); + strlcat(buf, ": ", sizeof(buf)); + strlcat(buf, comm, sizeof(buf)); + return (buf); } Index: stable/6/gnu/usr.bin/gdb/kgdb/trgt.c =================================================================== --- stable/6/gnu/usr.bin/gdb/kgdb/trgt.c (revision 178878) +++ stable/6/gnu/usr.bin/gdb/kgdb/trgt.c (revision 178879) @@ -1,364 +1,354 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include #include #include +#include #include "kgdb.h" static void kgdb_core_cleanup(void *); static char *vmcore; static struct target_ops kgdb_trgt_ops; kvm_t *kvm; static char kvm_err[_POSIX2_LINE_MAX]; #define KERNOFF (kgdb_kernbase ()) #define INKERNEL(x) ((x) >= KERNOFF) static CORE_ADDR kgdb_kernbase (void) { static CORE_ADDR kernbase; struct minimal_symbol *sym; if (kernbase == 0) { sym = lookup_minimal_symbol ("kernbase", NULL, NULL); if (sym == NULL) { kernbase = KERNBASE; } else { kernbase = SYMBOL_VALUE_ADDRESS (sym); } } return kernbase; } static void kgdb_trgt_open(char *filename, int from_tty) { struct cleanup *old_chain; struct thread_info *ti; struct kthr *kt; kvm_t *nkvm; char *temp; int ontop; target_preopen (from_tty); if (!filename) error ("No vmcore file specified."); if (!exec_bfd) error ("Can't open a vmcore without a kernel"); filename = tilde_expand (filename); if (filename[0] != '/') { temp = concat (current_directory, "/", filename, NULL); xfree(filename); filename = temp; } old_chain = make_cleanup (xfree, filename); nkvm = kvm_openfiles(bfd_get_filename(exec_bfd), filename, NULL, write_files ? O_RDWR : O_RDONLY, kvm_err); if (nkvm == NULL) error ("Failed to open vmcore: %s", kvm_err); /* Don't free the filename now and close any previous vmcore. */ discard_cleanups(old_chain); unpush_target(&kgdb_trgt_ops); kvm = nkvm; vmcore = filename; old_chain = make_cleanup(kgdb_core_cleanup, NULL); ontop = !push_target (&kgdb_trgt_ops); discard_cleanups (old_chain); kgdb_dmesg(); init_thread_list(); kt = kgdb_thr_init(); while (kt != NULL) { - ti = add_thread(ptid_build(kt->pid, 0, kt->tid)); + ti = add_thread(pid_to_ptid(kt->tid)); kt = kgdb_thr_next(kt); } if (curkthr != 0) - inferior_ptid = ptid_build(curkthr->pid, 0, curkthr->tid); + inferior_ptid = pid_to_ptid(curkthr->tid); if (ontop) { /* XXX: fetch registers? */ kld_init(); flush_cached_frames(); select_frame (get_current_frame()); print_stack_frame(get_selected_frame(), frame_relative_level(get_selected_frame()), 1); } else warning( "you won't be able to access this vmcore until you terminate\n\ your %s; do ``info files''", target_longname); } static void kgdb_trgt_close(int quitting) { if (kvm != NULL) { inferior_ptid = null_ptid; CLEAR_SOLIB(); if (kvm_close(kvm) != 0) warning("cannot close \"%s\": %s", vmcore, kvm_geterr(kvm)); kvm = NULL; xfree(vmcore); vmcore = NULL; if (kgdb_trgt_ops.to_sections) { xfree(kgdb_trgt_ops.to_sections); kgdb_trgt_ops.to_sections = NULL; kgdb_trgt_ops.to_sections_end = NULL; } } } static void kgdb_core_cleanup(void *arg) { kgdb_trgt_close(0); } static void kgdb_trgt_detach(char *args, int from_tty) { if (args) error ("Too many arguments"); unpush_target(&kgdb_trgt_ops); reinit_frame_cache(); if (from_tty) printf_filtered("No vmcore file now.\n"); } static char * kgdb_trgt_extra_thread_info(struct thread_info *ti) { - static char buf[64]; - char *p, *s; - p = buf + snprintf(buf, sizeof(buf), "PID=%d", ptid_get_pid(ti->ptid)); - s = kgdb_thr_extra_thread_info(ptid_get_tid(ti->ptid)); - if (s != NULL) - snprintf(p, sizeof(buf) - (p - buf), ": %s", s); - return (buf); + return (kgdb_thr_extra_thread_info(ptid_get_pid(ti->ptid))); } static void kgdb_trgt_files_info(struct target_ops *target) { printf_filtered ("\t`%s', ", vmcore); wrap_here (" "); printf_filtered ("file type %s.\n", "FreeBSD kernel vmcore"); } static void kgdb_trgt_find_new_threads(void) { struct target_ops *tb; if (kvm != NULL) return; tb = find_target_beneath(&kgdb_trgt_ops); if (tb->to_find_new_threads != NULL) tb->to_find_new_threads(); } static char * kgdb_trgt_pid_to_str(ptid_t ptid) { static char buf[33]; - snprintf(buf, sizeof(buf), "Thread %ld", ptid_get_tid(ptid)); + snprintf(buf, sizeof(buf), "Thread %d", ptid_get_pid(ptid)); return (buf); } static int kgdb_trgt_thread_alive(ptid_t ptid) { - return (kgdb_thr_lookup_tid(ptid_get_tid(ptid)) != NULL); + return (kgdb_thr_lookup_tid(ptid_get_pid(ptid)) != NULL); } static int kgdb_trgt_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write, struct mem_attrib *attrib, struct target_ops *target) { struct target_ops *tb; if (kvm != NULL) { if (len == 0) return (0); if (!write) return (kvm_read(kvm, memaddr, myaddr, len)); else return (kvm_write(kvm, memaddr, myaddr, len)); } tb = find_target_beneath(target); return (tb->to_xfer_memory(memaddr, myaddr, len, write, attrib, tb)); } static int kgdb_trgt_ignore_breakpoints(CORE_ADDR addr, char *contents) { return 0; } static void -kgdb_switch_to_thread(struct kthr *thr) +kgdb_switch_to_thread(int tid) { - if (thr->tid == ptid_get_tid(inferior_ptid)) - return; + char buf[16]; + int thread_id; - inferior_ptid = ptid_build(thr->pid, 0, thr->tid); - flush_cached_frames (); - registers_changed (); - stop_pc = read_pc (); - select_frame (get_current_frame ()); + thread_id = pid_to_thread_id(pid_to_ptid(tid)); + if (thread_id == 0) + error ("invalid tid"); + snprintf(buf, sizeof(buf), "%d", thread_id); + gdb_thread_select(uiout, buf); } static void kgdb_set_proc_cmd (char *arg, int from_tty) { CORE_ADDR addr; struct kthr *thr; if (!arg) error_no_arg ("proc address for the new context"); if (kvm == NULL) - error ("no kernel core file"); + error ("only supported for core file target"); addr = (CORE_ADDR) parse_and_eval_address (arg); if (!INKERNEL (addr)) { thr = kgdb_thr_lookup_pid((int)addr); if (thr == NULL) error ("invalid pid"); } else { thr = kgdb_thr_lookup_paddr(addr); if (thr == NULL) error("invalid proc address"); } - kgdb_switch_to_thread(thr); + kgdb_switch_to_thread(thr->tid); } static void kgdb_set_tid_cmd (char *arg, int from_tty) { CORE_ADDR addr; struct kthr *thr; if (!arg) error_no_arg ("TID or thread address for the new context"); - if (kvm == NULL) - error ("no kernel core file"); - addr = (CORE_ADDR) parse_and_eval_address (arg); - if (!INKERNEL (addr)) { - thr = kgdb_thr_lookup_tid((int)addr); - if (thr == NULL) - error ("invalid TID"); - } else { + if (kvm != NULL && INKERNEL (addr)) { thr = kgdb_thr_lookup_taddr(addr); if (thr == NULL) error("invalid thread address"); + addr = thr->tid; } - kgdb_switch_to_thread(thr); + kgdb_switch_to_thread(addr); } int fbsdcoreops_suppress_target = 1; void initialize_kgdb_target(void) { kgdb_trgt_ops.to_magic = OPS_MAGIC; kgdb_trgt_ops.to_shortname = "kernel"; kgdb_trgt_ops.to_longname = "kernel core dump file"; kgdb_trgt_ops.to_doc = "Use a vmcore file as a target. Specify the filename of the vmcore file."; kgdb_trgt_ops.to_stratum = core_stratum; kgdb_trgt_ops.to_has_memory = 1; kgdb_trgt_ops.to_has_registers = 1; kgdb_trgt_ops.to_has_stack = 1; kgdb_trgt_ops.to_open = kgdb_trgt_open; kgdb_trgt_ops.to_close = kgdb_trgt_close; kgdb_trgt_ops.to_attach = find_default_attach; kgdb_trgt_ops.to_detach = kgdb_trgt_detach; kgdb_trgt_ops.to_extra_thread_info = kgdb_trgt_extra_thread_info; kgdb_trgt_ops.to_fetch_registers = kgdb_trgt_fetch_registers; kgdb_trgt_ops.to_files_info = kgdb_trgt_files_info; kgdb_trgt_ops.to_find_new_threads = kgdb_trgt_find_new_threads; kgdb_trgt_ops.to_pid_to_str = kgdb_trgt_pid_to_str; kgdb_trgt_ops.to_store_registers = kgdb_trgt_store_registers; kgdb_trgt_ops.to_thread_alive = kgdb_trgt_thread_alive; kgdb_trgt_ops.to_xfer_memory = kgdb_trgt_xfer_memory; kgdb_trgt_ops.to_insert_breakpoint = kgdb_trgt_ignore_breakpoints; kgdb_trgt_ops.to_remove_breakpoint = kgdb_trgt_ignore_breakpoints; add_target(&kgdb_trgt_ops); add_com ("proc", class_obscure, kgdb_set_proc_cmd, "Set current process context"); add_com ("tid", class_obscure, kgdb_set_tid_cmd, "Set current thread context"); } Index: stable/6/gnu/usr.bin/gdb/kgdb/trgt_alpha.c =================================================================== --- stable/6/gnu/usr.bin/gdb/kgdb/trgt_alpha.c (revision 178878) +++ stable/6/gnu/usr.bin/gdb/kgdb/trgt_alpha.c (revision 178879) @@ -1,188 +1,188 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } #define ALPHA_S0_REGNUM ALPHA_T7_REGNUM + 1 supply_register(ALPHA_S0_REGNUM + 0, (char *)&pcb.pcb_context[0]); supply_register(ALPHA_S0_REGNUM + 1, (char *)&pcb.pcb_context[1]); supply_register(ALPHA_S0_REGNUM + 2, (char *)&pcb.pcb_context[2]); supply_register(ALPHA_S0_REGNUM + 3, (char *)&pcb.pcb_context[3]); supply_register(ALPHA_S0_REGNUM + 4, (char *)&pcb.pcb_context[4]); supply_register(ALPHA_S0_REGNUM + 5, (char *)&pcb.pcb_context[5]); supply_register(ALPHA_S0_REGNUM + 6, (char *)&pcb.pcb_context[6]); supply_register(ALPHA_SP_REGNUM, (char *)&pcb.pcb_hw.apcb_ksp); supply_register(ALPHA_PC_REGNUM, (char *)&pcb.pcb_context[7]); #undef ALPHA_S0_REGNUM } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } struct kgdb_frame_cache { CORE_ADDR pc; CORE_ADDR sp; }; static int kgdb_trgt_frame_offset[65] = { FRAME_V0, FRAME_T0, FRAME_T1, FRAME_T2, FRAME_T3, FRAME_T4, FRAME_T5, FRAME_T6, FRAME_T7, FRAME_S0, FRAME_S1, FRAME_S2, FRAME_S3, FRAME_S4, FRAME_S5, FRAME_S6, FRAME_A0, FRAME_A1, FRAME_A2, FRAME_A3, FRAME_A4, FRAME_A5, FRAME_T8, FRAME_T9, FRAME_T10, FRAME_T11, FRAME_RA, FRAME_T12, -1, FRAME_GP, FRAME_SP, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, FRAME_PC }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; ofs = (regnum >= 0 && regnum <= ALPHA_PC_REGNUM) ? kgdb_trgt_frame_offset[regnum] : -1; if (ofs == -1) return; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *addrp = cache->sp + ofs * 8; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_func_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strncmp(pname, "Xent", 4) == 0) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %lx =%s\n", __func__, pc, pname); */ return (NULL); } Index: stable/6/gnu/usr.bin/gdb/kgdb/trgt_amd64.c =================================================================== --- stable/6/gnu/usr.bin/gdb/kgdb/trgt_amd64.c (revision 178878) +++ stable/6/gnu/usr.bin/gdb/kgdb/trgt_amd64.c (revision 178879) @@ -1,191 +1,191 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(AMD64_RBX_REGNUM, (char *)&pcb.pcb_rbx); supply_register(AMD64_RBP_REGNUM, (char *)&pcb.pcb_rbp); supply_register(AMD64_RSP_REGNUM, (char *)&pcb.pcb_rsp); supply_register(AMD64_R8_REGNUM + 4, (char *)&pcb.pcb_r12); supply_register(AMD64_R8_REGNUM + 5, (char *)&pcb.pcb_r13); supply_register(AMD64_R8_REGNUM + 6, (char *)&pcb.pcb_r14); supply_register(AMD64_R15_REGNUM, (char *)&pcb.pcb_r15); supply_register(AMD64_RIP_REGNUM, (char *)&pcb.pcb_rip); } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } struct kgdb_frame_cache { CORE_ADDR pc; CORE_ADDR sp; }; static int kgdb_trgt_frame_offset[20] = { offsetof(struct trapframe, tf_rax), offsetof(struct trapframe, tf_rbx), offsetof(struct trapframe, tf_rcx), offsetof(struct trapframe, tf_rdx), offsetof(struct trapframe, tf_rsi), offsetof(struct trapframe, tf_rdi), offsetof(struct trapframe, tf_rbp), offsetof(struct trapframe, tf_rsp), offsetof(struct trapframe, tf_r8), offsetof(struct trapframe, tf_r9), offsetof(struct trapframe, tf_r10), offsetof(struct trapframe, tf_r11), offsetof(struct trapframe, tf_r12), offsetof(struct trapframe, tf_r13), offsetof(struct trapframe, tf_r14), offsetof(struct trapframe, tf_r15), offsetof(struct trapframe, tf_rip), offsetof(struct trapframe, tf_rflags), offsetof(struct trapframe, tf_cs), offsetof(struct trapframe, tf_ss) }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; ofs = (regnum >= AMD64_RAX_REGNUM && regnum <= AMD64_EFLAGS_REGNUM + 2) ? kgdb_trgt_frame_offset[regnum] : -1; if (ofs == -1) return; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *addrp = cache->sp + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_pc_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strcmp(pname, "calltrap") == 0 || strcmp(pname, "nmi_calltrap") == 0 || (pname[0] == 'X' && pname[1] != '_')) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %lx =%s\n", __func__, pc, pname); */ return (NULL); } Index: stable/6/gnu/usr.bin/gdb/kgdb/trgt_arm.c =================================================================== --- stable/6/gnu/usr.bin/gdb/kgdb/trgt_arm.c (revision 178878) +++ stable/6/gnu/usr.bin/gdb/kgdb/trgt_arm.c (revision 178879) @@ -1,237 +1,237 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #ifndef CROSS_DEBUGGER #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { #ifndef CROSS_DEBUGGER struct kthr *kt; struct pcb pcb; int i, reg; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } for (i = ARM_A1_REGNUM + 8; i <= ARM_SP_REGNUM; i++) { supply_register(i, (char *)&pcb.un_32.pcb32_r8 + (i - (ARM_A1_REGNUM + 8 )) * 4); } if (pcb.un_32.pcb32_sp != 0) { for (i = 0; i < 4; i++) { if (kvm_read(kvm, pcb.un_32.pcb32_sp + (i) * 4, ®, 4) != 4) { warnx("kvm_read: %s", kvm_geterr(kvm)); break; } supply_register(ARM_A1_REGNUM + 4 + i, (char *)®); } if (kvm_read(kvm, pcb.un_32.pcb32_sp + 4 * 4, ®, 4) != 4) warnx("kvm_read :%s", kvm_geterr(kvm)); else supply_register(ARM_PC_REGNUM, (char *)®); } #endif } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } #ifndef CROSS_DEBUGGER struct kgdb_frame_cache { CORE_ADDR fp; CORE_ADDR sp; }; static int kgdb_trgt_frame_offset[26] = { offsetof(struct trapframe, tf_r0), offsetof(struct trapframe, tf_r1), offsetof(struct trapframe, tf_r2), offsetof(struct trapframe, tf_r3), offsetof(struct trapframe, tf_r4), offsetof(struct trapframe, tf_r5), offsetof(struct trapframe, tf_r6), offsetof(struct trapframe, tf_r7), offsetof(struct trapframe, tf_r8), offsetof(struct trapframe, tf_r9), offsetof(struct trapframe, tf_r10), offsetof(struct trapframe, tf_r11), offsetof(struct trapframe, tf_r12), offsetof(struct trapframe, tf_svc_sp), offsetof(struct trapframe, tf_svc_lr), offsetof(struct trapframe, tf_pc), -1, -1, -1, -1, -1, -1, -1, -1, -1, offsetof(struct trapframe, tf_spsr) }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; frame_unwind_register(next_frame, ARM_SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, ARM_SP_REGNUM)); frame_unwind_register(next_frame, ARM_FP_REGNUM, buf); cache->fp = extract_unsigned_integer(buf, register_size(current_gdbarch, ARM_FP_REGNUM)); } return (cache); } static int is_undef; static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->fp, 0); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; int is_undefined = 0; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; ofs = (regnum >= 0 && regnum <= ARM_PS_REGNUM) ? kgdb_trgt_frame_offset[regnum] : -1; if (ofs == -1) return; cache = kgdb_trgt_frame_cache(next_frame, this_cache); if (is_undef && (regnum == ARM_SP_REGNUM || regnum == ARM_PC_REGNUM)) { *addrp = cache->sp + offsetof(struct trapframe, tf_spsr); target_read_memory(*addrp, valuep, regsz); is_undefined = 1; ofs = kgdb_trgt_frame_offset[ARM_SP_REGNUM]; } *addrp = cache->sp + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); if (is_undefined) { *addrp = *(unsigned int *)valuep + (regnum == ARM_SP_REGNUM ? 0 : 8); target_read_memory(*addrp, valuep, regsz); } } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; #endif const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { #ifndef CROSS_DEBUGGER char *pname; CORE_ADDR pc; pc = frame_pc_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) { is_undef = 0; return (NULL); } if (!strcmp(pname, "undefinedinstruction")) is_undef = 1; if (strcmp(pname, "Laddress_exception_entry") == 0 || strcmp(pname, "undefined_entry") == 0 || strcmp(pname, "exception_exit") == 0 || strcmp(pname, "Laddress_exception_msg") == 0 || strcmp(pname, "irq_entry") == 0) return (&kgdb_trgt_trapframe_unwind); if (!strcmp(pname, "undefinedinstruction")) is_undef = 1; else is_undef = 0; #endif return (NULL); } Index: stable/6/gnu/usr.bin/gdb/kgdb/trgt_i386.c =================================================================== --- stable/6/gnu/usr.bin/gdb/kgdb/trgt_i386.c (revision 178878) +++ stable/6/gnu/usr.bin/gdb/kgdb/trgt_i386.c (revision 178879) @@ -1,339 +1,339 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(I386_EBX_REGNUM, (char *)&pcb.pcb_ebx); supply_register(I386_ESP_REGNUM, (char *)&pcb.pcb_esp); supply_register(I386_EBP_REGNUM, (char *)&pcb.pcb_ebp); supply_register(I386_ESI_REGNUM, (char *)&pcb.pcb_esi); supply_register(I386_EDI_REGNUM, (char *)&pcb.pcb_edi); supply_register(I386_EIP_REGNUM, (char *)&pcb.pcb_eip); } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } struct kgdb_tss_cache { CORE_ADDR pc; CORE_ADDR sp; CORE_ADDR tss; }; static int kgdb_trgt_tss_offset[15] = { offsetof(struct i386tss, tss_eax), offsetof(struct i386tss, tss_ecx), offsetof(struct i386tss, tss_edx), offsetof(struct i386tss, tss_ebx), offsetof(struct i386tss, tss_esp), offsetof(struct i386tss, tss_ebp), offsetof(struct i386tss, tss_esi), offsetof(struct i386tss, tss_edi), offsetof(struct i386tss, tss_eip), offsetof(struct i386tss, tss_eflags), offsetof(struct i386tss, tss_cs), offsetof(struct i386tss, tss_ss), offsetof(struct i386tss, tss_ds), offsetof(struct i386tss, tss_es), offsetof(struct i386tss, tss_fs) }; /* * If the current thread is executing on a CPU, fetch the common_tss * for that CPU. * * This is painful because 'struct pcpu' is variant sized, so we can't * use it. Instead, we lookup the GDT selector for this CPU and * extract the base of the TSS from there. */ static CORE_ADDR kgdb_trgt_fetch_tss(void) { struct kthr *kt; struct segment_descriptor sd; uintptr_t addr, cpu0prvpage, tss; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL || kt->cpu == NOCPU) return (0); addr = kgdb_lookup("_gdt"); if (addr == 0) return (0); addr += (kt->cpu * NGDT + GPROC0_SEL) * sizeof(sd); if (kvm_read(kvm, addr, &sd, sizeof(sd)) != sizeof(sd)) { warnx("kvm_read: %s", kvm_geterr(kvm)); return (0); } if (sd.sd_type != SDT_SYS386BSY) { warnx("descriptor is not a busy TSS"); return (0); } tss = sd.sd_hibase << 24 | sd.sd_lobase; /* * In SMP kernels, the TSS is stored as part of the per-CPU * data. On older kernels, the CPU0's private page * is stored at an address that isn't mapped in minidumps. * However, the data is mapped at the alternate cpu0prvpage * address. Thus, if the TSS is at the invalid address, * change it to be relative to cpu0prvpage instead. */ if (trunc_page(tss) == 0xffc00000) { addr = kgdb_lookup("_cpu0prvpage"); if (addr == 0) { warnx("kvm_nlist(_cpu0prvpage): %s", kvm_geterr(kvm)); return (0); } if (kvm_read(kvm, addr, &cpu0prvpage, sizeof(cpu0prvpage)) != sizeof(cpu0prvpage)) { warnx("kvm_read: %s", kvm_geterr(kvm)); return (0); } tss = cpu0prvpage + (tss & PAGE_MASK); } return ((CORE_ADDR)tss); } static struct kgdb_tss_cache * kgdb_trgt_tss_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_tss_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_tss_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); cache->tss = kgdb_trgt_fetch_tss(); } return (cache); } static void kgdb_trgt_dblfault_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_tss_cache *cache; cache = kgdb_trgt_tss_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_dblfault_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_tss_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; ofs = (regnum >= I386_EAX_REGNUM && regnum <= I386_FS_REGNUM) ? kgdb_trgt_tss_offset[regnum] : -1; if (ofs == -1) return; cache = kgdb_trgt_tss_cache(next_frame, this_cache); if (cache->tss == 0) return; *addrp = cache->tss + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_dblfault_unwind = { UNKNOWN_FRAME, &kgdb_trgt_dblfault_this_id, &kgdb_trgt_dblfault_prev_register }; struct kgdb_frame_cache { int intrframe; CORE_ADDR pc; CORE_ADDR sp; }; static int kgdb_trgt_frame_offset[15] = { offsetof(struct trapframe, tf_eax), offsetof(struct trapframe, tf_ecx), offsetof(struct trapframe, tf_edx), offsetof(struct trapframe, tf_ebx), offsetof(struct trapframe, tf_esp), offsetof(struct trapframe, tf_ebp), offsetof(struct trapframe, tf_esi), offsetof(struct trapframe, tf_edi), offsetof(struct trapframe, tf_eip), offsetof(struct trapframe, tf_eflags), offsetof(struct trapframe, tf_cs), offsetof(struct trapframe, tf_ss), offsetof(struct trapframe, tf_ds), offsetof(struct trapframe, tf_es), offsetof(struct trapframe, tf_fs) }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; char *pname; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); find_pc_partial_function(cache->pc, &pname, NULL, NULL); cache->intrframe = (pname[0] == 'X') ? 1 : 0; frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; ofs = (regnum >= I386_EAX_REGNUM && regnum <= I386_FS_REGNUM) ? kgdb_trgt_frame_offset[regnum] : -1; if (ofs == -1) return; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *addrp = cache->sp + ofs + (cache->intrframe ? 4 : 0); *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_pc_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strcmp(pname, "dblfault_handler") == 0) return (&kgdb_trgt_dblfault_unwind); if (strcmp(pname, "calltrap") == 0 || (pname[0] == 'X' && pname[1] != '_')) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %llx =%s\n", __func__, pc, pname); */ return (NULL); } Index: stable/6/gnu/usr.bin/gdb/kgdb/trgt_ia64.c =================================================================== --- stable/6/gnu/usr.bin/gdb/kgdb/trgt_ia64.c (revision 178878) +++ stable/6/gnu/usr.bin/gdb/kgdb/trgt_ia64.c (revision 178879) @@ -1,319 +1,319 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; uint64_t r; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } /* Registers 0-127: general registers. */ supply_register(IA64_GR1_REGNUM, (char *)&pcb.pcb_special.gp); supply_register(IA64_GR4_REGNUM, (char *)&pcb.pcb_preserved.gr4); supply_register(IA64_GR5_REGNUM, (char *)&pcb.pcb_preserved.gr5); supply_register(IA64_GR6_REGNUM, (char *)&pcb.pcb_preserved.gr6); supply_register(IA64_GR7_REGNUM, (char *)&pcb.pcb_preserved.gr7); supply_register(IA64_GR12_REGNUM, (char *)&pcb.pcb_special.sp); supply_register(IA64_GR12_REGNUM+1, (char *)&pcb.pcb_special.tp); /* Registers 128-255: floating-point registers. */ supply_register(IA64_FR2_REGNUM, (char *)&pcb.pcb_preserved_fp.fr2); supply_register(IA64_FR2_REGNUM+1, (char *)&pcb.pcb_preserved_fp.fr3); supply_register(IA64_FR2_REGNUM+2, (char *)&pcb.pcb_preserved_fp.fr4); supply_register(IA64_FR2_REGNUM+3, (char *)&pcb.pcb_preserved_fp.fr5); supply_register(IA64_FR16_REGNUM, (char *)&pcb.pcb_preserved_fp.fr16); supply_register(IA64_FR16_REGNUM+1, (char*)&pcb.pcb_preserved_fp.fr17); supply_register(IA64_FR16_REGNUM+2, (char*)&pcb.pcb_preserved_fp.fr18); supply_register(IA64_FR16_REGNUM+3, (char*)&pcb.pcb_preserved_fp.fr19); supply_register(IA64_FR16_REGNUM+4, (char*)&pcb.pcb_preserved_fp.fr20); supply_register(IA64_FR16_REGNUM+5, (char*)&pcb.pcb_preserved_fp.fr21); supply_register(IA64_FR16_REGNUM+6, (char*)&pcb.pcb_preserved_fp.fr22); supply_register(IA64_FR16_REGNUM+7, (char*)&pcb.pcb_preserved_fp.fr23); supply_register(IA64_FR16_REGNUM+8, (char*)&pcb.pcb_preserved_fp.fr24); supply_register(IA64_FR16_REGNUM+9, (char*)&pcb.pcb_preserved_fp.fr25); supply_register(IA64_FR16_REGNUM+10,(char*)&pcb.pcb_preserved_fp.fr26); supply_register(IA64_FR16_REGNUM+11,(char*)&pcb.pcb_preserved_fp.fr27); supply_register(IA64_FR16_REGNUM+12,(char*)&pcb.pcb_preserved_fp.fr28); supply_register(IA64_FR16_REGNUM+13,(char*)&pcb.pcb_preserved_fp.fr29); supply_register(IA64_FR16_REGNUM+14,(char*)&pcb.pcb_preserved_fp.fr30); supply_register(IA64_FR16_REGNUM+15,(char*)&pcb.pcb_preserved_fp.fr31); /* Registers 320-327: branch registers. */ if (pcb.pcb_special.__spare == ~0UL) supply_register(IA64_BR0_REGNUM, (char *)&pcb.pcb_special.rp); supply_register(IA64_BR1_REGNUM, (char *)&pcb.pcb_preserved.br1); supply_register(IA64_BR2_REGNUM, (char *)&pcb.pcb_preserved.br2); supply_register(IA64_BR3_REGNUM, (char *)&pcb.pcb_preserved.br3); supply_register(IA64_BR4_REGNUM, (char *)&pcb.pcb_preserved.br4); supply_register(IA64_BR5_REGNUM, (char *)&pcb.pcb_preserved.br5); /* Registers 328-333: misc. other registers. */ supply_register(IA64_PR_REGNUM, (char *)&pcb.pcb_special.pr); if (pcb.pcb_special.__spare == ~0UL) { r = pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3); supply_register(IA64_IP_REGNUM, (char *)&r); supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.cfm); } else { supply_register(IA64_IP_REGNUM, (char *)&pcb.pcb_special.rp); supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.pfs); } /* Registers 334-461: application registers. */ supply_register(IA64_RSC_REGNUM, (char *)&pcb.pcb_special.rsc); r = pcb.pcb_special.bspstore; if (pcb.pcb_special.__spare == ~0UL) r += pcb.pcb_special.ndirty; else r = ia64_bsp_adjust(r, IA64_CFM_SOF(pcb.pcb_special.pfs) - IA64_CFM_SOL(pcb.pcb_special.pfs)); supply_register(IA64_BSP_REGNUM, (char *)&r); supply_register(IA64_BSPSTORE_REGNUM, (char *)&r); supply_register(IA64_RNAT_REGNUM, (char *)&pcb.pcb_special.rnat); supply_register(IA64_UNAT_REGNUM, (char *)&pcb.pcb_special.unat); supply_register(IA64_FPSR_REGNUM, (char *)&pcb.pcb_special.fpsr); if (pcb.pcb_special.__spare == ~0UL) supply_register(IA64_PFS_REGNUM, (char *)&pcb.pcb_special.pfs); supply_register(IA64_LC_REGNUM, (char *)&pcb.pcb_preserved.lc); } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } struct kgdb_frame_cache { CORE_ADDR bsp; CORE_ADDR ip; CORE_ADDR sp; CORE_ADDR saved_bsp; }; #define SPECIAL(x) offsetof(struct trapframe, tf_special) \ + offsetof(struct _special, x) #define SCRATCH(x) offsetof(struct trapframe, tf_scratch) \ + offsetof(struct _caller_saved, x) #define SCRATCH_FP(x) offsetof(struct trapframe, tf_scratch_fp) \ + offsetof(struct _caller_saved_fp, x) static int kgdb_trgt_frame_ofs_gr[32] = { -1, /* gr0 */ SPECIAL(gp), SCRATCH(gr2), SCRATCH(gr3), -1, -1, -1, -1, /* gr4-gr7 */ SCRATCH(gr8), SCRATCH(gr9), SCRATCH(gr10), SCRATCH(gr11), SPECIAL(sp), SPECIAL(tp), SCRATCH(gr14), SCRATCH(gr15), SCRATCH(gr16), SCRATCH(gr17), SCRATCH(gr18), SCRATCH(gr19), SCRATCH(gr20), SCRATCH(gr21), SCRATCH(gr22), SCRATCH(gr23), SCRATCH(gr24), SCRATCH(gr25), SCRATCH(gr26), SCRATCH(gr27), SCRATCH(gr28), SCRATCH(gr29), SCRATCH(gr30), SCRATCH(gr31) }; static int kgdb_trgt_frame_ofs_fr[32] = { -1, /* fr0: constant 0.0 */ -1, /* fr1: constant 1.0 */ -1, -1, -1, -1, /* fr2-fr5 */ SCRATCH_FP(fr6), SCRATCH_FP(fr7), SCRATCH_FP(fr8), SCRATCH_FP(fr9), SCRATCH_FP(fr10), SCRATCH_FP(fr11), SCRATCH_FP(fr12), SCRATCH_FP(fr13), SCRATCH_FP(fr14), SCRATCH_FP(fr15) }; static int kgdb_trgt_frame_ofs_br[8] = { SPECIAL(rp), -1, -1, -1, -1, -1, /* br1-br5 */ SCRATCH(br6), SCRATCH(br7) }; static int kgdb_trgt_frame_ofs_ar[49] = { /* ar0-ar15 */ SPECIAL(rsc), -1, /* ar.bsp */ SPECIAL(bspstore), SPECIAL(rnat), -1, -1, -1, -1, -1, /* ar20-ar24 */ SCRATCH(csd), SCRATCH(ssd), -1, -1, -1, -1, -1, /* ar27-ar31 */ SCRATCH(ccv), -1, -1, -1, /* ar33-ar35 */ SPECIAL(unat), -1, -1, -1, /* ar37-ar39 */ SPECIAL(fpsr), -1, -1, -1, -1, -1, -1, -1, /* ar41-ar47 */ -1, -1, -1, -1, -1, -1, -1, -1, /* ar48-ar55 */ -1, -1, -1, -1, -1, -1, -1, -1, /* ar56-ar63 */ SPECIAL(pfs) }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; frame_unwind_register(next_frame, IA64_BSP_REGNUM, buf); cache->bsp = extract_unsigned_integer(buf, register_size(current_gdbarch, IA64_BSP_REGNUM)); cache->ip = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build_special(cache->sp, cache->ip, cache->bsp); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char buf[MAX_REGISTER_SIZE]; char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; CORE_ADDR bsp; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; cache = kgdb_trgt_frame_cache(next_frame, this_cache); if (regnum == IA64_BSP_REGNUM) { if (cache->saved_bsp == 0) { target_read_memory(cache->sp + 16 + SPECIAL(bspstore), buf, regsz); bsp = extract_unsigned_integer(buf, regsz); target_read_memory(cache->sp + 16 + SPECIAL(ndirty), buf, regsz); bsp += extract_unsigned_integer(buf, regsz); cache->saved_bsp = bsp; } store_unsigned_integer(valuep, regsz, cache->saved_bsp); return; } if (regnum == IA64_PR_REGNUM) ofs = SPECIAL(pr); else if (regnum == IA64_IP_REGNUM) ofs = SPECIAL(iip); else if (regnum == IA64_PSR_REGNUM) ofs = SPECIAL(psr); else if (regnum == IA64_CFM_REGNUM) ofs = SPECIAL(cfm); else if (regnum >= IA64_GR0_REGNUM && regnum <= IA64_GR31_REGNUM) ofs = kgdb_trgt_frame_ofs_gr[regnum - IA64_GR0_REGNUM]; else if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR15_REGNUM) ofs = kgdb_trgt_frame_ofs_fr[regnum - IA64_FR0_REGNUM]; else if (regnum >= IA64_BR0_REGNUM && regnum <= IA64_BR7_REGNUM) ofs = kgdb_trgt_frame_ofs_br[regnum - IA64_BR0_REGNUM]; else if (regnum >= IA64_RSC_REGNUM && regnum <= IA64_PFS_REGNUM) ofs = kgdb_trgt_frame_ofs_ar[regnum - IA64_RSC_REGNUM]; else ofs = -1; if (ofs == -1) return; *addrp = cache->sp + 16 + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR ip; ip = frame_func_unwind(next_frame); pname = NULL; find_pc_partial_function(ip, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strncmp(pname, "ivt_", 4) == 0) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %lx =%s\n", __func__, ip, pname); */ return (NULL); } Index: stable/6/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c =================================================================== --- stable/6/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c (revision 178878) +++ stable/6/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c (revision 178879) @@ -1,199 +1,199 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(SPARC_SP_REGNUM, (char *)&pcb.pcb_sp); sparc_supply_rwindow(current_regcache, pcb.pcb_sp, -1); supply_register(SPARC64_PC_REGNUM, (char *)&pcb.pcb_pc); pcb.pcb_pc += 4; supply_register(SPARC64_NPC_REGNUM, (char *)&pcb.pcb_pc); } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } struct kgdb_frame_cache { CORE_ADDR pc; CORE_ADDR sp; CORE_ADDR fp; }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SPARC_SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SPARC_SP_REGNUM)); frame_unwind_register(next_frame, SPARC_FP_REGNUM, buf); cache->fp = extract_unsigned_integer(buf, register_size(current_gdbarch, SPARC_FP_REGNUM)); cache->fp += BIAS - sizeof(struct trapframe); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; cache = kgdb_trgt_frame_cache(next_frame, this_cache); switch (regnum) { case SPARC_SP_REGNUM: ofs = offsetof(struct trapframe, tf_sp); break; case SPARC64_PC_REGNUM: ofs = offsetof(struct trapframe, tf_tpc); break; case SPARC64_NPC_REGNUM: ofs = offsetof(struct trapframe, tf_tnpc); break; case SPARC_O0_REGNUM: case SPARC_O1_REGNUM: case SPARC_O2_REGNUM: case SPARC_O3_REGNUM: case SPARC_O4_REGNUM: case SPARC_O5_REGNUM: case SPARC_O7_REGNUM: ofs = offsetof(struct trapframe, tf_out) + (regnum - SPARC_O0_REGNUM) * 8; break; default: if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) { ofs = (regnum - SPARC_L0_REGNUM) * 8; *addrp = cache->sp + BIAS + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } return; } *addrp = cache->fp + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_func_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strcmp(pname, "tl0_intr") == 0 || strcmp(pname, "tl0_trap") == 0 || strcmp(pname, "tl1_intr") == 0 || strcmp(pname, "tl1_trap") == 0) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %lx =%s\n", __func__, pc, pname); */ return (NULL); } Index: stable/7/gnu/usr.bin/gdb/kgdb/kthr.c =================================================================== --- stable/7/gnu/usr.bin/gdb/kgdb/kthr.c (revision 178878) +++ stable/7/gnu/usr.bin/gdb/kgdb/kthr.c (revision 178879) @@ -1,228 +1,232 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include +#include #include #include #include "kgdb.h" #include static uintptr_t dumppcb; static int dumptid; static uintptr_t stoppcbs; static __cpumask_t stopped_cpus; static struct kthr *first; struct kthr *curkthr; uintptr_t kgdb_lookup(const char *sym) { struct nlist nl[2]; nl[0].n_name = (char *)(uintptr_t)sym; nl[1].n_name = NULL; if (kvm_nlist(kvm, nl) != 0) return (0); return (nl[0].n_value); } struct kthr * kgdb_thr_first(void) { return (first); } struct kthr * kgdb_thr_init(void) { struct proc p; struct thread td; struct kthr *kt; uintptr_t addr, paddr; while (first != NULL) { kt = first; first = kt->next; free(kt); } addr = kgdb_lookup("_allproc"); if (addr == 0) { warnx("kvm_nlist(_allproc): %s", kvm_geterr(kvm)); return (NULL); } kvm_read(kvm, addr, &paddr, sizeof(paddr)); dumppcb = kgdb_lookup("_dumppcb"); if (dumppcb == 0) { warnx("kvm_nlist(_dumppcb): %s", kvm_geterr(kvm)); return (NULL); } addr = kgdb_lookup("_dumptid"); if (addr != 0) kvm_read(kvm, addr, &dumptid, sizeof(dumptid)); else dumptid = -1; addr = kgdb_lookup("_stopped_cpus"); if (addr != 0) kvm_read(kvm, addr, &stopped_cpus, sizeof(stopped_cpus)); else stopped_cpus = 0; stoppcbs = kgdb_lookup("_stoppcbs"); while (paddr != 0) { if (kvm_read(kvm, paddr, &p, sizeof(p)) != sizeof(p)) { warnx("kvm_read: %s", kvm_geterr(kvm)); break; } addr = (uintptr_t)TAILQ_FIRST(&p.p_threads); while (addr != 0) { if (kvm_read(kvm, addr, &td, sizeof(td)) != sizeof(td)) { warnx("kvm_read: %s", kvm_geterr(kvm)); break; } kt = malloc(sizeof(*kt)); kt->next = first; kt->kaddr = addr; if (td.td_tid == dumptid) kt->pcb = dumppcb; else if (td.td_state == TDS_RUNNING && ((1 << td.td_oncpu) & stopped_cpus) && stoppcbs != 0) kt->pcb = (uintptr_t) stoppcbs + sizeof(struct pcb) * td.td_oncpu; else kt->pcb = (uintptr_t)td.td_pcb; kt->kstack = td.td_kstack; kt->tid = td.td_tid; kt->pid = p.p_pid; kt->paddr = paddr; kt->cpu = td.td_oncpu; first = kt; addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); } paddr = (uintptr_t)LIST_NEXT(&p, p_list); } curkthr = kgdb_thr_lookup_tid(dumptid); if (curkthr == NULL) curkthr = first; return (first); } struct kthr * kgdb_thr_lookup_tid(int tid) { struct kthr *kt; kt = first; while (kt != NULL && kt->tid != tid) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_taddr(uintptr_t taddr) { struct kthr *kt; kt = first; while (kt != NULL && kt->kaddr != taddr) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_pid(int pid) { struct kthr *kt; kt = first; while (kt != NULL && kt->pid != pid) kt = kt->next; return (kt); } struct kthr * kgdb_thr_lookup_paddr(uintptr_t paddr) { struct kthr *kt; kt = first; while (kt != NULL && kt->paddr != paddr) kt = kt->next; return (kt); } struct kthr * kgdb_thr_next(struct kthr *kt) { return (kt->next); } struct kthr * kgdb_thr_select(struct kthr *kt) { struct kthr *pcur; pcur = curkthr; curkthr = kt; return (pcur); } char * kgdb_thr_extra_thread_info(int tid) { + char comm[MAXCOMLEN + 1]; struct kthr *kt; struct proc *p; - static char comm[MAXCOMLEN + 1]; + static char buf[64]; kt = kgdb_thr_lookup_tid(tid); if (kt == NULL) - return (NULL); + return (NULL); + snprintf(buf, sizeof(buf), "PID=%d", kt->pid); p = (struct proc *)kt->paddr; if (kvm_read(kvm, (uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) != sizeof(comm)) - return (NULL); - - return (comm); + return (buf); + strlcat(buf, ": ", sizeof(buf)); + strlcat(buf, comm, sizeof(buf)); + return (buf); } Index: stable/7/gnu/usr.bin/gdb/kgdb/trgt.c =================================================================== --- stable/7/gnu/usr.bin/gdb/kgdb/trgt.c (revision 178878) +++ stable/7/gnu/usr.bin/gdb/kgdb/trgt.c (revision 178879) @@ -1,364 +1,354 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include #include #include +#include #include "kgdb.h" static void kgdb_core_cleanup(void *); static char *vmcore; static struct target_ops kgdb_trgt_ops; kvm_t *kvm; static char kvm_err[_POSIX2_LINE_MAX]; #define KERNOFF (kgdb_kernbase ()) #define INKERNEL(x) ((x) >= KERNOFF) static CORE_ADDR kgdb_kernbase (void) { static CORE_ADDR kernbase; struct minimal_symbol *sym; if (kernbase == 0) { sym = lookup_minimal_symbol ("kernbase", NULL, NULL); if (sym == NULL) { kernbase = KERNBASE; } else { kernbase = SYMBOL_VALUE_ADDRESS (sym); } } return kernbase; } static void kgdb_trgt_open(char *filename, int from_tty) { struct cleanup *old_chain; struct thread_info *ti; struct kthr *kt; kvm_t *nkvm; char *temp; int ontop; target_preopen (from_tty); if (!filename) error ("No vmcore file specified."); if (!exec_bfd) error ("Can't open a vmcore without a kernel"); filename = tilde_expand (filename); if (filename[0] != '/') { temp = concat (current_directory, "/", filename, NULL); xfree(filename); filename = temp; } old_chain = make_cleanup (xfree, filename); nkvm = kvm_openfiles(bfd_get_filename(exec_bfd), filename, NULL, write_files ? O_RDWR : O_RDONLY, kvm_err); if (nkvm == NULL) error ("Failed to open vmcore: %s", kvm_err); /* Don't free the filename now and close any previous vmcore. */ discard_cleanups(old_chain); unpush_target(&kgdb_trgt_ops); kvm = nkvm; vmcore = filename; old_chain = make_cleanup(kgdb_core_cleanup, NULL); ontop = !push_target (&kgdb_trgt_ops); discard_cleanups (old_chain); kgdb_dmesg(); init_thread_list(); kt = kgdb_thr_init(); while (kt != NULL) { - ti = add_thread(ptid_build(kt->pid, 0, kt->tid)); + ti = add_thread(pid_to_ptid(kt->tid)); kt = kgdb_thr_next(kt); } if (curkthr != 0) - inferior_ptid = ptid_build(curkthr->pid, 0, curkthr->tid); + inferior_ptid = pid_to_ptid(curkthr->tid); if (ontop) { /* XXX: fetch registers? */ kld_init(); flush_cached_frames(); select_frame (get_current_frame()); print_stack_frame(get_selected_frame(), frame_relative_level(get_selected_frame()), 1); } else warning( "you won't be able to access this vmcore until you terminate\n\ your %s; do ``info files''", target_longname); } static void kgdb_trgt_close(int quitting) { if (kvm != NULL) { inferior_ptid = null_ptid; CLEAR_SOLIB(); if (kvm_close(kvm) != 0) warning("cannot close \"%s\": %s", vmcore, kvm_geterr(kvm)); kvm = NULL; xfree(vmcore); vmcore = NULL; if (kgdb_trgt_ops.to_sections) { xfree(kgdb_trgt_ops.to_sections); kgdb_trgt_ops.to_sections = NULL; kgdb_trgt_ops.to_sections_end = NULL; } } } static void kgdb_core_cleanup(void *arg) { kgdb_trgt_close(0); } static void kgdb_trgt_detach(char *args, int from_tty) { if (args) error ("Too many arguments"); unpush_target(&kgdb_trgt_ops); reinit_frame_cache(); if (from_tty) printf_filtered("No vmcore file now.\n"); } static char * kgdb_trgt_extra_thread_info(struct thread_info *ti) { - static char buf[64]; - char *p, *s; - p = buf + snprintf(buf, sizeof(buf), "PID=%d", ptid_get_pid(ti->ptid)); - s = kgdb_thr_extra_thread_info(ptid_get_tid(ti->ptid)); - if (s != NULL) - snprintf(p, sizeof(buf) - (p - buf), ": %s", s); - return (buf); + return (kgdb_thr_extra_thread_info(ptid_get_pid(ti->ptid))); } static void kgdb_trgt_files_info(struct target_ops *target) { printf_filtered ("\t`%s', ", vmcore); wrap_here (" "); printf_filtered ("file type %s.\n", "FreeBSD kernel vmcore"); } static void kgdb_trgt_find_new_threads(void) { struct target_ops *tb; if (kvm != NULL) return; tb = find_target_beneath(&kgdb_trgt_ops); if (tb->to_find_new_threads != NULL) tb->to_find_new_threads(); } static char * kgdb_trgt_pid_to_str(ptid_t ptid) { static char buf[33]; - snprintf(buf, sizeof(buf), "Thread %ld", ptid_get_tid(ptid)); + snprintf(buf, sizeof(buf), "Thread %d", ptid_get_pid(ptid)); return (buf); } static int kgdb_trgt_thread_alive(ptid_t ptid) { - return (kgdb_thr_lookup_tid(ptid_get_tid(ptid)) != NULL); + return (kgdb_thr_lookup_tid(ptid_get_pid(ptid)) != NULL); } static int kgdb_trgt_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write, struct mem_attrib *attrib, struct target_ops *target) { struct target_ops *tb; if (kvm != NULL) { if (len == 0) return (0); if (!write) return (kvm_read(kvm, memaddr, myaddr, len)); else return (kvm_write(kvm, memaddr, myaddr, len)); } tb = find_target_beneath(target); return (tb->to_xfer_memory(memaddr, myaddr, len, write, attrib, tb)); } static int kgdb_trgt_ignore_breakpoints(CORE_ADDR addr, char *contents) { return 0; } static void -kgdb_switch_to_thread(struct kthr *thr) +kgdb_switch_to_thread(int tid) { - if (thr->tid == ptid_get_tid(inferior_ptid)) - return; + char buf[16]; + int thread_id; - inferior_ptid = ptid_build(thr->pid, 0, thr->tid); - flush_cached_frames (); - registers_changed (); - stop_pc = read_pc (); - select_frame (get_current_frame ()); + thread_id = pid_to_thread_id(pid_to_ptid(tid)); + if (thread_id == 0) + error ("invalid tid"); + snprintf(buf, sizeof(buf), "%d", thread_id); + gdb_thread_select(uiout, buf); } static void kgdb_set_proc_cmd (char *arg, int from_tty) { CORE_ADDR addr; struct kthr *thr; if (!arg) error_no_arg ("proc address for the new context"); if (kvm == NULL) - error ("no kernel core file"); + error ("only supported for core file target"); addr = (CORE_ADDR) parse_and_eval_address (arg); if (!INKERNEL (addr)) { thr = kgdb_thr_lookup_pid((int)addr); if (thr == NULL) error ("invalid pid"); } else { thr = kgdb_thr_lookup_paddr(addr); if (thr == NULL) error("invalid proc address"); } - kgdb_switch_to_thread(thr); + kgdb_switch_to_thread(thr->tid); } static void kgdb_set_tid_cmd (char *arg, int from_tty) { CORE_ADDR addr; struct kthr *thr; if (!arg) error_no_arg ("TID or thread address for the new context"); - if (kvm == NULL) - error ("no kernel core file"); - addr = (CORE_ADDR) parse_and_eval_address (arg); - if (!INKERNEL (addr)) { - thr = kgdb_thr_lookup_tid((int)addr); - if (thr == NULL) - error ("invalid TID"); - } else { + if (kvm != NULL && INKERNEL (addr)) { thr = kgdb_thr_lookup_taddr(addr); if (thr == NULL) error("invalid thread address"); + addr = thr->tid; } - kgdb_switch_to_thread(thr); + kgdb_switch_to_thread(addr); } int fbsdcoreops_suppress_target = 1; void initialize_kgdb_target(void) { kgdb_trgt_ops.to_magic = OPS_MAGIC; kgdb_trgt_ops.to_shortname = "kernel"; kgdb_trgt_ops.to_longname = "kernel core dump file"; kgdb_trgt_ops.to_doc = "Use a vmcore file as a target. Specify the filename of the vmcore file."; kgdb_trgt_ops.to_stratum = core_stratum; kgdb_trgt_ops.to_has_memory = 1; kgdb_trgt_ops.to_has_registers = 1; kgdb_trgt_ops.to_has_stack = 1; kgdb_trgt_ops.to_open = kgdb_trgt_open; kgdb_trgt_ops.to_close = kgdb_trgt_close; kgdb_trgt_ops.to_attach = find_default_attach; kgdb_trgt_ops.to_detach = kgdb_trgt_detach; kgdb_trgt_ops.to_extra_thread_info = kgdb_trgt_extra_thread_info; kgdb_trgt_ops.to_fetch_registers = kgdb_trgt_fetch_registers; kgdb_trgt_ops.to_files_info = kgdb_trgt_files_info; kgdb_trgt_ops.to_find_new_threads = kgdb_trgt_find_new_threads; kgdb_trgt_ops.to_pid_to_str = kgdb_trgt_pid_to_str; kgdb_trgt_ops.to_store_registers = kgdb_trgt_store_registers; kgdb_trgt_ops.to_thread_alive = kgdb_trgt_thread_alive; kgdb_trgt_ops.to_xfer_memory = kgdb_trgt_xfer_memory; kgdb_trgt_ops.to_insert_breakpoint = kgdb_trgt_ignore_breakpoints; kgdb_trgt_ops.to_remove_breakpoint = kgdb_trgt_ignore_breakpoints; add_target(&kgdb_trgt_ops); add_com ("proc", class_obscure, kgdb_set_proc_cmd, "Set current process context"); add_com ("tid", class_obscure, kgdb_set_tid_cmd, "Set current thread context"); } Index: stable/7/gnu/usr.bin/gdb/kgdb/trgt_amd64.c =================================================================== --- stable/7/gnu/usr.bin/gdb/kgdb/trgt_amd64.c (revision 178878) +++ stable/7/gnu/usr.bin/gdb/kgdb/trgt_amd64.c (revision 178879) @@ -1,191 +1,191 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(AMD64_RBX_REGNUM, (char *)&pcb.pcb_rbx); supply_register(AMD64_RBP_REGNUM, (char *)&pcb.pcb_rbp); supply_register(AMD64_RSP_REGNUM, (char *)&pcb.pcb_rsp); supply_register(AMD64_R8_REGNUM + 4, (char *)&pcb.pcb_r12); supply_register(AMD64_R8_REGNUM + 5, (char *)&pcb.pcb_r13); supply_register(AMD64_R8_REGNUM + 6, (char *)&pcb.pcb_r14); supply_register(AMD64_R15_REGNUM, (char *)&pcb.pcb_r15); supply_register(AMD64_RIP_REGNUM, (char *)&pcb.pcb_rip); } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } struct kgdb_frame_cache { CORE_ADDR pc; CORE_ADDR sp; }; static int kgdb_trgt_frame_offset[20] = { offsetof(struct trapframe, tf_rax), offsetof(struct trapframe, tf_rbx), offsetof(struct trapframe, tf_rcx), offsetof(struct trapframe, tf_rdx), offsetof(struct trapframe, tf_rsi), offsetof(struct trapframe, tf_rdi), offsetof(struct trapframe, tf_rbp), offsetof(struct trapframe, tf_rsp), offsetof(struct trapframe, tf_r8), offsetof(struct trapframe, tf_r9), offsetof(struct trapframe, tf_r10), offsetof(struct trapframe, tf_r11), offsetof(struct trapframe, tf_r12), offsetof(struct trapframe, tf_r13), offsetof(struct trapframe, tf_r14), offsetof(struct trapframe, tf_r15), offsetof(struct trapframe, tf_rip), offsetof(struct trapframe, tf_rflags), offsetof(struct trapframe, tf_cs), offsetof(struct trapframe, tf_ss) }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; ofs = (regnum >= AMD64_RAX_REGNUM && regnum <= AMD64_EFLAGS_REGNUM + 2) ? kgdb_trgt_frame_offset[regnum] : -1; if (ofs == -1) return; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *addrp = cache->sp + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_pc_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strcmp(pname, "calltrap") == 0 || strcmp(pname, "nmi_calltrap") == 0 || (pname[0] == 'X' && pname[1] != '_')) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %lx =%s\n", __func__, pc, pname); */ return (NULL); } Index: stable/7/gnu/usr.bin/gdb/kgdb/trgt_arm.c =================================================================== --- stable/7/gnu/usr.bin/gdb/kgdb/trgt_arm.c (revision 178878) +++ stable/7/gnu/usr.bin/gdb/kgdb/trgt_arm.c (revision 178879) @@ -1,237 +1,237 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #ifndef CROSS_DEBUGGER #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { #ifndef CROSS_DEBUGGER struct kthr *kt; struct pcb pcb; int i, reg; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } for (i = ARM_A1_REGNUM + 8; i <= ARM_SP_REGNUM; i++) { supply_register(i, (char *)&pcb.un_32.pcb32_r8 + (i - (ARM_A1_REGNUM + 8 )) * 4); } if (pcb.un_32.pcb32_sp != 0) { for (i = 0; i < 4; i++) { if (kvm_read(kvm, pcb.un_32.pcb32_sp + (i) * 4, ®, 4) != 4) { warnx("kvm_read: %s", kvm_geterr(kvm)); break; } supply_register(ARM_A1_REGNUM + 4 + i, (char *)®); } if (kvm_read(kvm, pcb.un_32.pcb32_sp + 4 * 4, ®, 4) != 4) warnx("kvm_read :%s", kvm_geterr(kvm)); else supply_register(ARM_PC_REGNUM, (char *)®); } #endif } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } #ifndef CROSS_DEBUGGER struct kgdb_frame_cache { CORE_ADDR fp; CORE_ADDR sp; }; static int kgdb_trgt_frame_offset[26] = { offsetof(struct trapframe, tf_r0), offsetof(struct trapframe, tf_r1), offsetof(struct trapframe, tf_r2), offsetof(struct trapframe, tf_r3), offsetof(struct trapframe, tf_r4), offsetof(struct trapframe, tf_r5), offsetof(struct trapframe, tf_r6), offsetof(struct trapframe, tf_r7), offsetof(struct trapframe, tf_r8), offsetof(struct trapframe, tf_r9), offsetof(struct trapframe, tf_r10), offsetof(struct trapframe, tf_r11), offsetof(struct trapframe, tf_r12), offsetof(struct trapframe, tf_svc_sp), offsetof(struct trapframe, tf_svc_lr), offsetof(struct trapframe, tf_pc), -1, -1, -1, -1, -1, -1, -1, -1, -1, offsetof(struct trapframe, tf_spsr) }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; frame_unwind_register(next_frame, ARM_SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, ARM_SP_REGNUM)); frame_unwind_register(next_frame, ARM_FP_REGNUM, buf); cache->fp = extract_unsigned_integer(buf, register_size(current_gdbarch, ARM_FP_REGNUM)); } return (cache); } static int is_undef; static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->fp, 0); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; int is_undefined = 0; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; ofs = (regnum >= 0 && regnum <= ARM_PS_REGNUM) ? kgdb_trgt_frame_offset[regnum] : -1; if (ofs == -1) return; cache = kgdb_trgt_frame_cache(next_frame, this_cache); if (is_undef && (regnum == ARM_SP_REGNUM || regnum == ARM_PC_REGNUM)) { *addrp = cache->sp + offsetof(struct trapframe, tf_spsr); target_read_memory(*addrp, valuep, regsz); is_undefined = 1; ofs = kgdb_trgt_frame_offset[ARM_SP_REGNUM]; } *addrp = cache->sp + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); if (is_undefined) { *addrp = *(unsigned int *)valuep + (regnum == ARM_SP_REGNUM ? 0 : 8); target_read_memory(*addrp, valuep, regsz); } } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; #endif const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { #ifndef CROSS_DEBUGGER char *pname; CORE_ADDR pc; pc = frame_pc_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) { is_undef = 0; return (NULL); } if (!strcmp(pname, "undefinedinstruction")) is_undef = 1; if (strcmp(pname, "Laddress_exception_entry") == 0 || strcmp(pname, "undefined_entry") == 0 || strcmp(pname, "exception_exit") == 0 || strcmp(pname, "Laddress_exception_msg") == 0 || strcmp(pname, "irq_entry") == 0) return (&kgdb_trgt_trapframe_unwind); if (!strcmp(pname, "undefinedinstruction")) is_undef = 1; else is_undef = 0; #endif return (NULL); } Index: stable/7/gnu/usr.bin/gdb/kgdb/trgt_i386.c =================================================================== --- stable/7/gnu/usr.bin/gdb/kgdb/trgt_i386.c (revision 178878) +++ stable/7/gnu/usr.bin/gdb/kgdb/trgt_i386.c (revision 178879) @@ -1,354 +1,354 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" static int ofs_fix; void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(I386_EBX_REGNUM, (char *)&pcb.pcb_ebx); supply_register(I386_ESP_REGNUM, (char *)&pcb.pcb_esp); supply_register(I386_EBP_REGNUM, (char *)&pcb.pcb_ebp); supply_register(I386_ESI_REGNUM, (char *)&pcb.pcb_esi); supply_register(I386_EDI_REGNUM, (char *)&pcb.pcb_edi); supply_register(I386_EIP_REGNUM, (char *)&pcb.pcb_eip); } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { /* * In revision 1.117 of i386/i386/exception.S trap handlers * were changed to pass trapframes by reference rather than * by value. Detect this by seeing if the first instruction * at the 'calltrap' label is a "push %esp" which has the * opcode 0x54. */ if (kgdb_parse("((char *)calltrap)[0]") == 0x54) ofs_fix = 4; else ofs_fix = 0; } struct kgdb_tss_cache { CORE_ADDR pc; CORE_ADDR sp; CORE_ADDR tss; }; static int kgdb_trgt_tss_offset[15] = { offsetof(struct i386tss, tss_eax), offsetof(struct i386tss, tss_ecx), offsetof(struct i386tss, tss_edx), offsetof(struct i386tss, tss_ebx), offsetof(struct i386tss, tss_esp), offsetof(struct i386tss, tss_ebp), offsetof(struct i386tss, tss_esi), offsetof(struct i386tss, tss_edi), offsetof(struct i386tss, tss_eip), offsetof(struct i386tss, tss_eflags), offsetof(struct i386tss, tss_cs), offsetof(struct i386tss, tss_ss), offsetof(struct i386tss, tss_ds), offsetof(struct i386tss, tss_es), offsetof(struct i386tss, tss_fs) }; /* * If the current thread is executing on a CPU, fetch the common_tss * for that CPU. * * This is painful because 'struct pcpu' is variant sized, so we can't * use it. Instead, we lookup the GDT selector for this CPU and * extract the base of the TSS from there. */ static CORE_ADDR kgdb_trgt_fetch_tss(void) { struct kthr *kt; struct segment_descriptor sd; uintptr_t addr, cpu0prvpage, tss; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL || kt->cpu == NOCPU) return (0); addr = kgdb_lookup("_gdt"); if (addr == 0) return (0); addr += (kt->cpu * NGDT + GPROC0_SEL) * sizeof(sd); if (kvm_read(kvm, addr, &sd, sizeof(sd)) != sizeof(sd)) { warnx("kvm_read: %s", kvm_geterr(kvm)); return (0); } if (sd.sd_type != SDT_SYS386BSY) { warnx("descriptor is not a busy TSS"); return (0); } tss = sd.sd_hibase << 24 | sd.sd_lobase; /* * In SMP kernels, the TSS is stored as part of the per-CPU * data. On older kernels, the CPU0's private page * is stored at an address that isn't mapped in minidumps. * However, the data is mapped at the alternate cpu0prvpage * address. Thus, if the TSS is at the invalid address, * change it to be relative to cpu0prvpage instead. */ if (trunc_page(tss) == 0xffc00000) { addr = kgdb_lookup("_cpu0prvpage"); if (addr == 0) { warnx("kvm_nlist(_cpu0prvpage): %s", kvm_geterr(kvm)); return (0); } if (kvm_read(kvm, addr, &cpu0prvpage, sizeof(cpu0prvpage)) != sizeof(cpu0prvpage)) { warnx("kvm_read: %s", kvm_geterr(kvm)); return (0); } tss = cpu0prvpage + (tss & PAGE_MASK); } return ((CORE_ADDR)tss); } static struct kgdb_tss_cache * kgdb_trgt_tss_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_tss_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_tss_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); cache->tss = kgdb_trgt_fetch_tss(); } return (cache); } static void kgdb_trgt_dblfault_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_tss_cache *cache; cache = kgdb_trgt_tss_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_dblfault_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_tss_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; ofs = (regnum >= I386_EAX_REGNUM && regnum <= I386_FS_REGNUM) ? kgdb_trgt_tss_offset[regnum] : -1; if (ofs == -1) return; cache = kgdb_trgt_tss_cache(next_frame, this_cache); if (cache->tss == 0) return; *addrp = cache->tss + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_dblfault_unwind = { UNKNOWN_FRAME, &kgdb_trgt_dblfault_this_id, &kgdb_trgt_dblfault_prev_register }; struct kgdb_frame_cache { int intrframe; CORE_ADDR pc; CORE_ADDR sp; }; static int kgdb_trgt_frame_offset[15] = { offsetof(struct trapframe, tf_eax), offsetof(struct trapframe, tf_ecx), offsetof(struct trapframe, tf_edx), offsetof(struct trapframe, tf_ebx), offsetof(struct trapframe, tf_esp), offsetof(struct trapframe, tf_ebp), offsetof(struct trapframe, tf_esi), offsetof(struct trapframe, tf_edi), offsetof(struct trapframe, tf_eip), offsetof(struct trapframe, tf_eflags), offsetof(struct trapframe, tf_cs), offsetof(struct trapframe, tf_ss), offsetof(struct trapframe, tf_ds), offsetof(struct trapframe, tf_es), offsetof(struct trapframe, tf_fs) }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; char *pname; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); find_pc_partial_function(cache->pc, &pname, NULL, NULL); cache->intrframe = (pname[0] == 'X') ? 1 : 0; frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; ofs = (regnum >= I386_EAX_REGNUM && regnum <= I386_FS_REGNUM) ? kgdb_trgt_frame_offset[regnum] + ofs_fix : -1; if (ofs == -1) return; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *addrp = cache->sp + ofs + (cache->intrframe ? 4 : 0); *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_pc_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strcmp(pname, "dblfault_handler") == 0) return (&kgdb_trgt_dblfault_unwind); if (strcmp(pname, "calltrap") == 0 || (pname[0] == 'X' && pname[1] != '_')) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %llx =%s\n", __func__, pc, pname); */ return (NULL); } Index: stable/7/gnu/usr.bin/gdb/kgdb/trgt_ia64.c =================================================================== --- stable/7/gnu/usr.bin/gdb/kgdb/trgt_ia64.c (revision 178878) +++ stable/7/gnu/usr.bin/gdb/kgdb/trgt_ia64.c (revision 178879) @@ -1,319 +1,319 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; uint64_t r; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } /* Registers 0-127: general registers. */ supply_register(IA64_GR1_REGNUM, (char *)&pcb.pcb_special.gp); supply_register(IA64_GR4_REGNUM, (char *)&pcb.pcb_preserved.gr4); supply_register(IA64_GR5_REGNUM, (char *)&pcb.pcb_preserved.gr5); supply_register(IA64_GR6_REGNUM, (char *)&pcb.pcb_preserved.gr6); supply_register(IA64_GR7_REGNUM, (char *)&pcb.pcb_preserved.gr7); supply_register(IA64_GR12_REGNUM, (char *)&pcb.pcb_special.sp); supply_register(IA64_GR12_REGNUM+1, (char *)&pcb.pcb_special.tp); /* Registers 128-255: floating-point registers. */ supply_register(IA64_FR2_REGNUM, (char *)&pcb.pcb_preserved_fp.fr2); supply_register(IA64_FR2_REGNUM+1, (char *)&pcb.pcb_preserved_fp.fr3); supply_register(IA64_FR2_REGNUM+2, (char *)&pcb.pcb_preserved_fp.fr4); supply_register(IA64_FR2_REGNUM+3, (char *)&pcb.pcb_preserved_fp.fr5); supply_register(IA64_FR16_REGNUM, (char *)&pcb.pcb_preserved_fp.fr16); supply_register(IA64_FR16_REGNUM+1, (char*)&pcb.pcb_preserved_fp.fr17); supply_register(IA64_FR16_REGNUM+2, (char*)&pcb.pcb_preserved_fp.fr18); supply_register(IA64_FR16_REGNUM+3, (char*)&pcb.pcb_preserved_fp.fr19); supply_register(IA64_FR16_REGNUM+4, (char*)&pcb.pcb_preserved_fp.fr20); supply_register(IA64_FR16_REGNUM+5, (char*)&pcb.pcb_preserved_fp.fr21); supply_register(IA64_FR16_REGNUM+6, (char*)&pcb.pcb_preserved_fp.fr22); supply_register(IA64_FR16_REGNUM+7, (char*)&pcb.pcb_preserved_fp.fr23); supply_register(IA64_FR16_REGNUM+8, (char*)&pcb.pcb_preserved_fp.fr24); supply_register(IA64_FR16_REGNUM+9, (char*)&pcb.pcb_preserved_fp.fr25); supply_register(IA64_FR16_REGNUM+10,(char*)&pcb.pcb_preserved_fp.fr26); supply_register(IA64_FR16_REGNUM+11,(char*)&pcb.pcb_preserved_fp.fr27); supply_register(IA64_FR16_REGNUM+12,(char*)&pcb.pcb_preserved_fp.fr28); supply_register(IA64_FR16_REGNUM+13,(char*)&pcb.pcb_preserved_fp.fr29); supply_register(IA64_FR16_REGNUM+14,(char*)&pcb.pcb_preserved_fp.fr30); supply_register(IA64_FR16_REGNUM+15,(char*)&pcb.pcb_preserved_fp.fr31); /* Registers 320-327: branch registers. */ if (pcb.pcb_special.__spare == ~0UL) supply_register(IA64_BR0_REGNUM, (char *)&pcb.pcb_special.rp); supply_register(IA64_BR1_REGNUM, (char *)&pcb.pcb_preserved.br1); supply_register(IA64_BR2_REGNUM, (char *)&pcb.pcb_preserved.br2); supply_register(IA64_BR3_REGNUM, (char *)&pcb.pcb_preserved.br3); supply_register(IA64_BR4_REGNUM, (char *)&pcb.pcb_preserved.br4); supply_register(IA64_BR5_REGNUM, (char *)&pcb.pcb_preserved.br5); /* Registers 328-333: misc. other registers. */ supply_register(IA64_PR_REGNUM, (char *)&pcb.pcb_special.pr); if (pcb.pcb_special.__spare == ~0UL) { r = pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3); supply_register(IA64_IP_REGNUM, (char *)&r); supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.cfm); } else { supply_register(IA64_IP_REGNUM, (char *)&pcb.pcb_special.rp); supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.pfs); } /* Registers 334-461: application registers. */ supply_register(IA64_RSC_REGNUM, (char *)&pcb.pcb_special.rsc); r = pcb.pcb_special.bspstore; if (pcb.pcb_special.__spare == ~0UL) r += pcb.pcb_special.ndirty; else r = ia64_bsp_adjust(r, IA64_CFM_SOF(pcb.pcb_special.pfs) - IA64_CFM_SOL(pcb.pcb_special.pfs)); supply_register(IA64_BSP_REGNUM, (char *)&r); supply_register(IA64_BSPSTORE_REGNUM, (char *)&r); supply_register(IA64_RNAT_REGNUM, (char *)&pcb.pcb_special.rnat); supply_register(IA64_UNAT_REGNUM, (char *)&pcb.pcb_special.unat); supply_register(IA64_FPSR_REGNUM, (char *)&pcb.pcb_special.fpsr); if (pcb.pcb_special.__spare == ~0UL) supply_register(IA64_PFS_REGNUM, (char *)&pcb.pcb_special.pfs); supply_register(IA64_LC_REGNUM, (char *)&pcb.pcb_preserved.lc); } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } struct kgdb_frame_cache { CORE_ADDR bsp; CORE_ADDR ip; CORE_ADDR sp; CORE_ADDR saved_bsp; }; #define SPECIAL(x) offsetof(struct trapframe, tf_special) \ + offsetof(struct _special, x) #define SCRATCH(x) offsetof(struct trapframe, tf_scratch) \ + offsetof(struct _caller_saved, x) #define SCRATCH_FP(x) offsetof(struct trapframe, tf_scratch_fp) \ + offsetof(struct _caller_saved_fp, x) static int kgdb_trgt_frame_ofs_gr[32] = { -1, /* gr0 */ SPECIAL(gp), SCRATCH(gr2), SCRATCH(gr3), -1, -1, -1, -1, /* gr4-gr7 */ SCRATCH(gr8), SCRATCH(gr9), SCRATCH(gr10), SCRATCH(gr11), SPECIAL(sp), SPECIAL(tp), SCRATCH(gr14), SCRATCH(gr15), SCRATCH(gr16), SCRATCH(gr17), SCRATCH(gr18), SCRATCH(gr19), SCRATCH(gr20), SCRATCH(gr21), SCRATCH(gr22), SCRATCH(gr23), SCRATCH(gr24), SCRATCH(gr25), SCRATCH(gr26), SCRATCH(gr27), SCRATCH(gr28), SCRATCH(gr29), SCRATCH(gr30), SCRATCH(gr31) }; static int kgdb_trgt_frame_ofs_fr[32] = { -1, /* fr0: constant 0.0 */ -1, /* fr1: constant 1.0 */ -1, -1, -1, -1, /* fr2-fr5 */ SCRATCH_FP(fr6), SCRATCH_FP(fr7), SCRATCH_FP(fr8), SCRATCH_FP(fr9), SCRATCH_FP(fr10), SCRATCH_FP(fr11), SCRATCH_FP(fr12), SCRATCH_FP(fr13), SCRATCH_FP(fr14), SCRATCH_FP(fr15) }; static int kgdb_trgt_frame_ofs_br[8] = { SPECIAL(rp), -1, -1, -1, -1, -1, /* br1-br5 */ SCRATCH(br6), SCRATCH(br7) }; static int kgdb_trgt_frame_ofs_ar[49] = { /* ar0-ar15 */ SPECIAL(rsc), -1, /* ar.bsp */ SPECIAL(bspstore), SPECIAL(rnat), -1, -1, -1, -1, -1, /* ar20-ar24 */ SCRATCH(csd), SCRATCH(ssd), -1, -1, -1, -1, -1, /* ar27-ar31 */ SCRATCH(ccv), -1, -1, -1, /* ar33-ar35 */ SPECIAL(unat), -1, -1, -1, /* ar37-ar39 */ SPECIAL(fpsr), -1, -1, -1, -1, -1, -1, -1, /* ar41-ar47 */ -1, -1, -1, -1, -1, -1, -1, -1, /* ar48-ar55 */ -1, -1, -1, -1, -1, -1, -1, -1, /* ar56-ar63 */ SPECIAL(pfs) }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; frame_unwind_register(next_frame, IA64_BSP_REGNUM, buf); cache->bsp = extract_unsigned_integer(buf, register_size(current_gdbarch, IA64_BSP_REGNUM)); cache->ip = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build_special(cache->sp, cache->ip, cache->bsp); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char buf[MAX_REGISTER_SIZE]; char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; CORE_ADDR bsp; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; cache = kgdb_trgt_frame_cache(next_frame, this_cache); if (regnum == IA64_BSP_REGNUM) { if (cache->saved_bsp == 0) { target_read_memory(cache->sp + 16 + SPECIAL(bspstore), buf, regsz); bsp = extract_unsigned_integer(buf, regsz); target_read_memory(cache->sp + 16 + SPECIAL(ndirty), buf, regsz); bsp += extract_unsigned_integer(buf, regsz); cache->saved_bsp = bsp; } store_unsigned_integer(valuep, regsz, cache->saved_bsp); return; } if (regnum == IA64_PR_REGNUM) ofs = SPECIAL(pr); else if (regnum == IA64_IP_REGNUM) ofs = SPECIAL(iip); else if (regnum == IA64_PSR_REGNUM) ofs = SPECIAL(psr); else if (regnum == IA64_CFM_REGNUM) ofs = SPECIAL(cfm); else if (regnum >= IA64_GR0_REGNUM && regnum <= IA64_GR31_REGNUM) ofs = kgdb_trgt_frame_ofs_gr[regnum - IA64_GR0_REGNUM]; else if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR15_REGNUM) ofs = kgdb_trgt_frame_ofs_fr[regnum - IA64_FR0_REGNUM]; else if (regnum >= IA64_BR0_REGNUM && regnum <= IA64_BR7_REGNUM) ofs = kgdb_trgt_frame_ofs_br[regnum - IA64_BR0_REGNUM]; else if (regnum >= IA64_RSC_REGNUM && regnum <= IA64_PFS_REGNUM) ofs = kgdb_trgt_frame_ofs_ar[regnum - IA64_RSC_REGNUM]; else ofs = -1; if (ofs == -1) return; *addrp = cache->sp + 16 + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR ip; ip = frame_func_unwind(next_frame); pname = NULL; find_pc_partial_function(ip, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strncmp(pname, "ivt_", 4) == 0) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %lx =%s\n", __func__, ip, pname); */ return (NULL); } Index: stable/7/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c =================================================================== --- stable/7/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c (revision 178878) +++ stable/7/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c (revision 178879) @@ -1,190 +1,190 @@ /*- * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; struct gdbarch_tdep *tdep; int i; tdep = gdbarch_tdep (current_gdbarch); - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } /* * r14-r31 are saved in the pcb */ for (i = 14; i <= 31; i++) { supply_register(tdep->ppc_gp0_regnum + i, (char *)&pcb.pcb_context[i]); } /* r1 is saved in the sp field */ supply_register(tdep->ppc_gp0_regnum + 1, (char *)&pcb.pcb_sp); supply_register(tdep->ppc_lr_regnum, (char *)&pcb.pcb_lr); supply_register(tdep->ppc_cr_regnum, (char *)&pcb.pcb_cr); } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } struct kgdb_frame_cache { CORE_ADDR pc; CORE_ADDR sp; }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SP_REGNUM)); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct gdbarch_tdep *tdep; struct kgdb_frame_cache *cache; int ofs, regsz; tdep = gdbarch_tdep(current_gdbarch); regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; if (regnum >= tdep->ppc_gp0_regnum && regnum <= tdep->ppc_gplast_regnum) ofs = offsetof(struct trapframe, fixreg[regnum - tdep->ppc_gp0_regnum]); else if (regnum == tdep->ppc_lr_regnum) ofs = offsetof(struct trapframe, lr); else if (regnum == tdep->ppc_cr_regnum) ofs = offsetof(struct trapframe, cr); else if (regnum == tdep->ppc_xer_regnum) ofs = offsetof(struct trapframe, xer); else if (regnum == tdep->ppc_ctr_regnum) ofs = offsetof(struct trapframe, ctr); else if (regnum == PC_REGNUM) ofs = offsetof(struct trapframe, srr0); else return; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *addrp = cache->sp + 8 + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_pc_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strcmp(pname, "asttrapexit") == 0 || strcmp(pname, "trapexit") == 0) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %llx =%s\n", __func__, pc, pname); */ return (NULL); } Index: stable/7/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c =================================================================== --- stable/7/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c (revision 178878) +++ stable/7/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c (revision 178879) @@ -1,199 +1,199 @@ /* * Copyright (c) 2004 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; - kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); + kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(SPARC_SP_REGNUM, (char *)&pcb.pcb_sp); sparc_supply_rwindow(current_regcache, pcb.pcb_sp, -1); supply_register(SPARC64_PC_REGNUM, (char *)&pcb.pcb_pc); pcb.pcb_pc += 4; supply_register(SPARC64_NPC_REGNUM, (char *)&pcb.pcb_pc); } void kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } void kgdb_trgt_new_objfile(struct objfile *objfile) { } struct kgdb_frame_cache { CORE_ADDR pc; CORE_ADDR sp; CORE_ADDR fp; }; static struct kgdb_frame_cache * kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) { char buf[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; cache = *this_cache; if (cache == NULL) { cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); *this_cache = cache; cache->pc = frame_func_unwind(next_frame); frame_unwind_register(next_frame, SPARC_SP_REGNUM, buf); cache->sp = extract_unsigned_integer(buf, register_size(current_gdbarch, SPARC_SP_REGNUM)); frame_unwind_register(next_frame, SPARC_FP_REGNUM, buf); cache->fp = extract_unsigned_integer(buf, register_size(current_gdbarch, SPARC_FP_REGNUM)); cache->fp += BIAS - sizeof(struct trapframe); } return (cache); } static void kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, struct frame_id *this_id) { struct kgdb_frame_cache *cache; cache = kgdb_trgt_frame_cache(next_frame, this_cache); *this_id = frame_id_build(cache->sp, cache->pc); } static void kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *valuep) { char dummy_valuep[MAX_REGISTER_SIZE]; struct kgdb_frame_cache *cache; int ofs, regsz; regsz = register_size(current_gdbarch, regnum); if (valuep == NULL) valuep = dummy_valuep; memset(valuep, 0, regsz); *optimizedp = 0; *addrp = 0; *lvalp = not_lval; *realnump = -1; cache = kgdb_trgt_frame_cache(next_frame, this_cache); switch (regnum) { case SPARC_SP_REGNUM: ofs = offsetof(struct trapframe, tf_sp); break; case SPARC64_PC_REGNUM: ofs = offsetof(struct trapframe, tf_tpc); break; case SPARC64_NPC_REGNUM: ofs = offsetof(struct trapframe, tf_tnpc); break; case SPARC_O0_REGNUM: case SPARC_O1_REGNUM: case SPARC_O2_REGNUM: case SPARC_O3_REGNUM: case SPARC_O4_REGNUM: case SPARC_O5_REGNUM: case SPARC_O7_REGNUM: ofs = offsetof(struct trapframe, tf_out) + (regnum - SPARC_O0_REGNUM) * 8; break; default: if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) { ofs = (regnum - SPARC_L0_REGNUM) * 8; *addrp = cache->sp + BIAS + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } return; } *addrp = cache->fp + ofs; *lvalp = lval_memory; target_read_memory(*addrp, valuep, regsz); } static const struct frame_unwind kgdb_trgt_trapframe_unwind = { UNKNOWN_FRAME, &kgdb_trgt_trapframe_this_id, &kgdb_trgt_trapframe_prev_register }; const struct frame_unwind * kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) { char *pname; CORE_ADDR pc; pc = frame_func_unwind(next_frame); pname = NULL; find_pc_partial_function(pc, &pname, NULL, NULL); if (pname == NULL) return (NULL); if (strcmp(pname, "tl0_intr") == 0 || strcmp(pname, "tl0_trap") == 0 || strcmp(pname, "tl1_intr") == 0 || strcmp(pname, "tl1_trap") == 0) return (&kgdb_trgt_trapframe_unwind); /* printf("%s: %lx =%s\n", __func__, pc, pname); */ return (NULL); }