Really add this file.

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

	* testelf.c: Really add this file.
This commit is contained in:
Soren Sandmann
2006-08-16 17:21:54 +00:00
committed by Søren Sandmann Pedersen
parent 2bc2e3658d
commit 1f4dd13cd3
4 changed files with 141 additions and 11 deletions

View File

@ -1,3 +1,7 @@
2006-08-16 Soren Sandmann <sandmann@redhat.com>
* testelf.c: Really add this file.
2006-08-15 Soren Sandmann <sandmann@redhat.com>
Add beginning of an ELF parser.

View File

@ -78,6 +78,13 @@ read_varargs (va_list args,
static guint64
align (guint64 offset, int alignment)
{
/* Note that we can speed this up by assuming alignment'
* is a power of two, since
*
* offset % alignment == offset & (alignemnt - 1)
*
*/
if (offset % alignment != 0)
offset += (alignment - (offset % alignment));
@ -229,7 +236,9 @@ bin_parser_get_uint (BinParser *parser,
return r64;
}
#if 0
g_print ("width: %d\n", field->width);
#endif
g_assert_not_reached();
return 0;
@ -456,11 +465,13 @@ parse_elf (const guchar *data,
section_header = data + bin_parser_get_uint (parser, "e_shoff");
#if 0
g_print ("section header offset: %u\n",
section_header - data);
g_print ("There are %llu sections\n",
bin_parser_get_uint (parser, "e_shnum"));
#endif
/* should think through how to deal with offsets, and whether parsers
* are always considered parsers of an array. If yes, then it

View File

@ -117,9 +117,11 @@ find_elf_type (const guchar *data, gsize length,
return FALSE;
}
#if 0
g_print ("This elf file is %s %s\n",
*is_64? "64 bit" : "32 bit",
*is_be? "big endiann" : "little endian");
#endif
return TRUE;
}
@ -145,11 +147,13 @@ dump_symbol_table (ElfParser *parser,
return;
}
#if 0
g_print ("dumping symbol table at %d\n", offset);
#endif
bin_parser_begin (parser->parser, parser->sym_format, offset);
for (i = 0; i < 200; ++i)
for (i = 0; i < 2000; ++i)
{
guint64 idx;
@ -157,6 +161,8 @@ dump_symbol_table (ElfParser *parser,
idx = bin_parser_get_uint (parser->parser, "st_name");
const char *result;
gsize size;
gulong addr;
guint info;
#if 0
g_print ("addr: %p\n", bin_parser_get_address (parser->parser, "st_name"));
@ -166,16 +172,22 @@ dump_symbol_table (ElfParser *parser,
#endif
size = bin_parser_get_uint (parser->parser, "st_size");
bin_parser_begin (parser->parser,
NULL, parser->str_table + idx);
result = bin_parser_get_string (parser->parser);
info = bin_parser_get_uint (parser->parser, "st_info");
bin_parser_end (parser->parser);
g_print ("%d symbol: size: %d, %s.\n",
i, size, result);
if (info == STT_FUNC)
{
addr = bin_parser_get_uint (parser->parser, "st_value");
bin_parser_begin (parser->parser,
NULL, parser->str_table + idx);
result = bin_parser_get_string (parser->parser);
bin_parser_end (parser->parser);
g_print ("%d %p: symbol: size: %d, %s\n",
i, (void *)addr, size, result);
}
}
bin_parser_end (parser->parser);
@ -223,7 +235,7 @@ elf_parser_new (const guchar *data, gsize length)
{
const char *name;
int offset;
bin_parser_index (parser->parser, i);
offset = bin_parser_get_uint (parser->parser, "sh_name");
name = elf_lookup_string (parser, offset);
@ -378,11 +390,80 @@ find_section (ElfParser *parser,
out:
bin_parser_end (bparser);
#if 0
g_print ("found %s at %d\n", name, result);
#endif
return result;
}
static gboolean
check_symbol (ElfParser *parser,
int index,
gulong address)
{
bin_parser_index (parser, index);
/* FIXME */
return FALSE;
}
void
lookup_function_symbol (ElfParser *parser,
int begin,
int end,
gulong address)
{
g_assert (end - begin > 0);
if (end - begin < 10)
{
int i;
for (i = 0; i < end - begin; ++i)
{
bin_parser_index (parser, i);
if (check_symbol (parser, i, address))
return;
}
}
else
{
int mid1 = (end - begin) / 2;
int mid2 = ((end - begin) / 2 - 1);
while (mid1 >= begin &&
mid2 < end)
{
/*
if mid1 is a function,
then check the address.
if higher than input address,
recurse on (begin, mid1).
else
recurse on (mid2 - 1, end)
similar for mid2, only the other way around.
of course, if one of them matches
*/
if (check_symbol (parser, mid1, address))
return;
if (check_symbol (parser, mid2, address))
return;
mid1--;
mid2++;
}
}
}
const ElfSym *
elf_parser_lookup_symbol (ElfParser *parser,
gulong address)
@ -392,6 +473,16 @@ elf_parser_lookup_symbol (ElfParser *parser,
gssize dynsym_offset = find_section (parser, ".dynsym");
gssize dynstr_offset = find_section (parser, ".dynstr");
if (symtab_offset != -1 && strtab_offset != -1)
{
/* lookup in normal symbol table */
}
if (dynsym_offset != -1 && dynstr_offset != -1)
{
/* lookup in dynsym table */
}
return NULL;
}

24
testelf.c Normal file
View File

@ -0,0 +1,24 @@
#include <glib.h>
#include "elfparser.h"
int
main ()
{
int i;
GMappedFile *libgtk = g_mapped_file_new ("/usr/lib/libgtk-x11-2.0.so",
FALSE, NULL);
#if 0
for (i = 0; i < 50000; ++i)
#endif
{
ElfParser *elf = elf_parser_new (
g_mapped_file_get_contents (libgtk),
g_mapped_file_get_length (libgtk));
elf_parser_lookup_symbol (elf, 1000);
}
}