/* This file is part of odin, a memory profiler with fragmentation analysis. Copyright (C) 2007 Chris Wilson Based on: Sysprof -- Sampling, systemwide CPU profiler Copyright 2006, 2007, Soeren Sandmann odin is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. odin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with odin. If not, see / The GNU General Public License is contained in the file COPYING. */ #ifndef BINPARSER_H #define BINPARSER_H #include G_BEGIN_DECLS typedef struct _bin_parser BinParser; typedef struct _bin_record BinRecord; typedef struct _bin_field BinField; /* The model is: * * BinParser has an offset associated with it. This offset can be * manipulated with methods * * goto - go to absolute position from file start * goto_rel - go to relative positio * goto_record_rel - skip the given number of records * align - move forward until aligned to given width * save/restore - save/restore the current offset (stack) * * and queried with * * get_offset - return current offset in bytes from start * * data can be retrieved with * * get_uint - return a uint of given width, and skip * get_string - return a null terminated stringm, and skip * get_pstring - return a 'pascal' string with given length * * get_uint_field - return the named field * * formats should probably be definable as static data. * */ typedef enum { BIN_LITTLE_ENDIAN, BIN_BIG_ENDIAN, BIN_NATIVE_ENDIAN } BinEndian; typedef enum { /* More types can (and probably will) be added in the future */ BIN_UINT, BIN_UNINTERPRETED } BinType; struct _bin_field { short index; char type; char n_bytes; /* number of bytes in the type */ }; struct _bin_parser { const guchar *data; gsize length; gsize offset; BinRecord *records; BinEndian endian; gsize saved_offset; }; void bin_parser_init (BinParser *parser, const guchar *data, gsize length); void bin_parser_fini (BinParser *parser); const guchar *bin_parser_get_data (BinParser *parser); gsize bin_parser_get_length (BinParser *parser); void bin_parser_set_endian (BinParser *parser, BinEndian endian); gboolean bin_parser_error (BinParser *parser); void bin_parser_clear_error (BinParser *parser); const gchar * bin_parser_get_error_msg (BinParser *parser); /* field idents */ enum { e_ident = 0, e_type, e_machine, e_version, e_entry, e_phoff, e_shoff, e_flags, e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx }; enum { sh_name = 0, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link, sh_info, sh_addralign, sh_entsize }; enum { st_name = 0, st_info, st_other, st_shndx, st_value, st_size }; BinRecord * bin_parser_create_record (BinParser *parser, const BinField *fields); gsize bin_record_get_size (BinRecord *record); guint64 bin_parser_get_uint_field (BinParser *parser, BinRecord *record, int field_ident); /* Move current offset */ gsize bin_parser_get_offset (BinParser *parser); void bin_parser_set_offset (BinParser *parser, gsize offset); void bin_parser_align (BinParser *parser, gsize byte_width); void bin_parser_seek_record (BinParser *parser, BinRecord *record, int n_records); void bin_parser_save (BinParser *parser); void bin_parser_restore (BinParser *parser); void bin_parser_advance (BinParser *parser, gint64 offset); /* retrieve data */ guint64 bin_parser_get_uint (BinParser *parser, int width); guint64 bin_parser_get_uleb128 (BinParser *parser); gint64 bin_parser_get_sleb128 (BinParser *parser); const char * bin_parser_get_string (BinParser *parser); G_END_DECLS #endif /* BINPARSER_H */