[sysprof] Eliminate more BinParser stuff



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]