Skip to content

Commit 49bca22

Browse files
author
milo
committed
v.0.8.12 Decoder/Reader refactored + reduces memory usage.
1 parent 109560c commit 49bca22

File tree

68 files changed

+1080
-1060
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1080
-1060
lines changed

CHANGELOG.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
# Changelog
22

3-
# Unreleased
3+
# v.0.8.12 - 2021-08-10
4+
5+
- reduction of heap usage and overall memory usage
6+
- only 10 heap allocs needed to disassemble an intel hex file
7+
8+
- getting rid of basic integers in important sections
9+
- flash address is now represented as uint32_t
10+
- opcodes are (finally) represented as uint32_t
11+
- for more user relevant changes see libvmcu headers
12+
13+
- the disassembly is now sorted (ascending, sorted by address)
14+
- this change is mandatory for the cfg
15+
16+
- refactored decoder
17+
- decoder operates now on an intermediate representation (binary_buffer) of the binary
18+
19+
- added vmcu_binary_buffer_t (only for internal usage)
20+
- this serves as an intermediate representation for the decoder
21+
- every single format reader (reader/) should return a binary buffer
22+
23+
- refactored intel hex reader
424

525
- adjusted example section in README
626

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ int main(const int argc, const char **argv) {
6262
vmcu_model_t *m328p = vmcu_model_ctor(VMCU_DEVICE_M328P);
6363
vmcu_report_t *report = vmcu_analyze_ihex("file.hex", m328p);
6464

65-
for(int32_t i = 0; i < report->cfg->used; i++) {
65+
for(uint32_t i = 0; i < report->cfg->used; i++) {
6666
6767
vmcu_cfg_node_t *node = &report->cfg->node[i];
6868
print_instruction(node->xto.i);
@@ -131,7 +131,7 @@ int main(const int argc, const char **argv) {
131131
vmcu_model_t *m328p = vmcu_model_ctor(VMCU_DEVICE_M328P);
132132
vmcu_report_t *report = vmcu_analyze_ihex("file.hex", m328p);
133133

134-
for(int32_t i = 0; i < report->progsize; i++) {
134+
for(uint32_t i = 0; i < report->progsize; i++) {
135135

136136
printf("0x%04x ", report->disassembly[i].addr);
137137
print_instruction(&report->disassembly[i]);
@@ -165,7 +165,7 @@ int main(const int argc, const char **argv) {
165165
vmcu_model_t *m328p = vmcu_model_ctor(VMCU_DEVICE_M328P);
166166
vmcu_report_t *report = vmcu_analyze_ihex("file.hex", m328p);
167167

168-
for(int32_t i = 0; i < report->progsize; i++) {
168+
for(uint32_t i = 0; i < report->progsize; i++) {
169169

170170
vmcu_instr_t *instr = &report->disassembly[i];
171171
@@ -199,7 +199,7 @@ int main(const int argc, const char **argv) {
199199
vmcu_model_t *m328p = vmcu_model_ctor(VMCU_DEVICE_M328P);
200200
vmcu_report_t *report = vmcu_analyze_ihex("file.hex", m328p);
201201

202-
for(int32_t i = 0; i < report->n_vector; i++) {
202+
for(uint32_t i = 0; i < report->n_vector; i++) {
203203

204204
vmcu_vector_t *vect = &report->vector[i];
205205
vmcu_instr_t *isr = vect->xto->i;
@@ -241,12 +241,12 @@ int main(const int argc, const char **argv) {
241241
vmcu_model_t *m328p = vmcu_model_ctor(VMCU_DEVICE_M328P);
242242
vmcu_report_t *report = vmcu_analyze_ihex("file.hex", m328p);
243243

244-
for(int32_t i = 0; i < report->n_label; i++) {
244+
for(uint32_t i = 0; i < report->n_label; i++) {
245245

246246
vmcu_label_t *lx = &report->label[i];
247247
printf("0x%04x\tL%d\n\n", lx->addr, lx->id);
248248

249-
for(int32_t j = 0; j < lx->n_xfrom; j++) {
249+
for(uint32_t j = 0; j < lx->n_xfrom; j++) {
250250

251251
vmcu_xref_t *x = &lx->xfrom[j];
252252
@@ -291,12 +291,12 @@ int main(const int argc, const char **argv) {
291291
vmcu_model_t *m328p = vmcu_model_ctor(VMCU_DEVICE_M328P);
292292
vmcu_report_t *report = vmcu_analyze_ihex("file.hex", m328p);
293293

294-
for(int32_t i = 0; i < report->n_sfr; i++) {
294+
for(uint32_t i = 0; i < report->n_sfr; i++) {
295295

296296
vmcu_sfr_t *sfr = &report->sfr[i];
297297
printf("SFR ID: %d\n\n", sfr->id);
298298

299-
for(int32_t j = 0; j < sfr->n_xfrom; j++) {
299+
for(uint32_t j = 0; j < sfr->n_xfrom; j++) {
300300

301301
vmcu_xref_t *x = &sfr->xfrom[j];
302302

@@ -344,7 +344,7 @@ int main(const int argc, const char **argv) {
344344
const VMCU_GROUP grp = instr.group; // VMCU_GROUP_MATH_LOGIC
345345

346346
const uint32_t opcode = instr.opcode; // 0x976a (big endian)
347-
const uint16_t addr = instr.addr; // 0x0000 (undefined)
347+
const uint32_t addr = instr.addr; // 0x0000 (undefined)
348348

349349
const bool dword = instr.dword; // false
350350
const bool exec = instr.exec; // true

TODO.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ These are a some of my ideas for the future of libvmcu
44

55
/********************************* Features ***************************************/
66

7-
[0] controlflow graph (cfg)
8-
[0.1] requires slab allocator to minimize memory requests
9-
107
[1] McCabe's cyclomatic complexity
118
[1.1] requires controlflow graph, see [0]
129

@@ -37,9 +34,7 @@ These are a some of my ideas for the future of libvmcu
3734

3835
/********************************* Internal / Cleanup *****************************/
3936

40-
[11] sort instructions by address in disassembly (important)
41-
42-
[12] remove usage of basic integers (int) in libvmcu
37+
[12] remove usage of basic integers (int) in libvmcu (nearly done)
4338

4439
[13] adjust driver makefiles (debug recipe, add -g -o)
4540

driver/cfg/cfg.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ int main(const int argc, const char **argv) {
5757

5858
vmcu_cfg_t *cfg = report->cfg;
5959

60-
for(int32_t i = 0; i < cfg->used; i++) {
60+
for(uint32_t i = 0; i < cfg->used; i++) {
6161

6262
vmcu_cfg_node_t *node = &cfg->node[i];
6363

@@ -111,7 +111,7 @@ static void print_instruction(vmcu_instr_t *instr) {
111111

112112
static void print_instruction_details(vmcu_instr_t *instr) {
113113

114-
printf("0x%04x", instr->addr);
114+
printf("0x%04" PRIx32, instr->addr);
115115

116116
const uint16_t opcl = (instr->opcode & 0x0000ffff);
117117
const uint16_t swpl = (opcl >> 8) | (opcl << 8);
@@ -122,9 +122,9 @@ static void print_instruction_details(vmcu_instr_t *instr) {
122122
if(instr->dword == false)
123123
printf(" %s....%s ", COLOR_GREEN, COLOR_RESET);
124124
else
125-
printf(" %s%04x%s ", COLOR_GREEN, swph, COLOR_RESET);
125+
printf(" %s%04" PRIx16 "%s ", COLOR_GREEN, swph, COLOR_RESET);
126126

127-
printf("%s%04x%s ", COLOR_YELLOW, swpl, COLOR_RESET);
127+
printf("%s%04" PRIx16 "%s ", COLOR_YELLOW, swpl, COLOR_RESET);
128128
}
129129

130130
static void print_colored_base(const char *basestr, VMCU_GROUP group) {

driver/details/details.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ int main(const int argc, const char **argv) {
2525
return EXIT_FAILURE;
2626
}
2727

28-
const uint32_t opc = htoi(argv[1]);
29-
3028
vmcu_instr_t instr;
3129
vmcu_model_t *m328p = vmcu_model_ctor(VMCU_DEVICE_M328P);
3230

31+
const uint32_t opc = htoi(argv[1]);
32+
3333
if(vmcu_disassemble_bytes(opc, &instr, m328p) < 0) {
3434

3535
printf("Could not decode.\n");
@@ -50,8 +50,8 @@ static void print_instr(vmcu_instr_t *instr, const uint32_t opcode) {
5050

5151
printf("---- Instruction details of 0x%04x ----\n", opcode);
5252

53-
printf("opcode: 0x%04x\n", instr->opcode);
54-
printf("address: 0x%04x\n", instr->addr);
53+
printf("opcode: 0x%04" PRIx32 "\n", instr->opcode);
54+
printf("address: 0x%04" PRIx32 "\n", instr->addr);
5555

5656
printf("mnemonic: ");
5757
print_mnemonic(instr);

driver/disasm/disasm.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ int main(const int argc, const char **argv) {
7171
atexit(cleanup);
7272
m328p = vmcu_model_ctor(VMCU_DEVICE_M328P);
7373

74-
int32_t progsize = 0;
74+
uint32_t progsize = 0;
7575
vmcu_instr_t *prog = vmcu_disassemble_ihex(argv[1], &progsize, m328p);
7676

7777
if(prog == NULL || progsize == 0)
7878
return EXIT_FAILURE;
7979

80-
for(int32_t i = 0; i < progsize; i++)
80+
for(uint32_t i = 0; i < progsize; i++)
8181
print_instruction(&prog[i]);
8282

8383
free(prog);
@@ -113,7 +113,7 @@ static void print_instruction(vmcu_instr_t *instr) {
113113

114114
static void print_instruction_details(vmcu_instr_t *instr) {
115115

116-
printf("0x%04x", instr->addr);
116+
printf("0x%04" PRIx32, instr->addr);
117117

118118
const uint16_t opcl = (instr->opcode & 0x0000ffff);
119119
const uint16_t swpl = (opcl >> 8) | (opcl << 8);
@@ -124,9 +124,9 @@ static void print_instruction_details(vmcu_instr_t *instr) {
124124
if(instr->dword == false)
125125
printf(" %s....%s ", COLOR_GREEN, COLOR_RESET);
126126
else
127-
printf(" %s%04x%s ", COLOR_GREEN, swph, COLOR_RESET);
127+
printf(" %s%04" PRIx16 "%s ", COLOR_GREEN, swph, COLOR_RESET);
128128

129-
printf("%s%04x%s ", COLOR_YELLOW, swpl, COLOR_RESET);
129+
printf("%s%04" PRIx16 "%s ", COLOR_YELLOW, swpl, COLOR_RESET);
130130
}
131131

132132
static void print_colored_base(const char *basestr, VMCU_GROUP group) {

driver/endloop/endloop.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <string.h>
77
#include <stdbool.h>
88
#include <inttypes.h>
9-
#include <time.h>
109

1110
// libvmcu
1211
#include "libvmcu_analyzer.h"
@@ -55,7 +54,7 @@ int main(const int argc, const char **argv) {
5554
return EXIT_FAILURE;
5655
}
5756

58-
for(int32_t i = 0; i < report->progsize; i++) {
57+
for(uint32_t i = 0; i < report->progsize; i++) {
5958

6059
vmcu_instr_t *instr = &report->disassembly[i];
6160

@@ -67,7 +66,7 @@ int main(const int argc, const char **argv) {
6766
else
6867
printf("unconditional endloop:\t");
6968

70-
printf("0x%04x\t", instr->addr);
69+
printf("0x%04" PRIx32 "\t", instr->addr);
7170
print_instruction(instr);
7271
}
7372

driver/findgroup/findgroup.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <stdlib.h>
66
#include <string.h>
77
#include <inttypes.h>
8-
#include <time.h>
98

109
// libvmcu
1110
#include "libvmcu_analyzer.h"
@@ -56,14 +55,14 @@ int main(const int argc, const char **argv) {
5655

5756
VMCU_GROUP filter = get_filter(argv[2]);
5857

59-
for(int32_t i = 0; i < report->progsize; i++) {
58+
for(uint32_t i = 0; i < report->progsize; i++) {
6059

6160
vmcu_instr_t *instr = &report->disassembly[i];
6261

6362
if(instr->group != filter)
6463
continue;
6564

66-
printf("0x%04x\t", instr->addr);
65+
printf("0x%04" PRIx32 "\t", instr->addr);
6766
print_instruction(instr);
6867
}
6968

driver/findisr/findisr.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,34 @@ static void cleanup(void);
1818

1919
/* --- Extern --- */
2020

21-
vmcu_label_t* find_label(int address, vmcu_report_t* report) {
21+
vmcu_label_t* find_label(uint32_t address, vmcu_report_t* report) {
2222

23-
for(int i=0; i < report->n_label; i++) {
23+
for(uint32_t i=0; i < report->n_label; i++) {
2424

2525
vmcu_label_t* label = &report->label[i];
2626

2727
if(label->addr == address)
2828
return label;
2929
}
30+
31+
return NULL;
3032
}
3133

3234
void analyze_isr(vmcu_instr_t* instr, vmcu_report_t* report) {
3335

3436
vmcu_operand_t* op = &instr->src;
35-
int absolute_address = (op->type == VMCU_OPTYPE_S12) ? op->s : op->p;
37+
uint32_t absolute_address = (op->type == VMCU_OPTYPE_S12) ? instr->addr : op->p;
3638

3739
if(instr->key == VMCU_IKEY_RJMP)
38-
absolute_address += instr->addr + 1;
40+
absolute_address += op->s + 1;
3941

4042
vmcu_label_t* label = find_label(absolute_address, report);
4143
printf("L%d\t0x%04x\n", label->id, absolute_address);
4244
}
4345

44-
void print_addresses(vmcu_report_t* report, int start_index, int end_index) {
46+
void print_addresses(vmcu_report_t* report, uint32_t start_index, uint32_t end_index) {
4547

46-
for(int i=start_index; i <= end_index; i++) {
48+
for(uint32_t i=start_index; i <= end_index; i++) {
4749

4850
vmcu_instr_t* instr = &report->disassembly[i];
4951
analyze_isr(instr, report);
@@ -77,36 +79,39 @@ int main(const int argc, const char **argv) {
7779
if((report = vmcu_analyze_ihex(filename, m328p)) == NULL)
7880
return EXIT_FAILURE;
7981

80-
int start_index = -1;
81-
for(int i=0; i < report->progsize; i++) {
82+
uint32_t start_index = 0;
83+
bool ready = false;
8284

83-
vmcu_instr_t* instr = &report->disassembly[i];
85+
for(uint32_t i=0; i < report->progsize; i++) {
8486

85-
int key = instr->key;
87+
vmcu_instr_t* instr = &report->disassembly[i];
88+
VMCU_IKEY key = instr->key;
8689

8790
if(key == VMCU_IKEY_JMP || key == VMCU_IKEY_RJMP) {
8891

89-
if(start_index == -1)
92+
if(ready == false) {
93+
9094
start_index = i;
95+
ready = true;
96+
}
9197

9298
continue;
9399
}
94100

95-
const int count = i - start_index;
96-
97-
if(start_index == -1)
101+
if(ready == false)
98102
continue;
99103

104+
const uint32_t count = i - start_index;
105+
100106
bool case1 = table_size == -1 && count >= 14;
101107
bool case2 = table_size != -1 && count == table_size;
102108

103-
int end_index = start_index + count - 1;
109+
uint32_t end_index = start_index + count - 1;
104110

105111
if(case1 || case2)
106112
print_addresses(report, start_index, end_index);
107113

108-
start_index = -1;
109-
114+
ready = false;
110115
}
111116

112117
return EXIT_SUCCESS;

driver/graph/graph.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ int main(const int argc, const char **argv) {
8585
struct CFGBlock** blocks = obtain_blocks(report, &nblocks);
8686

8787
for(uint32_t i = 0; i < nblocks; i++) {
88-
print_block(blocks[i], file);
88+
print_block(blocks[i], file);
8989
}
9090

9191
for(uint32_t i = 0; i < nblocks; i++) {
@@ -105,7 +105,6 @@ int main(const int argc, const char **argv) {
105105
free(blocks);
106106

107107
if(report != NULL) vmcu_report_dtor(report);
108-
109108
if(m328p != NULL) vmcu_model_dtor(m328p);
110109

111110
return EXIT_SUCCESS;
@@ -203,8 +202,8 @@ static uint32_t branch_from(vmcu_cfg_node_t* node){
203202

204203
static uint32_t get_highest_addr(vmcu_report_t* report){
205204
vmcu_instr_t* disassembly = report->disassembly;
206-
int32_t highest_addr = 0;
207-
for(int32_t i = 0; i < report->progsize; i++){
205+
uint32_t highest_addr = 0;
206+
for(uint32_t i = 0; i < report->progsize; i++){
208207
if(disassembly[i].addr > highest_addr){
209208
highest_addr = disassembly[i].addr;
210209
}

0 commit comments

Comments
 (0)