Add ref_count and filename (bin_files): Add map from filenames to BinFiles

2006-08-21  Soren Sandmann <sandmann@redhat.com>

	* 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
This commit is contained in:
Soren Sandmann
2006-08-22 03:26:57 +00:00
committed by Søren Sandmann Pedersen
parent a1bddd8d9f
commit bb616fd754
3 changed files with 60 additions and 16 deletions

View File

@ -1,3 +1,12 @@
2006-08-21 Soren Sandmann <sandmann@redhat.com>
* 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 <sandmann@redhat.com> 2006-08-21 Soren Sandmann <sandmann@redhat.com>
* process.c (process_lookup_symbol): Pass map->bin_file to * process.c (process_lookup_symbol): Pass map->bin_file to

7
TODO
View File

@ -32,7 +32,12 @@ Before 1.0.4:
Before 1.2: Before 1.2:
* Delete elf_parser_new() and rename elf_parser_new_from_file()
* See if we can make "In file <blah>" not be treated as a recursive function. * See if we can make "In file <blah>" 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 * Give more sensible 'error messages'. Ie., if you get permission denied for
a file, put "Permission denied" instead of "No map" a file, put "Permission denied" instead of "No map"
@ -606,6 +611,8 @@ Later:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ALREADY DONE -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -=-=-=-=-=-=-=-=-=-=-=-=-=-=- ALREADY DONE -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* Restore filename => binfile cache.
* It is apparently possible to get another timer interrupt in the middle * 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 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 you get crashes. Note this gets much worse on SMP (in fact how did this

View File

@ -38,9 +38,14 @@
struct BinFile struct BinFile
{ {
ElfParser *elf; int ref_count;
ino_t inode;
char *undefined_name; ElfParser * elf;
char * filename;
ino_t inode;
char * undefined_name;
}; };
/* FIXME: error handling */ /* FIXME: error handling */
@ -54,7 +59,6 @@ read_inode (const char *filename)
return statbuf.st_ino; return statbuf.st_ino;
} }
static ElfParser * static ElfParser *
separate_debug_file_exists (const char *name, guint32 crc) separate_debug_file_exists (const char *name, guint32 crc)
{ {
@ -129,17 +133,35 @@ find_separate_debug_file (ElfParser *elf,
} }
} }
static GHashTable *bin_files;
BinFile * BinFile *
bin_file_new (const char *filename) bin_file_new (const char *filename)
{ {
/* FIXME: should be able to return an error */ /* FIXME: should be able to return an error */
BinFile *bf; BinFile *bf;
bf = g_new0 (BinFile, 1); if (!bin_files)
bf->elf = elf_parser_new_from_file (filename, NULL); bin_files = g_hash_table_new (g_str_hash, g_str_equal);
bf->elf = find_separate_debug_file (bf->elf, filename);
bf->inode = read_inode (filename); bf = g_hash_table_lookup (bin_files, filename);
bf->undefined_name = g_strdup_printf ("In file %s", 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; return bf;
} }
@ -147,11 +169,17 @@ bin_file_new (const char *filename)
void void
bin_file_free (BinFile *bin_file) bin_file_free (BinFile *bin_file)
{ {
if (bin_file->elf) if (bin_file->ref_count-- == 0)
elf_parser_free (bin_file->elf); {
g_hash_table_remove (bin_files, bin_file->filename);
g_free (bin_file->undefined_name); if (bin_file->elf)
g_free (bin_file); elf_parser_free (bin_file->elf);
g_free (bin_file->filename);
g_free (bin_file->undefined_name);
g_free (bin_file);
}
} }
const BinSymbol * const BinSymbol *