Skip to content

Commit c6bce56

Browse files
committed
Remove memory allocation for ELF sections
* Since the section headers of ELF are continuous, all headers can be accessed by getting the starting address, so there is no need to allocate memory for this. * Eliminate MISRA C warnings as possible and follow contribution guide * Remove `getopt` and refactor `parse_args`, but the code is not elegant enough
1 parent c9f3dea commit c6bce56

File tree

3 files changed

+58
-90
lines changed

3 files changed

+58
-90
lines changed

src/elf.c

-31
Original file line numberDiff line numberDiff line change
@@ -355,37 +355,6 @@ bool elf_open(elf_t *e, const char *path)
355355
return true;
356356
}
357357

358-
struct Elf32_Shdr **get_elf_section_headers(elf_t *e)
359-
{
360-
struct Elf32_Ehdr *elf_hdr = (struct Elf32_Ehdr *) e->hdr;
361-
Elf32_Half shnum = elf_hdr->e_shnum;
362-
off_t offset = elf_hdr->e_shoff;
363-
uint8_t *buf = e->raw_data + offset;
364-
365-
struct Elf32_Shdr **shdrs = malloc(sizeof(struct Elf32_Shdr) * shnum);
366-
if (!shdrs)
367-
return NULL;
368-
369-
for (int i = 0; i < shnum; i++) {
370-
struct Elf32_Shdr *shdr = (struct Elf32_Shdr *) shdrs + i;
371-
struct Elf32_Shdr *_shdr =
372-
(struct Elf32_Shdr *) (buf + sizeof(struct Elf32_Shdr) * i);
373-
374-
shdr->sh_name = _shdr->sh_name;
375-
shdr->sh_type = _shdr->sh_type;
376-
shdr->sh_flags = _shdr->sh_flags;
377-
shdr->sh_addr = _shdr->sh_addr;
378-
shdr->sh_offset = _shdr->sh_offset;
379-
shdr->sh_size = _shdr->sh_size;
380-
shdr->sh_link = _shdr->sh_link;
381-
shdr->sh_info = _shdr->sh_info;
382-
shdr->sh_addralign = _shdr->sh_addralign;
383-
shdr->sh_entsize = _shdr->sh_entsize;
384-
}
385-
386-
return shdrs;
387-
}
388-
389358
struct Elf32_Ehdr *get_elf_header(elf_t *e)
390359
{
391360
return (struct Elf32_Ehdr *) e->hdr;

src/elf.h

-3
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,3 @@ struct Elf32_Ehdr *get_elf_header(elf_t *e);
152152

153153
/* get the first byte of ELF raw data */
154154
uint8_t *get_elf_first_byte(elf_t *e);
155-
156-
/* get all of the ELF section headers */
157-
struct Elf32_Shdr **get_elf_section_headers(elf_t *e);

tools/rv_histogram.c

+58-56
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* "LICENSE" for information on usage and redistribution of this file.
44
*/
55

6-
#include <getopt.h>
76
#include <stdio.h>
87
#include <stdlib.h>
98
#include <string.h>
@@ -18,15 +17,12 @@
1817
#include "decode.h"
1918
#include "elf.h"
2019

21-
typedef void (*hist_record_handler)(rv_insn_t *);
20+
typedef void (*hist_record_handler)(const rv_insn_t *);
2221

2322
static bool ascending_order = false;
2423
static bool show_reg = false;
2524
static const char *elf_prog = NULL;
2625

27-
hist_record_handler hist_record;
28-
static const char *insn_reg;
29-
static size_t freq;
3026
static size_t max_freq = 0;
3127
static size_t total_freq = 0;
3228
static unsigned short max_col;
@@ -92,17 +88,17 @@ static unsigned short get_used_col()
9288
{
9389
unsigned short used_col = 0;
9490

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

107103
return used_col;
108104
}
@@ -145,38 +141,47 @@ static void print_usage(const char *filename)
145141
filename);
146142
}
147143

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[])
149146
{
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;
163168
}
169+
/* set the executable */
170+
elf_prog = arg;
164171
}
165172

166-
elf_prog = args[optind];
167-
168-
return true;
173+
return ret;
169174
}
170175

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)
172177
{
173178
char hist_bar[max_col * 3 + 1];
174179
float percent;
175180
size_t idx = 1;
176181

177182
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;
180185

181186
percent = ((float) freq / total_freq) * 100;
182187
if (percent < 1.00)
@@ -189,7 +194,7 @@ void print_hist_stats(const rv_hist_t *stats, size_t stats_size)
189194
}
190195
}
191196

192-
void reg_hist_incr(rv_insn_t *ir)
197+
static void reg_hist_incr(const rv_insn_t *ir)
193198
{
194199
if (!ir)
195200
return;
@@ -214,7 +219,7 @@ void reg_hist_incr(rv_insn_t *ir)
214219
}
215220
}
216221

217-
void insn_hist_incr(rv_insn_t *ir)
222+
static void insn_hist_incr(const rv_insn_t *ir)
218223
{
219224
if (!ir) {
220225
rv_insn_stats[N_RV_INSNS].freq++;
@@ -224,15 +229,15 @@ void insn_hist_incr(rv_insn_t *ir)
224229
total_freq++;
225230
}
226231

227-
int main(int argc, char *args[])
232+
int main(int argc, const char *args[])
228233
{
229234
if (!parse_args(argc, args) || !elf_prog) {
230235
print_usage(args[0]);
231236
return 1;
232237
}
233238

234239
/* 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;
236241

237242
elf_t *e = elf_new();
238243
if (!elf_open(e, elf_prog)) {
@@ -241,39 +246,37 @@ int main(int argc, char *args[])
241246
}
242247

243248
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];
249252

250-
uintptr_t *elf_first_byte = (uintptr_t *) get_elf_first_byte(e);
251253
rv_insn_t ir;
252254
bool res;
253255

254256
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;
256260

257-
if (!(shdr->sh_type & SHT_PROGBITS && shdr->sh_flags & SHF_EXECINSTR))
261+
if (!(is_prg && has_insn))
258262
continue;
259263

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;
265267
uint32_t insn;
266268

267269
while (ptr < exec_end_addr) {
268270
#if RV32_HAS(EXT_C)
269271
if ((*((uint32_t *) ptr) & FC_OPCODE) != 0x3) {
270272
insn = *((uint16_t *) ptr);
271-
ptr = (uintptr_t *) ((uint8_t *) ptr + 2);
273+
ptr += 2;
272274
goto decode;
273275
}
274276
#endif
275277
insn = *((uint32_t *) ptr);
276-
ptr = (uintptr_t *) ((uint8_t *) ptr + 4);
278+
ptr += 4;
279+
277280

278281
#if RV32_HAS(EXT_C)
279282
decode:
@@ -312,7 +315,6 @@ int main(int argc, char *args[])
312315
print_hist_stats(rv_insn_stats, N_RV_INSNS + 1);
313316
}
314317

315-
free(shdrs);
316318
elf_delete(e);
317319

318320
return 0;

0 commit comments

Comments
 (0)