From bb616fd7549f96477f6170057a56324868580ce9 Mon Sep 17 00:00:00 2001 From: Soren Sandmann Date: Tue, 22 Aug 2006 03:26:57 +0000 Subject: [PATCH] Add ref_count and filename (bin_files): Add map from filenames to BinFiles 2006-08-21 Soren Sandmann * binfile.c (struct BinFile): Add ref_count and filename (bin_files): Add map from filenames to BinFiles (bin_file_new): First look for BinFile in the cache. (bin_file_free): If refcount reaches 0, remove BinFile from cache. * TODO: Updates --- ChangeLog | 9 +++++++++ TODO | 7 +++++++ binfile.c | 60 ++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6d601b6c..c8492a4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-08-21 Soren Sandmann + + * binfile.c (struct BinFile): Add ref_count and filename + (bin_files): Add map from filenames to BinFiles + (bin_file_new): First look for BinFile in the cache. + (bin_file_free): If refcount reaches 0, remove BinFile from cache. + + * TODO: Updates + 2006-08-21 Soren Sandmann * process.c (process_lookup_symbol): Pass map->bin_file to diff --git a/TODO b/TODO index 4c337908..93bb10c2 100644 --- a/TODO +++ b/TODO @@ -32,7 +32,12 @@ Before 1.0.4: Before 1.2: +* Delete elf_parser_new() and rename elf_parser_new_from_file() + * See if we can make "In file " not be treated as a recursive function. + Maybe simply treat each individual address in the file as a function. + Or try to parse the machine code. Places that are called are likely + to be functions. * Give more sensible 'error messages'. Ie., if you get permission denied for a file, put "Permission denied" instead of "No map" @@ -606,6 +611,8 @@ Later: -=-=-=-=-=-=-=-=-=-=-=-=-=-=- ALREADY DONE -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +* Restore filename => binfile cache. + * It is apparently possible to get another timer interrupt in the middle of timer_notify. If this happens the circular buffer gets screwed up and you get crashes. Note this gets much worse on SMP (in fact how did this diff --git a/binfile.c b/binfile.c index 469ba40d..692d3e45 100644 --- a/binfile.c +++ b/binfile.c @@ -38,9 +38,14 @@ struct BinFile { - ElfParser *elf; - ino_t inode; - char *undefined_name; + int ref_count; + + ElfParser * elf; + + char * filename; + ino_t inode; + + char * undefined_name; }; /* FIXME: error handling */ @@ -54,7 +59,6 @@ read_inode (const char *filename) return statbuf.st_ino; } - static ElfParser * separate_debug_file_exists (const char *name, guint32 crc) { @@ -63,7 +67,7 @@ separate_debug_file_exists (const char *name, guint32 crc) if (!parser) return NULL; - + file_crc = elf_parser_get_crc32 (parser); if (file_crc != crc) @@ -129,17 +133,35 @@ find_separate_debug_file (ElfParser *elf, } } +static GHashTable *bin_files; + BinFile * bin_file_new (const char *filename) { /* FIXME: should be able to return an error */ BinFile *bf; - - bf = g_new0 (BinFile, 1); - bf->elf = elf_parser_new_from_file (filename, NULL); - bf->elf = find_separate_debug_file (bf->elf, filename); - bf->inode = read_inode (filename); - bf->undefined_name = g_strdup_printf ("In file %s", filename); + + if (!bin_files) + bin_files = g_hash_table_new (g_str_hash, g_str_equal); + + bf = g_hash_table_lookup (bin_files, filename); + + if (bf) + { + bf->ref_count++; + } + else + { + bf = g_new0 (BinFile, 1); + bf->elf = elf_parser_new_from_file (filename, NULL); + bf->elf = find_separate_debug_file (bf->elf, filename); + bf->inode = read_inode (filename); + bf->filename = g_strdup (filename); + bf->undefined_name = g_strdup_printf ("In file %s", filename); + bf->ref_count = 1; + + g_hash_table_insert (bin_files, bf->filename, bf); + } return bf; } @@ -147,11 +169,17 @@ bin_file_new (const char *filename) void bin_file_free (BinFile *bin_file) { - if (bin_file->elf) - elf_parser_free (bin_file->elf); - - g_free (bin_file->undefined_name); - g_free (bin_file); + if (bin_file->ref_count-- == 0) + { + g_hash_table_remove (bin_files, bin_file->filename); + + if (bin_file->elf) + elf_parser_free (bin_file->elf); + + g_free (bin_file->filename); + g_free (bin_file->undefined_name); + g_free (bin_file); + } } const BinSymbol *