Add new struct BinRecord. Comment out functions related to formats. Add

2006-08-26  Soren Sandmann <sandmann@daimi.au.dk>

	* binparser.[ch]: Add new struct BinRecord. Comment out functions
	related to formats. Add new functions to get fields out of
	BinRecords.

	* elfparser.c: Update to new API.
This commit is contained in:
Soren Sandmann
2006-08-26 22:44:12 +00:00
committed by Søren Sandmann Pedersen
parent b569c3a34c
commit 54862afc74
4 changed files with 90 additions and 52 deletions

View File

@ -1,3 +1,11 @@
2006-08-26 Soren Sandmann <sandmann@daimi.au.dk>
* binparser.[ch]: Add new struct BinRecord. Comment out functions
related to formats. Add new functions to get fields out of
BinRecords.
* elfparser.c: Update to new API.
2006-08-26 Soren Sandmann <sandmann@daimi.au.dk> 2006-08-26 Soren Sandmann <sandmann@daimi.au.dk>
* binparser.h: Add new bin_record() functions * binparser.h: Add new bin_record() functions

View File

@ -338,6 +338,32 @@ bin_parser_index (BinParser *parser,
parser->frame->index = index; parser->frame->index = index;
} }
BinParser *
bin_record_get_parser (BinRecord *record)
{
return record->parser;
}
const gchar *
bin_record_get_string_indirect (BinRecord *record,
const char *name,
gsize str_table)
{
BinParser *parser = record->parser;
const char *result = NULL;
gsize index;
index = bin_record_get_uint (record, name);
bin_parser_begin (parser, record->format, str_table + index);
result = bin_parser_get_string (parser);
bin_parser_end (record->parser);
return result;
}
gsize gsize
bin_parser_get_offset (BinParser *parser) bin_parser_get_offset (BinParser *parser)
{ {
@ -410,6 +436,12 @@ bin_record_index (BinRecord *record,
record->index = index; record->index = index;
} }
gsize
bin_record_get_offset (BinRecord *record)
{
return record->offset;
}
/* Fields */ /* Fields */
BinField * BinField *

View File

@ -11,14 +11,16 @@ BinParser *bin_parser_new (const guchar *data,
const guchar *bin_parser_get_data (BinParser *parser); const guchar *bin_parser_get_data (BinParser *parser);
gsize bin_parser_get_length (BinParser *parser); gsize bin_parser_get_length (BinParser *parser);
gsize bin_parser_get_offset (BinParser *parser); gsize bin_parser_get_offset (BinParser *parser);
#if 0
void bin_parser_index (BinParser *parser, int index); void bin_parser_index (BinParser *parser, int index);
void bin_parser_begin (BinParser *parser, void bin_parser_begin (BinParser *parser,
BinFormat *format, BinFormat *format,
gsize offset); gsize offset);
void bin_parser_end (BinParser *parser); void bin_parser_end (BinParser *parser);
const char *bin_parser_get_string (BinParser *parser);
guint64 bin_parser_get_uint (BinParser *parser, guint64 bin_parser_get_uint (BinParser *parser,
const gchar *name); const gchar *name);
#endif
const char *bin_parser_get_string (BinParser *parser);
/* Record */ /* Record */
BinRecord *bin_parser_get_record (BinParser *parser, BinRecord *bin_parser_get_record (BinParser *parser,
@ -29,6 +31,11 @@ guint64 bin_record_get_uint (BinRecord *record,
const char *name); const char *name);
void bin_record_index (BinRecord *record, void bin_record_index (BinRecord *record,
int index); int index);
gsize bin_record_get_offset (BinRecord *record);
const gchar *bin_record_get_string_indirect (BinRecord *record,
const char *name,
gsize str_table);
BinParser *bin_record_get_parser (BinRecord *record);
/* BinFormat */ /* BinFormat */
BinFormat *bin_format_new (gboolean big_endian, BinFormat *bin_format_new (gboolean big_endian,

View File

@ -46,42 +46,23 @@ static void make_formats (ElfParser *parser,
gboolean is_64, gboolean is_64,
gboolean is_big_endian); gboolean is_big_endian);
static const char *
get_string (BinParser *parser,
gsize table,
const char *name)
{
const char *result = NULL;
gsize index;
index = bin_parser_get_uint (parser, name);
bin_parser_begin (parser, NULL, table + index);
result = bin_parser_get_string (parser);
bin_parser_end (parser);
return result;
}
static Section * static Section *
section_new (ElfParser *parser, section_new (BinRecord *record,
gsize name_table) gsize name_table)
{ {
BinParser *bparser = parser->parser;
Section *section = g_new (Section, 1); Section *section = g_new (Section, 1);
guint64 flags; guint64 flags;
section->name = get_string (bparser, name_table, "sh_name"); section->name = bin_record_get_string_indirect (
section->size = bin_parser_get_uint (bparser, "sh_size"); record, "sh_name", name_table);
section->offset = bin_parser_get_uint (bparser, "sh_offset"); section->size = bin_record_get_uint (record, "sh_size");
section->offset = bin_record_get_uint (record, "sh_offset");
flags = bin_parser_get_uint (bparser, "sh_flags"); flags = bin_record_get_uint (record, "sh_flags");
section->allocated = !!(flags & SHF_ALLOC); section->allocated = !!(flags & SHF_ALLOC);
if (section->allocated) if (section->allocated)
section->load_address = bin_parser_get_uint (bparser, "sh_addr"); section->load_address = bin_record_get_uint (record, "sh_addr");
else else
section->load_address = 0; section->load_address = 0;
@ -120,6 +101,7 @@ parser_new_from_data (const guchar *data, gsize length)
gsize section_names; gsize section_names;
gsize section_headers; gsize section_headers;
int i; int i;
BinRecord *elf_header, *shn_entry;
if (!parse_elf_signature (data, length, &is_64, &is_big_endian)) if (!parse_elf_signature (data, length, &is_64, &is_big_endian))
{ {
@ -134,30 +116,32 @@ parser_new_from_data (const guchar *data, gsize length)
make_formats (parser, is_64, is_big_endian); make_formats (parser, is_64, is_big_endian);
/* Read ELF header */ /* Read ELF header */
bin_parser_begin (parser->parser, parser->header, 0);
parser->n_sections = bin_parser_get_uint (parser->parser, "e_shnum"); elf_header = bin_parser_get_record (parser->parser, parser->header, 0);
section_names_idx = bin_parser_get_uint (parser->parser, "e_shstrndx");
section_headers = bin_parser_get_uint (parser->parser, "e_shoff");
bin_parser_end (parser->parser); parser->n_sections = bin_record_get_uint (elf_header, "e_shnum");
section_names_idx = bin_record_get_uint (elf_header, "e_shstrndx");
section_headers = bin_record_get_uint (elf_header, "e_shoff");
bin_record_free (elf_header);
/* Read section headers */ /* Read section headers */
parser->sections = g_new0 (Section *, parser->n_sections); parser->sections = g_new0 (Section *, parser->n_sections);
bin_parser_begin (parser->parser, parser->shn_entry, section_headers); shn_entry = bin_parser_get_record (parser->parser,
parser->shn_entry, section_headers);
bin_parser_index (parser->parser, section_names_idx); bin_record_index (shn_entry, section_names_idx);
section_names = bin_parser_get_uint (parser->parser, "sh_offset"); section_names = bin_record_get_uint (shn_entry, "sh_offset");
for (i = 0; i < parser->n_sections; ++i) for (i = 0; i < parser->n_sections; ++i)
{ {
bin_parser_index (parser->parser, i); bin_record_index (shn_entry, i);
parser->sections[i] = section_new (parser, section_names); parser->sections[i] = section_new (shn_entry, section_names);
} }
bin_parser_end (parser->parser); bin_record_free (shn_entry);
return parser; return parser;
} }
@ -316,6 +300,7 @@ read_table (ElfParser *parser,
int sym_size = bin_format_get_size (parser->sym_format); int sym_size = bin_format_get_size (parser->sym_format);
int i; int i;
int n_functions; int n_functions;
BinRecord *symbol;
parser->n_symbols = sym_table->size / sym_size; parser->n_symbols = sym_table->size / sym_size;
parser->symbols = g_new (ElfSym, parser->n_symbols); parser->symbols = g_new (ElfSym, parser->n_symbols);
@ -325,7 +310,7 @@ read_table (ElfParser *parser,
parser->n_symbols, sym_size, sym_table->name); parser->n_symbols, sym_size, sym_table->name);
#endif #endif
bin_parser_begin (parser->parser, parser->sym_format, sym_table->offset); symbol = bin_parser_get_record (parser->parser, parser->sym_format, sym_table->offset);
n_functions = 0; n_functions = 0;
for (i = 0; i < parser->n_symbols; ++i) for (i = 0; i < parser->n_symbols; ++i)
@ -335,12 +320,13 @@ read_table (ElfParser *parser,
const char *name; const char *name;
gulong offset; gulong offset;
bin_parser_index (parser->parser, i); bin_record_index (symbol, i);
info = bin_parser_get_uint (parser->parser, "st_info"); info = bin_record_get_uint (symbol, "st_info");
addr = bin_parser_get_uint (parser->parser, "st_value"); addr = bin_record_get_uint (symbol, "st_value");
name = get_string (parser->parser, str_table->offset, "st_name"); name = bin_record_get_string_indirect (symbol, "st_name",
offset = bin_parser_get_offset (parser->parser); str_table->offset);
offset = bin_record_get_offset (symbol);
if (addr != 0 && if (addr != 0 &&
(info & 0xf) == STT_FUNC && (info & 0xf) == STT_FUNC &&
@ -354,7 +340,7 @@ read_table (ElfParser *parser,
} }
} }
bin_parser_end (parser->parser); bin_record_free (symbol);
#if 0 #if 0
g_print ("found %d functions\n", n_functions); g_print ("found %d functions\n", n_functions);
@ -475,15 +461,18 @@ elf_parser_lookup_symbol (ElfParser *parser,
if (result) if (result)
{ {
/* Check that address is actually within the function */ BinRecord *symbol;
bin_parser_begin (parser->parser, parser->sym_format, result->offset);
size = bin_parser_get_uint (parser->parser, "st_size"); /* 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) if (result->address + size <= address)
result = NULL; result = NULL;
bin_parser_end (parser->parser); bin_record_free (symbol);
} }
return result; return result;
@ -556,14 +545,16 @@ elf_parser_get_sym_name (ElfParser *parser,
const ElfSym *sym) const ElfSym *sym)
{ {
const char *result; const char *result;
BinRecord *symbol;
g_return_val_if_fail (parser != NULL, NULL); g_return_val_if_fail (parser != NULL, NULL);
bin_parser_begin (parser->parser, parser->sym_format, sym->offset); symbol = bin_parser_get_record (parser->parser, parser->sym_format, sym->offset);
result = get_string (parser->parser, parser->sym_strings, "st_name"); result = bin_record_get_string_indirect (symbol, "st_name",
parser->sym_strings);
bin_parser_end (parser->parser); bin_record_free (symbol);
return result; return result;
} }