Re: [PATCH 2/2] markup_oops.pl and GDB: GDB: make it can show gdb command
From: Hui Zhu
Date: Mon Mar 01 2010 - 21:16:56 EST
Ping.
2010/2/22 Hui Zhu <teawater@xxxxxxxxx>:
> This patch add a new target empty which level is same with corelow
> target. It can save the memory and reg operation command's value and
> send it to GDB as the inferior's value.
> "target empty" to use this target.
>
> 2010-02-22 Hui Zhu <teawater@xxxxxxxxx>
>
> * Makefile.in (SFILES): Add empty.c.
> (COMMON_OBS): Add empty.o
> * empty.c: New file.
> ---
> Makefile.in | 3
> empty.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 298 insertions(+), 1 deletion(-)
>
> --- a/Makefile.in
> +++ b/Makefile.in
> @@ -688,6 +688,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
> record.c gcore.c \
> jit.c \
> xml-syscall.c \
> + empty.c
>
> LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
>
> @@ -839,7 +840,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
> prologue-value.o memory-map.o xml-support.o xml-syscall.o \
> target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
> inferior.o osdata.o gdb_usleep.o record.o gcore.o \
> - jit.o progspace.o
> + jit.o progspace.o empty.o
>
> # Definitions for the syscall's XML files and dir
> XML_SYSCALLS_DIR = syscalls/
> --- /dev/null
> +++ b/empty.c
> @@ -0,0 +1,296 @@
> +/* Empty target for GDB, the GNU debugger.
> +
> + Copyright (C) 2010 Free Software Foundation, Inc.
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +#include "defs.h"
> +#include "gdbcmd.h"
> +#include "regcache.h"
> +#include "gdbthread.h"
> +#include "event-top.h"
> +#include "exceptions.h"
> +#include "completer.h"
> +#include "arch-utils.h"
> +#include "gdbcore.h"
> +#include "exec.h"
> +#include "record.h"
> +#include "elf-bfd.h"
> +#include "gcore.h"
> +
> +#define EMPTY_PID 1
> +
> +static struct target_ops empty_ops;
> +
> +static gdb_byte *empty_regbuf = NULL;
> +
> +struct empty_mem_list_s
> +{
> + struct empty_mem_list_s *prev;
> + struct empty_mem_list_s *next;
> + ULONGEST begin;
> + ULONGEST end;
> + gdb_byte *buf;
> +};
> +
> +static struct empty_mem_list_s *empty_mem_list = NULL;
> +
> +static void
> +empty_open (char *arg, int from_tty)
> +{
> + int regnum = gdbarch_num_regs (get_current_arch ());
> +
> + empty_regbuf = xzalloc (MAX_REGISTER_SIZE * regnum);
> +
> + push_target (&empty_ops);
> +
> + inferior_ptid = pid_to_ptid (EMPTY_PID);
> + inferior_appeared (current_inferior (), EMPTY_PID);
> + add_thread_silent (inferior_ptid);
> +}
> +
> +static void
> +empty_close (int quitting)
> +{
> + struct empty_mem_list_s *mlp;
> +
> + for (mlp = empty_mem_list; mlp;)
> + {
> + struct empty_mem_list_s *tmp = mlp;
> +
> + mlp = mlp->next;
> + xfree (tmp->buf);
> + xfree (tmp);
> + }
> +
> + if (empty_regbuf)
> + {
> + xfree (empty_regbuf);
> + empty_regbuf = NULL;
> + }
> +}
> +
> +static void
> +empty_kill (struct target_ops *ops)
> +{
> + unpush_target (ops);
> +}
> +
> +static void
> +empty_fetch_registers (struct target_ops *ops,
> + struct regcache *regcache, int regno)
> +{
> + if (regno < 0)
> + {
> + int num = gdbarch_num_regs (get_regcache_arch (regcache));
> + int i;
> +
> + for (i = 0; i < num; i ++)
> + regcache_raw_supply (regcache, i,
> + empty_regbuf + MAX_REGISTER_SIZE * i);
> + }
> + else
> + regcache_raw_supply (regcache, regno,
> + empty_regbuf + MAX_REGISTER_SIZE * regno);
> +}
> +
> +static void
> +empty_prepare_to_store (struct regcache *regcache)
> +{
> +}
> +
> +static void
> +empty_store_registers (struct target_ops *ops,
> + struct regcache *regcache, int regno)
> +{
> + regcache_raw_collect (regcache, regno,
> + empty_regbuf + MAX_REGISTER_SIZE * regno);
> +}
> +
> +static LONGEST
> +empty_xfer_partial (struct target_ops *ops, enum target_object object,
> + const char *annex, gdb_byte *readbuf,
> + const gdb_byte *writebuf, ULONGEST offset,
> + LONGEST len)
> +{
> + struct empty_mem_list_s *mlp;
> +
> + if (ops->beneath != NULL)
> + {
> + if (ops->beneath->to_xfer_partial (ops->beneath, object, annex,
> + readbuf, writebuf, offset, len) == len)
> + return len;
> + }
> +
> + if (readbuf)
> + {
> + memset (readbuf, 0, len);
> +
> + for (mlp = empty_mem_list; mlp; mlp = mlp->next)
> + {
> + ULONGEST wbegin = 0;
> + ULONGEST wend = 0;
> +
> + if (mlp->begin >= offset && mlp->begin <= offset + len)
> + {
> + wbegin = offset;
> +
> + if (mlp->end > offset + len)
> + wend = offset + len;
> + else
> + wend = mlp->end;
> + }
> + else if (mlp->end >= offset && mlp->end <= offset + len)
> + {
> + wend = offset + len;
> +
> + if (mlp->begin > offset)
> + wbegin = mlp->begin;
> + else
> + wbegin = offset;
> + }
> + else if (mlp->begin < offset && mlp->end > offset +len)
> + {
> + wbegin = offset;
> + wend = offset + len;
> + }
> +
> + if (wbegin != wend)
> + memcpy (readbuf + wbegin - offset,
> + mlp->buf + wbegin - mlp->begin, wend - wbegin);
> + }
> + }
> + else
> + {
> + struct empty_mem_list_s *mlp_new = NULL;
> + struct empty_mem_list_s *mlp_head = NULL, *mlp_tail = NULL;
> + struct empty_mem_list_s *mlp_bodycore = NULL;
> + struct empty_mem_list_s *mlp_bodyhead = NULL, *mlp_bodytail = NULL;
> + ULONGEST begin = offset, end = offset +len;
> + gdb_byte *buf;
> +
> + /* Get mlp_head, mlp_tail, mlp_bodyhead, mlp_bodytail, begin, end. */
> + for (mlp = empty_mem_list; mlp; mlp = mlp->next)
> + {
> + if (mlp->end < begin)
> + mlp_head = mlp;
> + else if (begin >= mlp->begin && end <= mlp->end)
> + {
> + mlp_bodycore = mlp;
> + break;
> + }
> + else if ((mlp->begin >= begin && mlp->begin <= end)
> + || (mlp->end >= begin && mlp->end <= end)
> + || (mlp->begin < begin && mlp->end > end))
> + {
> + if (mlp_bodyhead)
> + mlp_bodytail = mlp;
> + else
> + {
> + mlp_bodyhead = mlp;
> + mlp_bodytail = mlp;
> + }
> + if (mlp->begin < begin)
> + begin = mlp->begin;
> + if (mlp->begin > end)
> + end = mlp->end;
> + }
> + else if (end < mlp->begin)
> + {
> + mlp_tail = mlp;
> + break;
> + }
> + }
> +
> + if (mlp_bodycore)
> + {
> + memcpy (mlp_bodycore->buf + begin - mlp_bodycore->begin, writebuf, len);
> + }
> + else
> + {
> + mlp_new = xmalloc (sizeof (struct empty_mem_list_s));
> + mlp_new->begin = begin;
> + mlp_new->end = end;
> + mlp_new->buf = xzalloc (end - begin);
> +
> + /* Write the mlp_body value to mlp_new and release mlp_body. */
> + for (mlp = mlp_bodyhead; mlp && mlp->prev != mlp_bodytail;)
> + {
> + struct empty_mem_list_s *tmp = mlp;
> +
> + mlp = mlp->next;
> + memcpy (mlp_new->buf + tmp->begin - begin, tmp->buf, tmp->end - tmp->begin);
> + xfree (tmp->buf);
> + xfree (tmp);
> + }
> +
> + /* Write the new value to mlp_new. */
> + memcpy (mlp_new->buf + offset - begin, writebuf, len);
> +
> + /* Add mlp_new to list. */
> + mlp_new->prev = mlp_head;
> + mlp_new->next = mlp_tail;
> + if (mlp_head)
> + mlp_head->next = mlp_new;
> + if (mlp_tail)
> + mlp_tail->prev = mlp_new;
> + if (!mlp_new->prev)
> + empty_mem_list = mlp_new;
> + }
> +
> + reinit_frame_cache ();
> + }
> +
> + return len;
> +}
> +
> +static int
> +ignore (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt)
> +{
> + return 0;
> +}
> +
> +static void
> +init_empty_ops (void)
> +{
> + empty_ops.to_shortname = "empty";
> + empty_ops.to_longname = "Empty target";
> + empty_ops.to_doc = "Empty target";
> + empty_ops.to_open = empty_open;
> + empty_ops.to_close = empty_close;
> + empty_ops.to_attach = find_default_attach;
> + empty_ops.to_kill = empty_kill;
> + empty_ops.to_fetch_registers = empty_fetch_registers;
> + empty_ops.to_prepare_to_store = empty_prepare_to_store;
> + empty_ops.to_store_registers = empty_store_registers;
> + empty_ops.to_xfer_partial = empty_xfer_partial;
> + empty_ops.to_insert_breakpoint = ignore;
> + empty_ops.to_remove_breakpoint = ignore;
> + empty_ops.to_create_inferior = find_default_create_inferior;
> + empty_ops.to_stratum = core_stratum;
> + empty_ops.to_has_execution = default_child_has_execution;
> + empty_ops.to_has_memory = default_child_has_memory;
> + empty_ops.to_has_stack = default_child_has_stack;
> + empty_ops.to_has_registers = default_child_has_registers;
> + empty_ops.to_magic = OPS_MAGIC;
> +}
> +
> +void
> +_initialize_empty (void)
> +{
> + init_empty_ops ();
> + add_target (&empty_ops);
> +}
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/