From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8129 invoked by alias); 10 May 2012 19:52:57 -0000 Received: (qmail 8117 invoked by uid 22791); 10 May 2012 19:52:53 -0000 X-SWARE-Spam-Status: No, hits=-5.6 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,T_FILL_THIS_FORM_SHORT,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 10 May 2012 19:52:26 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q4AJqQVd000802 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 10 May 2012 15:52:26 -0400 Received: from barimba (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q4AJqORF019322 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Thu, 10 May 2012 15:52:24 -0400 From: Tom Tromey To: gdb-patches@sourceware.org Subject: Re: [3/10] introduce psymtab users References: <87haw7brks.fsf@fleche.redhat.com> Date: Thu, 10 May 2012 19:52:00 -0000 In-Reply-To: <87haw7brks.fsf@fleche.redhat.com> (Tom Tromey's message of "Wed, 25 Apr 2012 12:21:23 -0600") Message-ID: <87aa1fbyq0.fsf@fleche.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.95 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain 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: 2012-05/txt/msg00380.txt.bz2 >>>>> "Tom" == Tom Tromey writes: Tom> This patch adds some basic infrastructure to psymtabs. It adds a Tom> "users" field which the psymtab readers can set. Then, it changes the Tom> psymtab code to handle included psymtabs properly. Here is the updated version of this patch. I think it takes all the comments into account. Tom >From d8efcf6e2771975d8e314641b9265ce06e94d629 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 18 Apr 2012 14:49:36 -0600 Subject: [PATCH 03/10] introduce psymtab users notion * psymtab.c (partial_map_expand_apply): Add assertion. (partial_map_symtabs_matching_filename): Skip included psymtabs. (psymtab_to_symtab): Find unshared psymtab. (dump_psymtab): Print including psymtabs. (recursively_search_psymtabs): New function. (expand_symtabs_matching_via_partial): Use it. * psympriv.h (struct partial_symtab) : New fields. (enum psymtab_search_status): New. --- gdb/psympriv.h | 44 +++++++++++++++ gdb/psymtab.c | 165 ++++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 164 insertions(+), 45 deletions(-) diff --git a/gdb/psympriv.h b/gdb/psympriv.h index df7b874..370ce86 100644 --- a/gdb/psympriv.h +++ b/gdb/psympriv.h @@ -54,6 +54,17 @@ struct partial_symbol #define PSYMBOL_DOMAIN(psymbol) (psymbol)->domain #define PSYMBOL_CLASS(psymbol) (psymbol)->aclass +/* A convenience enum to give names to some constants used when + searching psymtabs. This is internal to psymtab and should not be + used elsewhere. */ + +enum psymtab_search_status + { + PST_NOT_SEARCHED, + PST_SEARCHED_AND_FOUND, + PST_SEARCHED_AND_NOT_FOUND + }; + /* Each source file that has not been fully read in is represented by a partial_symtab. This contains the information on where in the executable the debugging symbols for a specific file are, and a @@ -111,6 +122,35 @@ struct partial_symtab int number_of_dependencies; + /* If NULL, this is an ordinary partial symbol table. + + If non-NULL, this holds a single includer of this partial symbol + table, and this partial symbol table is a shared one. + + A shared psymtab is one that is referenced by multiple other + psymtabs, and which conceptually has its contents directly + included in those. + + Shared psymtabs have special semantics. When a search finds a + symbol in a shared table, we instead return one of the non-shared + tables that include this one. + + A shared psymtabs can be referred to by other shared ones. + + The psymtabs that refer to a shared psymtab will list the shared + psymtab in their 'dependencies' array. + + In DWARF terms, a shared psymtab is a DW_TAG_partial_unit; but + of course using a name based on that would be too confusing, so + "shared" was chosen instead. + + Only a single user is needed because, when expanding a shared + psymtab, we only need to expand its "canonical" non-shared user. + The choice of which one should be canonical is left to the + debuginfo reader; it can be arbitrary. */ + + struct partial_symtab *user; + /* Global symbol list. This list will be sorted after readin to improve access. Binary search will be the usual method of finding a symbol within it. globals_offset is an integer offset @@ -142,6 +182,10 @@ struct partial_symtab unsigned char psymtabs_addrmap_supported; + /* A flag that is temporarily used when searching psymtabs. */ + + ENUM_BITFIELD (psymtab_search_status) searched_flag : 2; + /* Pointer to symtab eventually allocated for this source file, 0 if !readin or if we haven't looked for the symtab after it was readin. */ diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 9620de8..814023e 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -135,6 +135,10 @@ partial_map_expand_apply (struct objfile *objfile, { struct symtab *last_made = objfile->symtabs; + /* Shared psymtabs should never be seen here. Instead they should + be handled properly by the caller. */ + gdb_assert (pst->user == NULL); + /* Don't visit already-expanded psymtabs. */ if (pst->readin) return 0; @@ -165,6 +169,11 @@ partial_map_symtabs_matching_filename (struct objfile *objfile, ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst) { + /* We can skip shared psymtabs here, because any file name will be + attached to the unshared psymtab. */ + if (pst->user != NULL) + continue; + if (FILENAME_CMP (name, pst->filename) == 0 || (!is_abs && compare_filenames_for_search (pst->filename, name, name_len))) @@ -760,6 +769,11 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, static struct symtab * psymtab_to_symtab (struct partial_symtab *pst) { + /* If it is a shared psymtab, find an unshared psymtab that includes + it. Any such psymtab will do. */ + while (pst->user != NULL) + pst = pst->user; + /* If it's been looked up before, return it. */ if (pst->symtab) return pst->symtab; @@ -1000,6 +1014,12 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab, fprintf_filtered (outfile, " %s\n", psymtab->dependencies[i]->filename); } + if (psymtab->user != NULL) + { + fprintf_filtered (outfile, " Shared partial symtab with user "); + gdb_print_host_address (psymtab->user, outfile); + fprintf_filtered (outfile, "\n"); + } if (psymtab->n_global_syms > 0) { print_partial_symbols (gdbarch, @@ -1236,6 +1256,94 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace, } } +/* A helper for expand_symtabs_matching_via_partial that handles + searching included psymtabs. This returns 1 if a symbol is found, + and zero otherwise. It also updates the 'searched_flag' on the + various psymtabs that it searches. */ + +static int +recursively_search_psymtabs (struct partial_symtab *ps, + struct objfile *objfile, + enum search_domain kind, + int (*name_matcher) (const char *, void *), + void *data) +{ + struct partial_symbol **psym; + struct partial_symbol **bound, **gbound, **sbound; + int keep_going = 1; + int result = PST_SEARCHED_AND_NOT_FOUND; + int i; + + if (ps->searched_flag != PST_NOT_SEARCHED) + return ps->searched_flag == PST_SEARCHED_AND_FOUND; + + /* Recurse into shared psymtabs first, because they may have already + been searched, and this could save some time. */ + for (i = 0; i < ps->number_of_dependencies; ++i) + { + int r; + + /* Skip non-shared dependencies, these are handled elsewhere. */ + if (ps->dependencies[i]->user == NULL) + continue; + + r = recursively_search_psymtabs (ps->dependencies[i], + objfile, kind, name_matcher, data); + if (r != 0) + { + ps->searched_flag = PST_SEARCHED_AND_FOUND; + return 1; + } + } + + gbound = (objfile->global_psymbols.list + + ps->globals_offset + ps->n_global_syms); + sbound = (objfile->static_psymbols.list + + ps->statics_offset + ps->n_static_syms); + bound = gbound; + + /* Go through all of the symbols stored in a partial + symtab in one loop. */ + psym = objfile->global_psymbols.list + ps->globals_offset; + while (keep_going) + { + if (psym >= bound) + { + if (bound == gbound && ps->n_static_syms != 0) + { + psym = objfile->static_psymbols.list + ps->statics_offset; + bound = sbound; + } + else + keep_going = 0; + continue; + } + else + { + QUIT; + + if ((kind == ALL_DOMAIN + || (kind == VARIABLES_DOMAIN + && SYMBOL_CLASS (*psym) != LOC_TYPEDEF + && SYMBOL_CLASS (*psym) != LOC_BLOCK) + || (kind == FUNCTIONS_DOMAIN + && SYMBOL_CLASS (*psym) == LOC_BLOCK) + || (kind == TYPES_DOMAIN + && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)) + && (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data)) + { + /* Found a match, so notify our caller. */ + result = PST_SEARCHED_AND_FOUND; + keep_going = 0; + } + } + psym++; + } + + ps->searched_flag = result; + return result == PST_SEARCHED_AND_FOUND; +} + static void expand_symtabs_matching_via_partial (struct objfile *objfile, @@ -1246,60 +1354,27 @@ expand_symtabs_matching_via_partial { struct partial_symtab *ps; + /* Clear the search flags. */ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps) { - struct partial_symbol **psym; - struct partial_symbol **bound, **gbound, **sbound; - int keep_going = 1; + ps->searched_flag = PST_NOT_SEARCHED; + } + ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps) + { if (ps->readin) continue; - if (file_matcher && ! (*file_matcher) (ps->filename, data)) + /* We skip shared psymtabs because file-matching doesn't apply + to them; but we search them later in the loop. */ + if (ps->user != NULL) continue; - gbound = objfile->global_psymbols.list - + ps->globals_offset + ps->n_global_syms; - sbound = objfile->static_psymbols.list - + ps->statics_offset + ps->n_static_syms; - bound = gbound; + if (file_matcher && ! (*file_matcher) (ps->filename, data)) + continue; - /* Go through all of the symbols stored in a partial - symtab in one loop. */ - psym = objfile->global_psymbols.list + ps->globals_offset; - while (keep_going) - { - if (psym >= bound) - { - if (bound == gbound && ps->n_static_syms != 0) - { - psym = objfile->static_psymbols.list + ps->statics_offset; - bound = sbound; - } - else - keep_going = 0; - continue; - } - else - { - QUIT; - - if ((kind == ALL_DOMAIN - || (kind == VARIABLES_DOMAIN - && SYMBOL_CLASS (*psym) != LOC_TYPEDEF - && SYMBOL_CLASS (*psym) != LOC_BLOCK) - || (kind == FUNCTIONS_DOMAIN - && SYMBOL_CLASS (*psym) == LOC_BLOCK) - || (kind == TYPES_DOMAIN - && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)) - && (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data)) - { - psymtab_to_symtab (ps); - keep_going = 0; - } - } - psym++; - } + if (recursively_search_psymtabs (ps, objfile, kind, name_matcher, data)) + psymtab_to_symtab (ps); } } -- 1.7.7.6