3
3
* "LICENSE" for information on usage and redistribution of this file.
4
4
*/
5
5
6
- #include <getopt.h>
7
6
#include <stdio.h>
8
7
#include <stdlib.h>
9
8
#include <string.h>
18
17
#include "decode.h"
19
18
#include "elf.h"
20
19
21
- typedef void (* hist_record_handler )(rv_insn_t * );
20
+ typedef void (* hist_record_handler )(const rv_insn_t * );
22
21
23
22
static bool ascending_order = false;
24
23
static bool show_reg = false;
25
24
static const char * elf_prog = NULL ;
26
25
27
- hist_record_handler hist_record ;
28
- static const char * insn_reg ;
29
- static size_t freq ;
30
26
static size_t max_freq = 0 ;
31
27
static size_t total_freq = 0 ;
32
28
static unsigned short max_col ;
@@ -92,17 +88,17 @@ static unsigned short get_used_col()
92
88
{
93
89
unsigned short used_col = 0 ;
94
90
95
- used_col += 3 ; /* width = 3 */
96
- used_col += 1 ; /* . */
97
- used_col += 1 ; /* single space */
98
- used_col += 10 ; /* width = 10 */
99
- used_col += 5 ; /* width = 5 */
100
- used_col += 1 ; /* % */
101
- used_col += 1 ; /* single space */
102
- used_col += 1 ; /* [ */
103
- used_col += 10 ; /* width = 10 */
104
- used_col += 1 ; /* ] */
105
- used_col += 1 ; /* single space */
91
+ used_col += 3u ; /* width = 3 */
92
+ used_col += 1u ; /* . */
93
+ used_col += 1u ; /* single space */
94
+ used_col += 10u ; /* width = 10 */
95
+ used_col += 5u ; /* width = 5 */
96
+ used_col += 1u ; /* % */
97
+ used_col += 1u ; /* single space */
98
+ used_col += 1u ; /* [ */
99
+ used_col += 10u ; /* width = 10 */
100
+ used_col += 1u ; /* ] */
101
+ used_col += 1u ; /* single space */
106
102
107
103
return used_col ;
108
104
}
@@ -145,38 +141,47 @@ static void print_usage(const char *filename)
145
141
filename );
146
142
}
147
143
148
- static bool parse_args (int argc , char * * args )
144
+ /* FIXME: refactor to elegant code */
145
+ static bool parse_args (int argc , const char * args [])
149
146
{
150
- const char * optstr = "ar" ;
151
- int opt ;
152
-
153
- while ((opt = getopt (argc , args , optstr )) != -1 ) {
154
- switch (opt ) {
155
- case 'a' :
156
- ascending_order = true;
157
- break ;
158
- case 'r' :
159
- show_reg = true;
160
- break ;
161
- default :
162
- return false;
147
+ bool ret = true;
148
+ for (int i = 1 ; (i < argc ) && ret ; i ++ ) {
149
+ const char * arg = args [i ];
150
+ if (arg [0 ] == '-' ) {
151
+ if (strstr (arg , "-ar" ) || strstr (arg , "-ra" )) {
152
+ ascending_order = true;
153
+ show_reg = true;
154
+ continue ;
155
+ }
156
+
157
+ if (!strcmp (arg , "-a" )) {
158
+ ascending_order = true;
159
+ continue ;
160
+ }
161
+
162
+ if (!strcmp (arg , "-r" )) {
163
+ show_reg = true;
164
+ continue ;
165
+ }
166
+
167
+ ret = false;
163
168
}
169
+ /* set the executable */
170
+ elf_prog = arg ;
164
171
}
165
172
166
- elf_prog = args [optind ];
167
-
168
- return true;
173
+ return ret ;
169
174
}
170
175
171
- void print_hist_stats (const rv_hist_t * stats , size_t stats_size )
176
+ static void print_hist_stats (const rv_hist_t * stats , size_t stats_size )
172
177
{
173
178
char hist_bar [max_col * 3 + 1 ];
174
179
float percent ;
175
180
size_t idx = 1 ;
176
181
177
182
for (size_t i = 0 ; i < stats_size ; i ++ ) {
178
- insn_reg = stats [i ].insn_reg ;
179
- freq = stats [i ].freq ;
183
+ const char * insn_reg = stats [i ].insn_reg ;
184
+ size_t freq = stats [i ].freq ;
180
185
181
186
percent = ((float ) freq / total_freq ) * 100 ;
182
187
if (percent < 1.00 )
@@ -189,7 +194,7 @@ void print_hist_stats(const rv_hist_t *stats, size_t stats_size)
189
194
}
190
195
}
191
196
192
- void reg_hist_incr (rv_insn_t * ir )
197
+ static void reg_hist_incr (const rv_insn_t * ir )
193
198
{
194
199
if (!ir )
195
200
return ;
@@ -214,7 +219,7 @@ void reg_hist_incr(rv_insn_t *ir)
214
219
}
215
220
}
216
221
217
- void insn_hist_incr (rv_insn_t * ir )
222
+ static void insn_hist_incr (const rv_insn_t * ir )
218
223
{
219
224
if (!ir ) {
220
225
rv_insn_stats [N_RV_INSNS ].freq ++ ;
@@ -224,15 +229,15 @@ void insn_hist_incr(rv_insn_t *ir)
224
229
total_freq ++ ;
225
230
}
226
231
227
- int main (int argc , char * args [])
232
+ int main (int argc , const char * args [])
228
233
{
229
234
if (!parse_args (argc , args ) || !elf_prog ) {
230
235
print_usage (args [0 ]);
231
236
return 1 ;
232
237
}
233
238
234
239
/* resolver of histogram accounting */
235
- hist_record = show_reg ? reg_hist_incr : insn_hist_incr ;
240
+ hist_record_handler hist_record = show_reg ? reg_hist_incr : insn_hist_incr ;
236
241
237
242
elf_t * e = elf_new ();
238
243
if (!elf_open (e , elf_prog )) {
@@ -241,39 +246,37 @@ int main(int argc, char *args[])
241
246
}
242
247
243
248
struct Elf32_Ehdr * hdr = get_elf_header (e );
244
- struct Elf32_Shdr * * shdrs = get_elf_section_headers (e );
245
- if (!shdrs ) {
246
- fprintf (stderr , "malloc for section headers failed\n" );
247
- return 1 ;
248
- }
249
+ uint8_t * elf_first_byte = get_elf_first_byte (e );
250
+ const struct Elf32_Shdr * * shdrs =
251
+ (const struct Elf32_Shdr * * ) & elf_first_byte [hdr -> e_shoff ];
249
252
250
- uintptr_t * elf_first_byte = (uintptr_t * ) get_elf_first_byte (e );
251
253
rv_insn_t ir ;
252
254
bool res ;
253
255
254
256
for (int i = 0 ; i < hdr -> e_shnum ; i ++ ) {
255
- struct Elf32_Shdr * shdr = (struct Elf32_Shdr * ) shdrs + i ;
257
+ const struct Elf32_Shdr * shdr = (const struct Elf32_Shdr * ) & shdrs [i ];
258
+ bool is_prg = shdr -> sh_type & SHT_PROGBITS ;
259
+ bool has_insn = shdr -> sh_flags & SHF_EXECINSTR ;
256
260
257
- if (!(shdr -> sh_type & SHT_PROGBITS && shdr -> sh_flags & SHF_EXECINSTR ))
261
+ if (!(is_prg && has_insn ))
258
262
continue ;
259
263
260
- uintptr_t * exec_start_addr =
261
- (uintptr_t * ) ((uint8_t * ) elf_first_byte + shdr -> sh_offset );
262
- uintptr_t * exec_end_addr =
263
- (uintptr_t * ) ((uint8_t * ) exec_start_addr + shdr -> sh_size );
264
- uintptr_t * ptr = (uintptr_t * ) exec_start_addr ;
264
+ uint8_t * exec_start_addr = & elf_first_byte [shdr -> sh_offset ];
265
+ const uint8_t * exec_end_addr = & exec_start_addr [shdr -> sh_size ];
266
+ uint8_t * ptr = exec_start_addr ;
265
267
uint32_t insn ;
266
268
267
269
while (ptr < exec_end_addr ) {
268
270
#if RV32_HAS (EXT_C )
269
271
if ((* ((uint32_t * ) ptr ) & FC_OPCODE ) != 0x3 ) {
270
272
insn = * ((uint16_t * ) ptr );
271
- ptr = ( uintptr_t * ) (( uint8_t * ) ptr + 2 ) ;
273
+ ptr += 2 ;
272
274
goto decode ;
273
275
}
274
276
#endif
275
277
insn = * ((uint32_t * ) ptr );
276
- ptr = (uintptr_t * ) ((uint8_t * ) ptr + 4 );
278
+ ptr += 4 ;
279
+
277
280
278
281
#if RV32_HAS (EXT_C )
279
282
decode :
@@ -312,7 +315,6 @@ int main(int argc, char *args[])
312
315
print_hist_stats (rv_insn_stats , N_RV_INSNS + 1 );
313
316
}
314
317
315
- free (shdrs );
316
318
elf_delete (e );
317
319
318
320
return 0 ;
0 commit comments