From a845f5cbc85f6501d73e578d2b97449e37064ba4 Mon Sep 17 00:00:00 2001 From: Paul Pluzhnikov Date: Tue, 21 Jul 2009 20:54:30 +0000 Subject: [PATCH] 2009-07-21 Paul Pluzhnikov * objfiles.c (objfiles_updated_p): New variable. (qsort_cmp, bsearch_cmp, update_section_map): New function. (find_pc_section): Use bsearch. (set_objfiles_updated_on_exe_change): New function. (set_objfiles_updated_on_solib_activity): New function. (_initialize_objfiles): New function. --- gdb/ChangeLog | 9 ++++ gdb/objfiles.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 136 insertions(+), 5 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3a3b812ea47..84a91af2dcc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2009-07-21 Paul Pluzhnikov + + * objfiles.c (objfiles_updated_p): New variable. + (qsort_cmp, bsearch_cmp, update_section_map): New function. + (find_pc_section): Use bsearch. + (set_objfiles_updated_on_exe_change): New function. + (set_objfiles_updated_on_solib_activity): New function. + (_initialize_objfiles): New function. + 2009-06-26 Michael Eager * features/rs6000/powerpc-405.xml: New. diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 69b366f0e60..ab5f0ea381b 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -50,6 +50,7 @@ #include "addrmap.h" #include "arch-utils.h" #include "exec.h" +#include "observer.h" /* Prototypes for local functions */ @@ -64,6 +65,11 @@ struct objfile *current_objfile; /* For symbol file being read in */ struct objfile *symfile_objfile; /* Main symbol table loaded from */ struct objfile *rt_common_objfile; /* For runtime common symbols */ +/* Records whether any objfiles appeared or disappeared since we last updated + address to obj section map. */ + +static int objfiles_updated_p; + /* Locate all mappable sections of a BFD file. objfile_p_char is a char * to get it through bfd_map_over_sections; we cast it back to its proper type. */ @@ -757,23 +763,113 @@ have_minimal_symbols (void) return 0; } +/* Qsort comparison function. */ + +static int +qsort_cmp (const void *a, const void *b) +{ + const struct obj_section *sect1 = *(const struct obj_section **) a; + const struct obj_section *sect2 = *(const struct obj_section **) b; + const CORE_ADDR sect1_addr = obj_section_addr (sect1); + const CORE_ADDR sect2_addr = obj_section_addr (sect2); + + if (sect1_addr < sect2_addr) + { + gdb_assert (obj_section_endaddr (sect1) <= sect2_addr); + return -1; + } + else if (sect1_addr > sect2_addr) + { + gdb_assert (sect1_addr >= obj_section_endaddr (sect2)); + return 1; + } + /* This can happen for separate debug-info files. */ + gdb_assert (obj_section_endaddr (sect1) == obj_section_endaddr (sect2)); + + return 0; +} + +/* Update PMAP, PMAP_SIZE with non-TLS sections from all objfiles. */ + +static void +update_section_map (struct obj_section ***pmap, int *pmap_size) +{ + int map_size, idx; + struct obj_section *s, **map; + struct objfile *objfile; + + gdb_assert (objfiles_updated_p != 0); + + map = *pmap; + xfree (map); + +#define insert_p(objf, sec) \ + ((bfd_get_section_flags ((objf)->obfd, (sec)->the_bfd_section) \ + & SEC_THREAD_LOCAL) == 0) + + map_size = 0; + ALL_OBJSECTIONS (objfile, s) + if (insert_p (objfile, s)) + map_size += 1; + + map = xmalloc (map_size * sizeof (*map)); + + idx = 0; + ALL_OBJSECTIONS (objfile, s) + if (insert_p (objfile, s)) + map[idx++] = s; + +#undef insert_p + + qsort (map, map_size, sizeof (*map), qsort_cmp); + + *pmap = map; + *pmap_size = map_size; +} + +/* Bsearch comparison function. */ + +static int +bsearch_cmp (const void *key, const void *elt) +{ + const CORE_ADDR pc = *(CORE_ADDR *) key; + const struct obj_section *section = *(const struct obj_section **) elt; + + if (pc < obj_section_addr (section)) + return -1; + if (pc < obj_section_endaddr (section)) + return 0; + return 1; +} + /* Returns a section whose range includes PC or NULL if none found. */ struct obj_section * find_pc_section (CORE_ADDR pc) { - struct obj_section *s; - struct objfile *objfile; + static struct obj_section **sections; + static int num_sections; + + struct obj_section *s, **sp; /* Check for mapped overlay section first. */ s = find_pc_mapped_section (pc); if (s) return s; - ALL_OBJSECTIONS (objfile, s) - if (obj_section_addr (s) <= pc && pc < obj_section_endaddr (s)) - return s; + if (objfiles_updated_p != 0) + { + update_section_map (§ions, &num_sections); + /* Don't need updates to section map until objfiles are added + or removed. */ + objfiles_updated_p = 0; + } + + sp = (struct obj_section **) bsearch (&pc, sections, num_sections, + sizeof (*sections), bsearch_cmp); + if (sp != NULL) + return *sp; return NULL; } @@ -892,3 +988,29 @@ objfile_data (struct objfile *objfile, const struct objfile_data *data) gdb_assert (data->index < objfile->num_data); return objfile->data[data->index]; } + +/* Set objfiles_updated_p so section map will be rebuilt next time it + is used. Called by executable_changed observer. */ + +static void +set_objfiles_updated_on_exe_change (void) +{ + objfiles_updated_p = 1; /* Rebuild section map next time we need it. */ +} + +/* Set objfiles_updated_p so section map will be rebuilt next time it + is used. Called by solib_loaded/unloaded observer. */ + +static void +set_objfiles_updated_on_solib_activity (struct so_list *so_list) +{ + objfiles_updated_p = 1; /* Rebuild section map next time we need it. */ +} + +void +_initialize_objfiles (void) +{ + observer_attach_executable_changed (set_objfiles_updated_on_exe_change); + observer_attach_solib_loaded (set_objfiles_updated_on_solib_activity); + observer_attach_solib_unloaded (set_objfiles_updated_on_solib_activity); +} -- 2.30.2