summaryrefslogtreecommitdiff
path: root/src/minibfd/binparser.h
blob: a642f864d89508271a1013f695947b89dc5eb912 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
   This file is part of odin, a memory profiler with fragmentation analysis.

   Copyright (C) 2007 Chris Wilson <chris@chris-wilson.co.uk>

   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 <http://www.gnu.org/licenses/>/

   The GNU General Public License is contained in the file COPYING.
*/

#ifndef BINPARSER_H
#define BINPARSER_H

#include <glib.h>

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 */