From: Daniel Jacobowitz Date: Thu, 21 Sep 2006 13:48:29 +0000 (+0000) Subject: * Makefile.in (memattr_h, memattr.o): Update. X-Git-Tag: gdb_6_6-2006-11-15-branchpoint~430 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c96fc75e9e90e0781789095b842495bbcdbb037a;p=external%2Fbinutils.git * Makefile.in (memattr_h, memattr.o): Update. * memattr.h: Include "vec.h". (struct mem_region): Remove linked list pointer. (mem_region_s): New typedef and corresponding vector. * memattr.c: Include "vec.h". (mem_region_chain): Delete. (mem_region_list): New vector pointer. (mem_region_lessthan): New function. (create_mem_region): Remove unused return value. Use vector operations. Remove linear search. (delete_mem_region): Delete. (lookup_mem_region): Use vector operations. Add a FIXME. (mem_info_command): Update to work with vectors. (mem_enable, mem_enable_command, mem_disable, mem_disable_command) (mem_free, mem_delete): Likewise. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7b0e5d6..1ff1fa6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,21 @@ +2006-09-21 Daniel Jacobowitz + + * Makefile.in (memattr_h, memattr.o): Update. + * memattr.h: Include "vec.h". + (struct mem_region): Remove linked list pointer. + (mem_region_s): New typedef and corresponding vector. + * memattr.c: Include "vec.h". + (mem_region_chain): Delete. + (mem_region_list): New vector pointer. + (mem_region_lessthan): New function. + (create_mem_region): Remove unused return value. Use vector + operations. Remove linear search. + (delete_mem_region): Delete. + (lookup_mem_region): Use vector operations. Add a FIXME. + (mem_info_command): Update to work with vectors. + (mem_enable, mem_enable_command, mem_disable, mem_disable_command) + (mem_free, mem_delete): Likewise. + 2006-09-21 Nathan Sidwell * vec.h: New file. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 1690f52..a6d1f70 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -747,7 +747,7 @@ macroscope_h = macroscope.h $(macrotab_h) $(symtab_h) macrotab_h = macrotab.h main_h = main.h mdebugread_h = mdebugread.h $(coff_sym_h) $(coff_symconst_h) -memattr_h = memattr.h +memattr_h = memattr.h $(vec_h) mips_linux_tdep_h = mips-linux-tdep.h mips_mdebug_tdep_h = mips-mdebug-tdep.h mipsnbsd_tdep_h = mipsnbsd-tdep.h @@ -2327,7 +2327,7 @@ mdebugread.o: mdebugread.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \ $(bfd_h) $(coff_ecoff_h) $(libaout_h) $(aout_aout64_h) \ $(aout_stab_gnu_h) $(expression_h) memattr.o: memattr.c $(defs_h) $(command_h) $(gdbcmd_h) $(memattr_h) \ - $(target_h) $(value_h) $(language_h) $(gdb_string_h) + $(target_h) $(value_h) $(language_h) $(vec_h) $(gdb_string_h) mem-break.o: mem-break.c $(defs_h) $(symtab_h) $(breakpoint_h) $(inferior_h) \ $(target_h) mingw-hdep.o: mingw-hdep.c $(defs_h) $(serial_h) $(gdb_assert_h) \ diff --git a/gdb/memattr.c b/gdb/memattr.c index 3a5f7d0..3ed9f60 100644 --- a/gdb/memattr.c +++ b/gdb/memattr.c @@ -1,6 +1,7 @@ /* Memory attributes support, for GDB. - Copyright (C) 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. This file is part of GDB. @@ -26,6 +27,7 @@ #include "target.h" #include "value.h" #include "language.h" +#include "vec.h" #include "gdb_string.h" const struct mem_attrib default_mem_attrib = @@ -37,54 +39,66 @@ const struct mem_attrib default_mem_attrib = 0 /* verify */ }; -static struct mem_region *mem_region_chain = NULL; +VEC(mem_region_s) *mem_region_list; static int mem_number = 0; -static struct mem_region * +/* Predicate function which returns true if LHS should sort before RHS + in a list of memory regions, useful for VEC_lower_bound. */ + +static int +mem_region_lessthan (const struct mem_region *lhs, + const struct mem_region *rhs) +{ + return lhs->lo < rhs->lo; +} + +static void create_mem_region (CORE_ADDR lo, CORE_ADDR hi, const struct mem_attrib *attrib) { - struct mem_region *n, *new; + struct mem_region new; + int i, ix; /* lo == hi is a useless empty region */ if (lo >= hi && hi != 0) { printf_unfiltered (_("invalid memory region: low >= high\n")); - return NULL; + return; } - n = mem_region_chain; - while (n) + new.lo = lo; + new.hi = hi; + + ix = VEC_lower_bound (mem_region_s, mem_region_list, &new, + mem_region_lessthan); + + /* Check for an overlapping memory region. We only need to check + in the vicinity - at most one before and one after the + insertion point. */ + for (i = ix - 1; i < ix + 1; i++) { - /* overlapping node */ + struct mem_region *n; + + if (i < 0) + continue; + if (i >= VEC_length (mem_region_s, mem_region_list)) + continue; + + n = VEC_index (mem_region_s, mem_region_list, i); + if ((lo >= n->lo && (lo < n->hi || n->hi == 0)) || (hi > n->lo && (hi <= n->hi || n->hi == 0)) || (lo <= n->lo && (hi >= n->hi || hi == 0))) { printf_unfiltered (_("overlapping memory region\n")); - return NULL; + return; } - n = n->next; } - new = xmalloc (sizeof (struct mem_region)); - new->lo = lo; - new->hi = hi; - new->number = ++mem_number; - new->enabled_p = 1; - new->attrib = *attrib; - - /* link in new node */ - new->next = mem_region_chain; - mem_region_chain = new; - - return new; -} - -static void -delete_mem_region (struct mem_region *m) -{ - xfree (m); + new.number = ++mem_number; + new.enabled_p = 1; + new.attrib = *attrib; + VEC_safe_insert (mem_region_s, mem_region_list, ix, &new); } /* @@ -97,6 +111,7 @@ lookup_mem_region (CORE_ADDR addr) struct mem_region *m; CORE_ADDR lo; CORE_ADDR hi; + int ix; /* First we initialize LO and HI so that they describe the entire memory space. As we process the memory region chain, they are @@ -108,7 +123,10 @@ lookup_mem_region (CORE_ADDR addr) lo = (CORE_ADDR) 0; hi = (CORE_ADDR) ~ 0; - for (m = mem_region_chain; m; m = m->next) + /* If we ever want to support a huge list of memory regions, this + check should be replaced with a binary search (probably using + VEC_lower_bound). */ + for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) { if (m->enabled_p == 1) { @@ -215,8 +233,9 @@ mem_info_command (char *args, int from_tty) { struct mem_region *m; struct mem_attrib *attrib; + int ix; - if (!mem_region_chain) + if (!mem_region_list) { printf_unfiltered (_("There are no memory regions defined.\n")); return; @@ -233,7 +252,7 @@ mem_info_command (char *args, int from_tty) printf_filtered ("Attrs "); printf_filtered ("\n"); - for (m = mem_region_chain; m; m = m->next) + for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) { char *tmp; printf_filtered ("%-3d %-3c\t", @@ -339,8 +358,9 @@ static void mem_enable (int num) { struct mem_region *m; + int ix; - for (m = mem_region_chain; m; m = m->next) + for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) if (m->number == num) { m->enabled_p = 1; @@ -356,12 +376,13 @@ mem_enable_command (char *args, int from_tty) char *p1; int num; struct mem_region *m; + int ix; dcache_invalidate (target_dcache); if (p == 0) { - for (m = mem_region_chain; m; m = m->next) + for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) m->enabled_p = 1; } else @@ -389,8 +410,9 @@ static void mem_disable (int num) { struct mem_region *m; + int ix; - for (m = mem_region_chain; m; m = m->next) + for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) if (m->number == num) { m->enabled_p = 0; @@ -406,12 +428,13 @@ mem_disable_command (char *args, int from_tty) char *p1; int num; struct mem_region *m; + int ix; dcache_invalidate (target_dcache); if (p == 0) { - for (m = mem_region_chain; m; m = m->next) + for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) m->enabled_p = 0; } else @@ -437,13 +460,7 @@ mem_disable_command (char *args, int from_tty) static void mem_clear (void) { - struct mem_region *m; - - while ((m = mem_region_chain) != 0) - { - mem_region_chain = m->next; - delete_mem_region (m); - } + VEC_free (mem_region_s, mem_region_list); } /* Delete the memory region number NUM. */ @@ -452,30 +469,25 @@ static void mem_delete (int num) { struct mem_region *m1, *m; + int ix; - if (!mem_region_chain) + if (!mem_region_list) { printf_unfiltered (_("No memory region number %d.\n"), num); return; } - if (mem_region_chain->number == num) + for (ix = 0; VEC_iterate (mem_region_s, mem_region_list, ix, m); ix++) + if (m->number == num) + break; + + if (m == NULL) { - m1 = mem_region_chain; - mem_region_chain = m1->next; - delete_mem_region (m1); + printf_unfiltered (_("No memory region number %d.\n"), num); + return; } - else - for (m = mem_region_chain; m->next; m = m->next) - { - if (m->next->number == num) - { - m1 = m->next; - m->next = m1->next; - delete_mem_region (m1); - break; - } - } + + VEC_ordered_remove (mem_region_s, mem_region_list, ix); } static void diff --git a/gdb/memattr.h b/gdb/memattr.h index cbb2aba..72c5887 100644 --- a/gdb/memattr.h +++ b/gdb/memattr.h @@ -1,5 +1,6 @@ /* Memory attributes support, for GDB. - Copyright (C) 2001 Free Software Foundation, Inc. + + Copyright (C) 2001, 2006 Free Software Foundation, Inc. This file is part of GDB. @@ -21,6 +22,8 @@ #ifndef MEMATTR_H #define MEMATTR_H +#include "vec.h" + enum mem_access_mode { MEM_RW, /* read/write */ @@ -67,12 +70,6 @@ struct mem_attrib struct mem_region { - /* FIXME: memory regions are stored in an unsorted singly-linked - list. This probably won't scale to handle hundreds of memory - regions --- that many could be needed to describe the allowed - access modes for memory mapped i/o device registers. */ - struct mem_region *next; - CORE_ADDR lo; CORE_ADDR hi; @@ -86,6 +83,12 @@ struct mem_region struct mem_attrib attrib; }; +/* Declare a vector type for a group of mem_region structures. The + typedef is necessary because vec.h can not handle a struct tag. + Except during construction, these vectors are kept sorted. */ +typedef struct mem_region mem_region_s; +DEF_VEC_O(mem_region_s); + extern struct mem_region *lookup_mem_region(CORE_ADDR); #endif /* MEMATTR_H */