[sysprof] Eliminate more BinParser stuff
- From: Søren Sandmann Pedersen <ssp src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [sysprof] Eliminate more BinParser stuff
- Date: Fri, 9 Oct 2009 00:32:53 +0000 (UTC)
commit ca14021fb357ca69e2cb2c25b535ba90ce44b2de
Author: Søren Sandmann Pedersen <ssp redhat com>
Date: Thu Oct 8 19:17:24 2009 -0400
Eliminate more BinParser stuff
elfparser.c | 154 +++++++++++++++++++++++++++--------------------------------
1 files changed, 70 insertions(+), 84 deletions(-)
---
diff --git a/elfparser.c b/elfparser.c
index cab917d..9513c63 100644
--- a/elfparser.c
+++ b/elfparser.c
@@ -26,6 +26,7 @@ typedef struct Section Section;
struct ElfSym
{
+ gulong table;
gulong offset;
gulong address;
};
@@ -75,13 +76,27 @@ static gboolean parse_elf_signature (const guchar *data, gsize length,
gboolean *is_64, gboolean *is_be);
static void make_formats (ElfParser *parser, gboolean is_64);
+/* FIXME: All of these should in principle do endian swapping,
+ * but sysprof never has to deal with binaries of a different
+ * endianness than sysprof itself
+ */
+#define GET_FIELD(parser, offset, struct_name, idx, field_name) \
+ (((parser))->is_64? \
+ ((Elf64_ ## struct_name *)(((parser)->data + offset)) + (idx))->field_name : \
+ ((Elf32_ ## struct_name *)(((parser)->data + offset)) + (idx))->field_name)
+
+#define GET_UINT32(parser, offset) \
+ *((uint32_t *)(parser->data + offset)) \
+
+#define GET_SIZE(parser, struct_name) \
+ (((parser)->is_64? \
+ sizeof (Elf64_ ## struct_name) : \
+ sizeof (Elf32_ ## struct_name)))
+
#define MAKE_ELF_UINT_ACCESSOR(field_name) \
static uint64_t field_name (ElfParser *parser) \
{ \
- if (parser->is_64) \
- return ((Elf64_Ehdr *)parser->data)->field_name; \
- else \
- return ((Elf32_Ehdr *)parser->data)->field_name; \
+ return GET_FIELD (parser, 0, Ehdr, 0, field_name); \
}
MAKE_ELF_UINT_ACCESSOR (e_type)
@@ -101,11 +116,9 @@ MAKE_ELF_UINT_ACCESSOR (e_shstrndx)
#define MAKE_SECTION_HEADER_ACCESSOR(field_name) \
static uint64_t field_name (ElfParser *parser, int nth_section) \
{ \
- const char *data = parser->data + e_shoff (parser); \
- if (parser->is_64) \
- return (((Elf64_Shdr *)data) + nth_section)->field_name; \
- else \
- return (((Elf32_Shdr *)data) + nth_section)->field_name; \
+ gsize offset = e_shoff (parser); \
+ \
+ return GET_FIELD (parser, offset, Shdr, nth_section, field_name); \
}
MAKE_SECTION_HEADER_ACCESSOR (sh_name);
@@ -120,39 +133,17 @@ MAKE_SECTION_HEADER_ACCESSOR (sh_addralign);
MAKE_SECTION_HEADER_ACCESSOR (sh_entsize);
#define MAKE_SYMBOL_ACCESSOR(field_name) \
- static uint64_t field_name (ElfParser *parser, gsize offset) \
+ static uint64_t field_name (ElfParser *parser, gulong offset, gulong nth) \
{ \
- const char *data = parser->data + offset; \
- if (parser->is_64) \
- return (((Elf64_Sym *)data)->field_name); \
- else \
- return (((Elf32_Sym *)data)->field_name); \
+ return GET_FIELD (parser, offset, Sym, nth, field_name); \
}
MAKE_SYMBOL_ACCESSOR(st_name);
-
-
-static const char *
-get_string_indirect (BinParser *parser,
- BinRecord *record,
- const char *name,
- gsize str_table)
-{
- const char *result = NULL;
- gsize index;
-
- bin_parser_save (parser);
-
- index = bin_parser_get_uint_field (parser, record, name);
-
- bin_parser_set_offset (parser, str_table + index);
-
- result = bin_parser_get_string (parser);
-
- bin_parser_restore (parser);
-
- return result;
-}
+MAKE_SYMBOL_ACCESSOR(st_info);
+MAKE_SYMBOL_ACCESSOR(st_value);
+MAKE_SYMBOL_ACCESSOR(st_size);
+MAKE_SYMBOL_ACCESSOR(st_other);
+MAKE_SYMBOL_ACCESSOR(st_shndx);
static void
section_free (Section *section)
@@ -487,8 +478,6 @@ read_table (ElfParser *parser,
g_print ("sym table offset: %d\n", sym_table->offset);
#endif
- bin_parser_set_offset (parser->parser, sym_table->offset);
-
n_symbols = 0;
#if 0
g_print ("n syms: %d\n", parser->n_symbols);
@@ -497,16 +486,11 @@ read_table (ElfParser *parser,
{
guint info;
gulong addr;
- gulong offset;
gulong shndx;
-
- info = bin_parser_get_uint_field (
- parser->parser, parser->sym_format, "st_info");
- addr = bin_parser_get_uint_field (
- parser->parser, parser->sym_format, "st_value");
- shndx = bin_parser_get_uint_field (
- parser->parser, parser->sym_format, "st_shndx");
- offset = bin_parser_get_offset (parser->parser);
+
+ info = st_info (parser, sym_table->offset, i);
+ addr = st_value (parser, sym_table->offset, i);
+ shndx = st_shndx (parser, sym_table->offset, i);
#if 0
g_print ("read symbol: %s (section: %d)\n", get_string_indirct (parser->parser,
@@ -518,14 +502,14 @@ read_table (ElfParser *parser,
if (addr != 0 &&
shndx < parser->n_sections &&
parser->sections[shndx] == parser->text_section &&
- (info & 0xf) == STT_FUNC &&
+ (info & 0xf) == STT_FUNC &&
((info >> 4) == STB_GLOBAL ||
(info >> 4) == STB_LOCAL ||
- (info >> 4) == STB_WEAK)
- )
+ (info >> 4) == STB_WEAK))
{
parser->symbols[n_symbols].address = addr;
- parser->symbols[n_symbols].offset = offset;
+ parser->symbols[n_symbols].table = sym_table->offset;
+ parser->symbols[n_symbols].offset = i;
n_symbols++;
@@ -546,8 +530,6 @@ read_table (ElfParser *parser,
addr, parser, info & 0xf, info >> 4, STT_FUNC, STB_GLOBAL);
#endif
}
-
- bin_parser_seek_record (parser->parser, parser->sym_format, 1);
}
parser->sym_strings = str_table->offset;
@@ -667,12 +649,7 @@ elf_parser_lookup_symbol (ElfParser *parser,
if (result)
{
- gulong size;
-
- bin_parser_set_offset (parser->parser, result->offset);
-
- size = bin_parser_get_uint_field (
- parser->parser, parser->sym_format, "st_size");
+ gulong size = st_size (parser, result->table, result->offset);
if (size > 0 && result->address + size <= address)
{
@@ -731,32 +708,37 @@ elf_parser_get_build_id (ElfParser *parser)
{
if (!parser->checked_build_id)
{
- const Section *build_id = find_section (parser, ".note.gnu.build-id", SHT_NOTE);
+ const Section *build_id =
+ find_section (parser, ".note.gnu.build-id", SHT_NOTE);
guint64 name_size;
guint64 desc_size;
guint64 type;
const char *name;
- const gchar *desc;
+ guint64 offset;
parser->checked_build_id = TRUE;
if (!build_id)
return NULL;
-
- bin_parser_set_offset (parser->parser, build_id->offset);
-
- name_size = bin_parser_get_uint_field (parser->parser, parser->note_format, "name_size");
- desc_size = bin_parser_get_uint_field (parser->parser, parser->note_format, "desc_size");
- type = bin_parser_get_uint_field (parser->parser, parser->note_format, "type");
- bin_parser_seek_record (parser->parser, parser->note_format, 1);
- name = bin_parser_get_string (parser->parser);
+ offset = build_id->offset;
+
+ name_size = GET_FIELD (parser, offset, Nhdr, 0, n_namesz);
+ desc_size = GET_FIELD (parser, offset, Nhdr, 0, n_descsz);
+ type = GET_FIELD (parser, offset, Nhdr, 0, n_type);
- bin_parser_align (parser->parser, 4);
+ offset += GET_SIZE (parser, Nhdr);
+
+ name = parser->data + offset;
- desc = bin_parser_get_string (parser->parser);
+ if (strncmp (name, ELF_NOTE_GNU, name_size) != 0 || type != NT_GNU_BUILD_ID)
+ return NULL;
+
+ offset += strlen (parser->data + offset);
- parser->build_id = make_hex_string (desc, desc_size);
+ offset = (offset + 3) & (~0x3);
+
+ parser->build_id = make_hex_string (parser->data + offset, desc_size);
}
return parser->build_id;
@@ -765,21 +747,24 @@ elf_parser_get_build_id (ElfParser *parser)
const char *
elf_parser_get_debug_link (ElfParser *parser, guint32 *crc32)
{
+ guint64 offset;
const Section *debug_link = find_section (parser, ".gnu_debuglink",
SHT_PROGBITS);
const gchar *result;
if (!debug_link)
return NULL;
+
+ offset = debug_link->offset;
- bin_parser_set_offset (parser->parser, debug_link->offset);
-
- result = bin_parser_get_string (parser->parser);
-
- bin_parser_align (parser->parser, 4);
-
+ result = parser->data + offset;
+
if (crc32)
- *crc32 = bin_parser_get_uint (parser->parser, 4);
+ {
+ offset = (offset + 3) & ~0x3;
+
+ *crc32 = GET_UINT32 (parser, offset);
+ }
return result;
}
@@ -789,9 +774,9 @@ get_section (ElfParser *parser,
const char *name)
{
const Section *section = find_section (parser, name, SHT_PROGBITS);
-
+
if (section)
- return bin_parser_get_data (parser->parser) + section->offset;
+ return parser->data + section->offset;
else
return NULL;
}
@@ -814,7 +799,8 @@ elf_parser_get_sym_name (ElfParser *parser,
{
g_return_val_if_fail (parser != NULL, NULL);
- return (char *)(parser->data + parser->sym_strings + st_name (parser, sym->offset));
+ return (char *)(parser->data + parser->sym_strings +
+ st_name (parser, sym->table, sym->offset));
}
gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]