From 0cf636d8fee13e6d9fc321caaa9e2289a5f8a821 Mon Sep 17 00:00:00 2001 From: Soren Sandmann Date: Sun, 8 Oct 2006 20:14:25 +0000 Subject: [PATCH] Add a cache of the text section. 2006-10-08 Soren Sandmann * elfparser.c (struct ElfParser): Add a cache of the text section. * binparser.c (struct BinParser): Add a cache of a bin record to get rid of malloc()/free() overhead. * elfparser.c (struct ElfSym): Cache the size of the symbol --- ChangeLog | 9 +++++++++ binfile.c | 5 ++++- binparser.c | 23 +++++++++++++++++++++-- elfparser.c | 61 ++++++++++++++++++++++++++----------------------------------- 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index 258c2b6..2a37775 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-10-08 Soren Sandmann + + * elfparser.c (struct ElfParser): Add a cache of the text section. + + * binparser.c (struct BinParser): Add a cache of a bin record to + get rid of malloc()/free() overhead. + + * elfparser.c (struct ElfSym): Cache the size of the symbol + 2006-10-08 Soren Sandmann * elfparser.c: Remove now unused load-address heuristic diff --git a/binfile.c b/binfile.c index 8d98b8e..6eb7063 100644 --- a/binfile.c +++ b/binfile.c @@ -191,9 +191,12 @@ bin_file_new (const char *filename) * (potential) debug binary */ if (bf->elf) + { bf->text_offset = elf_parser_get_text_offset (bf->elf); - bf->elf = find_separate_debug_file (bf->elf, filename); /* find_separate_debug_file (bf->elf, filename); */ + 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); diff --git a/binparser.c b/binparser.c index 93e0020..2fba501 100644 --- a/binparser.c +++ b/binparser.c @@ -35,6 +35,9 @@ struct BinParser gsize offset; const guchar * data; gsize length; + + gboolean cache_in_use; + BinRecord cache; }; BinParser * @@ -46,6 +49,7 @@ bin_parser_new (const guchar *data, parser->offset = 0; parser->data = data; parser->length = length; + parser->cache_in_use = FALSE; return parser; } @@ -359,18 +363,33 @@ bin_parser_get_record (BinParser *parser, BinFormat *format, gsize offset) { - BinRecord *record = g_new0 (BinRecord, 1); + BinRecord *record; + + if (!parser->cache_in_use) + { + parser->cache_in_use = TRUE; + record = &(parser->cache); + } + else + { + record = g_new0 (BinRecord, 1); + } + record->parser = parser; record->index = 0; record->offset = offset; record->format = format; + return record; } void bin_record_free (BinRecord *record) { - g_free (record); + if (record == &(record->parser->cache)) + record->parser->cache_in_use = FALSE; + else + g_free (record); } guint64 diff --git a/elfparser.c b/elfparser.c index 742c57a..a7d013a 100644 --- a/elfparser.c +++ b/elfparser.c @@ -10,6 +10,7 @@ struct ElfSym { gulong offset; gulong address; + gulong size; }; struct Section @@ -39,6 +40,8 @@ struct ElfParser gsize sym_strings; GMappedFile * file; + + const Section * text_section; }; static gboolean parse_elf_signature (const guchar *data, gsize length, @@ -176,6 +179,11 @@ parser_new_from_data (const guchar *data, gsize length) parser->sections[i] = section_new (shn_entry, section_names); } + + /* Cache the text section */ + parser->text_section = find_section (parser, ".text", SHT_PROGBITS); + if (!parser->text_section) + parser->text_section = find_section (parser, ".text", SHT_NOBITS); bin_record_free (shn_entry); @@ -208,6 +216,14 @@ elf_parser_new (const char *filename, parser = parser_new_from_data (data, length); + if (!parser) + { + g_mapped_file_free (file); + return NULL; + } + + parser->file = file; + #if 0 g_print ("Elf file: %s (debug: %s)\n", filename, elf_parser_get_debug_link (parser, NULL)); @@ -420,6 +436,8 @@ read_table (ElfParser *parser, { parser->symbols[n_functions].address = addr; parser->symbols[n_functions].offset = offset; + parser->symbols[n_functions].size = + bin_record_get_uint (symbol, "st_size"); #if 0 g_print ("name: %s\n", @@ -531,7 +549,6 @@ const ElfSym * elf_parser_lookup_symbol (ElfParser *parser, gulong address) { - const Section *text; const ElfSym *result; gsize size; @@ -541,15 +558,10 @@ elf_parser_lookup_symbol (ElfParser *parser, if (parser->n_symbols == 0) return NULL; - text = find_section (parser, ".text", SHT_PROGBITS); - if (!text) - { - text = find_section (parser, ".text", SHT_NOBITS); - if (!text) - return NULL; - } + if (!parser->text_section) + return NULL; - address += text->load_address; + address += parser->text_section->load_address; #if 0 g_print ("the address we are looking up is %p\n", address); @@ -564,21 +576,8 @@ elf_parser_lookup_symbol (ElfParser *parser, } #endif - if (result) - { - BinRecord *symbol; - - /* Check that address is actually within the function */ - symbol = bin_parser_get_record (parser->parser, - parser->sym_format, result->offset); - - size = bin_record_get_uint (symbol, "st_size"); - - if (result->address + size <= address) - result = NULL; - - bin_record_free (symbol); - } + if (result && result->address + result->size <= address) + result = NULL; return result; } @@ -586,20 +585,12 @@ elf_parser_lookup_symbol (ElfParser *parser, gulong elf_parser_get_text_offset (ElfParser *parser) { - const Section *text; - g_return_val_if_fail (parser != NULL, (gulong)-1); - - text = find_section (parser, ".text", SHT_PROGBITS); - if (!text) - { - text = find_section (parser, ".text", SHT_NOBITS); - if (!text) - return (gulong)-1; - } + if (!parser->text_section) + return (gulong)-1; - return text->offset; + return parser->text_section->offset; } const char * -- 2.7.4