From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9218 invoked by alias); 7 Feb 2011 14:29:32 -0000 Received: (qmail 9210 invoked by uid 22791); 7 Feb 2011 14:29:30 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,TW_BJ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 07 Feb 2011 14:29:24 +0000 Received: (qmail 24546 invoked from network); 7 Feb 2011 14:29:22 -0000 Received: from unknown (HELO scottsdale.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 7 Feb 2011 14:29:22 -0000 To: gdb-patches@sourceware.org Subject: [unavailable values part 1, 03/17] expose list of available ranges to common code From: Pedro Alves Date: Mon, 07 Feb 2011 14:29:00 -0000 MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201102071429.19096.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-02/txt/msg00134.txt.bz2 Making use of the new traceframe info object, this patch add a new function that exports a list of available memory ranges that has been collected in the traceframe to common code. No uses are added in this patch yet though. [I could have merged this with other patches, but it was useful while developing to keep it separate...] This splits the mem_range type into its own file, as otherwise, a following patch would either need to make exec.h include tracepoint.h (weird), or I'd have to move the struct mem_range declaration somewhere more central, like target.h (weird) or defs.h (desirably avoidable). For the record, I tried making all this range handling be done with addrmaps, but, I found out it was much more trouble than it's worth. -- Pedro Alves 2011-02-07 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/Makefile.in | 6 ++-- gdb/memrange.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/memrange.h | 51 ++++++++++++++++++++++++++++++++++ gdb/tracepoint.c | 59 +++++++++++++++++++++++++++++---------- gdb/tracepoint.h | 4 ++ 5 files changed, 184 insertions(+), 18 deletions(-) Index: src/gdb/Makefile.in =================================================================== --- src.orig/gdb/Makefile.in 2011-02-07 13:16:08.446706002 +0000 +++ src/gdb/Makefile.in 2011-02-07 13:16:55.856705999 +0000 @@ -711,7 +711,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr 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 \ @@ -770,7 +770,7 @@ gdbserver/mem-break.h gdbserver/wincecom 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 \ @@ -889,7 +889,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $ 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 Index: src/gdb/memrange.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/memrange.c 2011-02-07 13:17:12.586706003 +0000 @@ -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); + } +} Index: src/gdb/memrange.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/memrange.h 2011-02-07 13:17:20.796706003 +0000 @@ -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 Index: src/gdb/tracepoint.c =================================================================== --- src.orig/gdb/tracepoint.c 2011-02-07 13:16:08.446706002 +0000 +++ src/gdb/tracepoint.c 2011-02-07 13:16:55.866706000 +0000 @@ -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) Index: src/gdb/tracepoint.h =================================================================== --- src.orig/gdb/tracepoint.h 2011-02-07 13:16:08.436706001 +0000 +++ src/gdb/tracepoint.h 2011-02-07 13:16:55.866706000 +0000 @@ -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 *file 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 */