From e74e288317ad82860cd5d9bce423fa30945e3f4a Mon Sep 17 00:00:00 2001 From: palves Date: Mon, 14 Feb 2011 11:20:27 +0000 Subject: [PATCH] 2011-02-14 Pedro Alves gdb/ * Makefile.in (SFILES): Add memrange.c. (HFILES_NO_SRCDIR): Add memrange.h. (COMMON_OBS): Add memrange.o. * memrange.c: New file. * memrange.h: New file. * tracepoint.c: Include memrange.h. (struct mem_range): Delete. (mem_range_s): Delete. (traceframe_available_memory): New function. * tracepoint.h (traceframe_available_memory): Declare. --- gdb/ChangeLog | 13 +++++++++ gdb/Makefile.in | 6 ++--- gdb/memrange.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/memrange.h | 51 +++++++++++++++++++++++++++++++++++ gdb/tracepoint.c | 59 +++++++++++++++++++++++++++++----------- gdb/tracepoint.h | 4 +++ 6 files changed, 197 insertions(+), 18 deletions(-) create mode 100644 gdb/memrange.c create mode 100644 gdb/memrange.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d74fc1ef1f..df7e871bd9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,18 @@ 2011-02-14 Pedro Alves + * Makefile.in (SFILES): Add memrange.c. + (HFILES_NO_SRCDIR): Add memrange.h. + (COMMON_OBS): Add memrange.o. + * memrange.c: New file. + * memrange.h: New file. + * tracepoint.c: Include memrange.h. + (struct mem_range): Delete. + (mem_range_s): Delete. + (traceframe_available_memory): New function. + * tracepoint.h (traceframe_available_memory): Declare. + +2011-02-14 Pedro Alves + * target.h (struct traceframe_info): Forward declare. (enum target_object): Add TARGET_OBJECT_TRACEFRAME_INFO. (struct target_ops) : New field. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index f991cb030a..e43108e991 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -717,7 +717,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c \ macrotab.c macroexp.c macrocmd.c macroscope.c main.c maint.c \ mdebugread.c memattr.c mem-break.c minsyms.c mipsread.c memory-map.c \ - mi/mi-common.c \ + memrange.c mi/mi-common.c \ objc-exp.y objc-lang.c \ objfiles.c osabi.c observer.c osdata.c \ opencl-lang.c \ @@ -776,7 +776,7 @@ gdbserver/mem-break.h gdbserver/wincecompat.h gdbserver/target.h \ gdbserver/linux-low.h gdbserver/gdb_proc_service.h \ gdbserver/regcache.h gdbthread.h dwarf2-frame.h nbsd-nat.h dcache.h \ amd64-nat.h s390-tdep.h arm-linux-tdep.h exceptions.h macroscope.h \ -gdbarch.h bsd-uthread.h gdb_thread_db.h gdb_stat.h memory-map.h \ +gdbarch.h bsd-uthread.h gdb_thread_db.h gdb_stat.h memory-map.h memrange.h \ mdebugread.h m88k-tdep.h stabsread.h hppa-linux-offsets.h linux-fork.h \ ser-unix.h inf-ptrace.h terminal.h ui-out.h frame-base.h \ f-lang.h dwarf2loc.h value.h sparc-tdep.h defs.h target-descriptions.h \ @@ -894,7 +894,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ trad-frame.o \ tramp-frame.o \ solib.o solib-target.o \ - prologue-value.o memory-map.o xml-support.o xml-syscall.o \ + prologue-value.o memory-map.o memrange.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 diff --git a/gdb/memrange.c b/gdb/memrange.c new file mode 100644 index 0000000000..4ffe6bdd6d --- /dev/null +++ b/gdb/memrange.c @@ -0,0 +1,82 @@ +/* Memory ranges + + Copyright (C) 2010, 2011 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 . */ + +#include "defs.h" +#include "memrange.h" + +int +mem_ranges_overlap (CORE_ADDR start1, int len1, + CORE_ADDR start2, int len2) +{ + ULONGEST h, l; + + l = max (start1, start2); + h = min (start1 + len1, start2 + len2); + return (l < h); +} + +/* qsort comparison function, that compares mem_ranges. */ + +static int +compare_mem_ranges (const void *ap, const void *bp) +{ + const struct mem_range *r1 = ap; + const struct mem_range *r2 = bp; + + if (r1->start > r2->start) + return 1; + else if (r1->start < r2->start) + return -1; + else + return 0; +} + +void +normalize_mem_ranges (VEC(mem_range_s) *ranges) +{ + if (!VEC_empty (mem_range_s, ranges)) + { + struct mem_range *ra, *rb; + int a, b; + + qsort (VEC_address (mem_range_s, ranges), + VEC_length (mem_range_s, ranges), + sizeof (mem_range_s), + compare_mem_ranges); + + a = 0; + ra = VEC_index (mem_range_s, ranges, a); + for (b = 1; VEC_iterate (mem_range_s, ranges, b, rb); b++) + { + /* If mem_range B overlaps or is adjacent to mem_range A, + merge them. */ + if (rb->start <= ra->start + ra->length) + { + ra->length = (rb->start + rb->length) - ra->start; + continue; /* next b, same a */ + } + a++; /* next a */ + ra = VEC_index (mem_range_s, ranges, a); + + if (a != b) + *ra = *rb; + } + VEC_truncate (mem_range_s, ranges, a + 1); + } +} diff --git a/gdb/memrange.h b/gdb/memrange.h new file mode 100644 index 0000000000..9071b88de5 --- /dev/null +++ b/gdb/memrange.h @@ -0,0 +1,51 @@ +/* The memory range data structure, and associated utilities. + + Copyright (C) 2010, 2011 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 . */ + +#ifndef MEMRANGE_H +#define MEMRANGE_H + +#include "vec.h" + +/* Defines a [START, START + LENGTH) memory range. */ + +struct mem_range +{ + /* Lowest address in the range. */ + CORE_ADDR start; + + /* Length of the range. */ + int length; +}; + +typedef struct mem_range mem_range_s; + +DEF_VEC_O(mem_range_s); + +/* Returns true if the ranges defined by [start1, start1+len1) and + [start2, start2+len2) overlap. */ + +extern int mem_ranges_overlap (CORE_ADDR start1, int len1, + CORE_ADDR start2, int len2); + +/* Sort ranges by start address, then coalesce contiguous or + overlapping ranges. */ + +extern void normalize_mem_ranges (VEC(mem_range_s) *memory); + +#endif diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 8117531431..18f3c7f1d8 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -50,6 +50,7 @@ #include "source.h" #include "ax.h" #include "ax-gdb.h" +#include "memrange.h" /* readline include files */ #include "readline/readline.h" @@ -130,21 +131,6 @@ extern void output_command (char *, int); typedef struct trace_state_variable tsv_s; DEF_VEC_O(tsv_s); -/* Defines a [START, START + LENGTH) memory range. */ - -struct mem_range -{ - /* Lowest address in the range. */ - CORE_ADDR start; - - /* Length of the range. */ - int length; -}; - -typedef struct mem_range mem_range_s; - -DEF_VEC_O(mem_range_s); - /* An object describing the contents of a traceframe. */ struct traceframe_info @@ -4597,6 +4583,49 @@ get_traceframe_info (void) return traceframe_info; } +/* Return in RESULT, the set of collected memory in the current + traceframe, found within the LEN bytes range starting at MEMADDR. + Returns true if the target supports the query, otherwise returns + false. */ + +int +traceframe_available_memory (VEC(mem_range_s) **result, + CORE_ADDR memaddr, ULONGEST len) +{ + struct traceframe_info *info = get_traceframe_info (); + + if (info != NULL) + { + struct mem_range *r; + int i; + + *result = NULL; + + for (i = 0; VEC_iterate (mem_range_s, info->memory, i, r); i++) + if (mem_ranges_overlap (r->start, r->length, memaddr, len)) + { + ULONGEST lo1, hi1, lo2, hi2; + struct mem_range *nr; + + lo1 = memaddr; + hi1 = memaddr + len; + + lo2 = r->start; + hi2 = r->start + r->length; + + nr = VEC_safe_push (mem_range_s, *result, NULL); + + nr->start = max (lo1, lo2); + nr->length = min (hi1, hi2) - nr->start; + } + + normalize_mem_ranges (*result); + return 1; + } + + return 0; +} + /* module initialization */ void _initialize_tracepoint (void) diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h index 276501e517..ee15e948cb 100644 --- a/gdb/tracepoint.h +++ b/gdb/tracepoint.h @@ -22,6 +22,7 @@ #include "breakpoint.h" #include "target.h" +#include "memrange.h" /* A trace state variable is a value managed by a target being traced. A trace state variable (or tsv for short) can be accessed @@ -238,4 +239,7 @@ extern void trace_save (const char *filename, int target_does_save); extern struct traceframe_info *parse_traceframe_info (const char *tframe_info); +extern int traceframe_available_memory (VEC(mem_range_s) **result, + CORE_ADDR memaddr, ULONGEST len); + #endif /* TRACEPOINT_H */ -- 2.11.0