Add a cache of the text section.

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

	* 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
This commit is contained in:
Soren Sandmann
2006-10-08 20:14:25 +00:00
committed by Søren Sandmann Pedersen
parent 86810e63a5
commit 0cf636d8fe
4 changed files with 60 additions and 38 deletions

View File

@ -1,3 +1,12 @@
2006-10-08 Soren Sandmann <sandmann@redhat.com>
* 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 <sandmann@redhat.com>
* elfparser.c: Remove now unused load-address heuristic

View File

@ -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);

View File

@ -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

View File

@ -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 *