mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +00:00
Really add this file.
2006-08-16 Soren Sandmann <sandmann@redhat.com> * testelf.c: Really add this file.
This commit is contained in:
committed by
Søren Sandmann Pedersen
parent
2bc2e3658d
commit
1f4dd13cd3
@ -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>
|
2006-08-15 Soren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
Add beginning of an ELF parser.
|
Add beginning of an ELF parser.
|
||||||
|
|||||||
11
binparser.c
11
binparser.c
@ -78,6 +78,13 @@ read_varargs (va_list args,
|
|||||||
static guint64
|
static guint64
|
||||||
align (guint64 offset, int alignment)
|
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)
|
if (offset % alignment != 0)
|
||||||
offset += (alignment - (offset % alignment));
|
offset += (alignment - (offset % alignment));
|
||||||
|
|
||||||
@ -229,7 +236,9 @@ bin_parser_get_uint (BinParser *parser,
|
|||||||
return r64;
|
return r64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
g_print ("width: %d\n", field->width);
|
g_print ("width: %d\n", field->width);
|
||||||
|
#endif
|
||||||
|
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
return 0;
|
return 0;
|
||||||
@ -456,11 +465,13 @@ parse_elf (const guchar *data,
|
|||||||
|
|
||||||
section_header = data + bin_parser_get_uint (parser, "e_shoff");
|
section_header = data + bin_parser_get_uint (parser, "e_shoff");
|
||||||
|
|
||||||
|
#if 0
|
||||||
g_print ("section header offset: %u\n",
|
g_print ("section header offset: %u\n",
|
||||||
section_header - data);
|
section_header - data);
|
||||||
|
|
||||||
g_print ("There are %llu sections\n",
|
g_print ("There are %llu sections\n",
|
||||||
bin_parser_get_uint (parser, "e_shnum"));
|
bin_parser_get_uint (parser, "e_shnum"));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* should think through how to deal with offsets, and whether parsers
|
/* should think through how to deal with offsets, and whether parsers
|
||||||
* are always considered parsers of an array. If yes, then it
|
* are always considered parsers of an array. If yes, then it
|
||||||
|
|||||||
113
elfparser.c
113
elfparser.c
@ -117,9 +117,11 @@ find_elf_type (const guchar *data, gsize length,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
g_print ("This elf file is %s %s\n",
|
g_print ("This elf file is %s %s\n",
|
||||||
*is_64? "64 bit" : "32 bit",
|
*is_64? "64 bit" : "32 bit",
|
||||||
*is_be? "big endiann" : "little endian");
|
*is_be? "big endiann" : "little endian");
|
||||||
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -145,11 +147,13 @@ dump_symbol_table (ElfParser *parser,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
g_print ("dumping symbol table at %d\n", offset);
|
g_print ("dumping symbol table at %d\n", offset);
|
||||||
|
#endif
|
||||||
|
|
||||||
bin_parser_begin (parser->parser, parser->sym_format, offset);
|
bin_parser_begin (parser->parser, parser->sym_format, offset);
|
||||||
|
|
||||||
for (i = 0; i < 200; ++i)
|
for (i = 0; i < 2000; ++i)
|
||||||
{
|
{
|
||||||
guint64 idx;
|
guint64 idx;
|
||||||
|
|
||||||
@ -157,6 +161,8 @@ dump_symbol_table (ElfParser *parser,
|
|||||||
idx = bin_parser_get_uint (parser->parser, "st_name");
|
idx = bin_parser_get_uint (parser->parser, "st_name");
|
||||||
const char *result;
|
const char *result;
|
||||||
gsize size;
|
gsize size;
|
||||||
|
gulong addr;
|
||||||
|
guint info;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
g_print ("addr: %p\n", bin_parser_get_address (parser->parser, "st_name"));
|
g_print ("addr: %p\n", bin_parser_get_address (parser->parser, "st_name"));
|
||||||
@ -166,16 +172,22 @@ dump_symbol_table (ElfParser *parser,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
size = bin_parser_get_uint (parser->parser, "st_size");
|
size = bin_parser_get_uint (parser->parser, "st_size");
|
||||||
|
info = bin_parser_get_uint (parser->parser, "st_info");
|
||||||
bin_parser_begin (parser->parser,
|
|
||||||
NULL, parser->str_table + idx);
|
|
||||||
|
|
||||||
result = bin_parser_get_string (parser->parser);
|
|
||||||
|
|
||||||
bin_parser_end (parser->parser);
|
if (info == STT_FUNC)
|
||||||
|
{
|
||||||
g_print ("%d symbol: size: %d, %s.\n",
|
addr = bin_parser_get_uint (parser->parser, "st_value");
|
||||||
i, size, result);
|
|
||||||
|
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);
|
bin_parser_end (parser->parser);
|
||||||
@ -223,7 +235,7 @@ elf_parser_new (const guchar *data, gsize length)
|
|||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
bin_parser_index (parser->parser, i);
|
bin_parser_index (parser->parser, i);
|
||||||
offset = bin_parser_get_uint (parser->parser, "sh_name");
|
offset = bin_parser_get_uint (parser->parser, "sh_name");
|
||||||
name = elf_lookup_string (parser, offset);
|
name = elf_lookup_string (parser, offset);
|
||||||
@ -378,11 +390,80 @@ find_section (ElfParser *parser,
|
|||||||
out:
|
out:
|
||||||
bin_parser_end (bparser);
|
bin_parser_end (bparser);
|
||||||
|
|
||||||
|
#if 0
|
||||||
g_print ("found %s at %d\n", name, result);
|
g_print ("found %s at %d\n", name, result);
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
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 *
|
const ElfSym *
|
||||||
elf_parser_lookup_symbol (ElfParser *parser,
|
elf_parser_lookup_symbol (ElfParser *parser,
|
||||||
gulong address)
|
gulong address)
|
||||||
@ -392,6 +473,16 @@ elf_parser_lookup_symbol (ElfParser *parser,
|
|||||||
gssize dynsym_offset = find_section (parser, ".dynsym");
|
gssize dynsym_offset = find_section (parser, ".dynsym");
|
||||||
gssize dynstr_offset = find_section (parser, ".dynstr");
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
24
testelf.c
Normal file
24
testelf.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user