summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2012-11-27 22:16:56 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2012-11-27 22:16:56 +0100
commit7dc3e939d2cd0a39035587f211587167eb6671de (patch)
tree8e932df28e865b66988c2e13cbed222f9347708e
parent9716d1f1f964a29c5087a2861e2b94afd140dcbb (diff)
downloadrockbox-7dc3e939d2cd0a39035587f211587167eb6671de.tar.gz
rockbox-7dc3e939d2cd0a39035587f211587167eb6671de.zip
sbtoelf: implement sb1 loading and dumping
Implement actual loading of a sb1 file to a structure in full generality. Also implement dumping for debug purpose Change-Id: I320035ea628719480a79aaccb05dce9a83256927
-rw-r--r--utils/imxtools/sbtools/crypto.c1
-rw-r--r--utils/imxtools/sbtools/misc.c6
-rw-r--r--utils/imxtools/sbtools/sb.c2
-rw-r--r--utils/imxtools/sbtools/sb1.c192
-rw-r--r--utils/imxtools/sbtools/sb1.h46
-rw-r--r--utils/imxtools/sbtools/sbtoelf.c23
6 files changed, 240 insertions, 30 deletions
diff --git a/utils/imxtools/sbtools/crypto.c b/utils/imxtools/sbtools/crypto.c
index d73547de25..d4afc6c816 100644
--- a/utils/imxtools/sbtools/crypto.c
+++ b/utils/imxtools/sbtools/crypto.c
@@ -28,7 +28,6 @@
28 28
29static enum crypto_method_t cur_method = CRYPTO_NONE; 29static enum crypto_method_t cur_method = CRYPTO_NONE;
30static byte key[16]; 30static byte key[16];
31static union xorcrypt_key_t xor_key[2];
32static uint16_t usb_vid, usb_pid; 31static uint16_t usb_vid, usb_pid;
33 32
34void crypto_setup(enum crypto_method_t method, void *param) 33void crypto_setup(enum crypto_method_t method, void *param)
diff --git a/utils/imxtools/sbtools/misc.c b/utils/imxtools/sbtools/misc.c
index ec9b8c2a27..d88b2bc858 100644
--- a/utils/imxtools/sbtools/misc.c
+++ b/utils/imxtools/sbtools/misc.c
@@ -239,6 +239,12 @@ void print_key(struct crypto_key_t *key, bool newline)
239 case CRYPTO_NONE: 239 case CRYPTO_NONE:
240 printf("none"); 240 printf("none");
241 break; 241 break;
242 case CRYPTO_XOR_KEY:
243 print_hex(&key->u.xor_key[0].key[0], 64, false);
244 print_hex(&key->u.xor_key[1].key[0], 64, false);
245 break;
246 default:
247 printf("unknown");
242 } 248 }
243 if(newline) 249 if(newline)
244 printf("\n"); 250 printf("\n");
diff --git a/utils/imxtools/sbtools/sb.c b/utils/imxtools/sbtools/sb.c
index 78f98b5985..2625d770c2 100644
--- a/utils/imxtools/sbtools/sb.c
+++ b/utils/imxtools/sbtools/sb.c
@@ -1138,7 +1138,7 @@ void sb_dump(struct sb_file_t *file, void *u, sb_color_printf cprintf)
1138 #define TEXT2 BLUE 1138 #define TEXT2 BLUE
1139 #define SEP OFF 1139 #define SEP OFF
1140 1140
1141 printf(HEADER, "SB File\n"); 1141 printf(BLUE, "SB File\n");
1142 printf(TREE, "+-"); 1142 printf(TREE, "+-");
1143 printf(HEADER, "Version: "); 1143 printf(HEADER, "Version: ");
1144 printf(TEXT, "1.%d\n", file->minor_version); 1144 printf(TEXT, "1.%d\n", file->minor_version);
diff --git a/utils/imxtools/sbtools/sb1.c b/utils/imxtools/sbtools/sb1.c
index 19f53b0015..22854036c1 100644
--- a/utils/imxtools/sbtools/sb1.c
+++ b/utils/imxtools/sbtools/sb1.c
@@ -26,6 +26,25 @@
26#include "crypto.h" 26#include "crypto.h"
27#include "sb1.h" 27#include "sb1.h"
28 28
29static int sdram_size_table[] = {2, 8, 16, 32, 64};
30
31#define NR_SDRAM_ENTRIES (int)(sizeof(sdram_size_table) / sizeof(sdram_size_table[0]))
32
33int sb1_sdram_size_by_index(int index)
34{
35 if(index < 0 || index >= NR_SDRAM_ENTRIES)
36 return -1;
37 return sdram_size_table[index];
38}
39
40int sb1_sdram_index_by_size(int size)
41{
42 for(int i = 0; i < NR_SDRAM_ENTRIES; i++)
43 if(sdram_size_table[i] == size)
44 return i;
45 return -1;
46}
47
29static uint16_t swap16(uint16_t t) 48static uint16_t swap16(uint16_t t)
30{ 49{
31 return (t << 8) | (t >> 8); 50 return (t << 8) | (t >> 8);
@@ -96,23 +115,34 @@ static const char *sb1_cmd_name(int cmd)
96 } 115 }
97} 116}
98 117
118static const char *sb1_datatype_name(int cmd)
119{
120 switch(cmd)
121 {
122 case SB1_DATATYPE_UINT32: return "uint32";
123 case SB1_DATATYPE_UINT16: return "uint16";
124 case SB1_DATATYPE_UINT8: return "uint8";
125 default: return "unknown";
126 }
127}
128
99struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u, 129struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
100 sb1_color_printf cprintf, enum sb1_error_t *err) 130 sb1_color_printf cprintf, enum sb1_error_t *err)
101{ 131{
102 struct sb1_file_t *sb1_file = NULL; 132 struct sb1_file_t *file = NULL;
103 uint8_t *buf = _buf; 133 uint8_t *buf = _buf;
104 134
105 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__) 135 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__)
106 #define fatal(e, ...) \ 136 #define fatal(e, ...) \
107 do { if(err) *err = e; \ 137 do { if(err) *err = e; \
108 cprintf(u, true, GREY, __VA_ARGS__); \ 138 cprintf(u, true, GREY, __VA_ARGS__); \
109 sb1_free(sb1_file); \ 139 sb1_free(file); \
110 return NULL; } while(0) 140 return NULL; } while(0)
111 #define print_hex(c, p, len, nl) \ 141 #define print_hex(c, p, len, nl) \
112 do { printf(c, ""); print_hex(p, len, nl); } while(0) 142 do { printf(c, ""); print_hex(p, len, nl); } while(0)
113 143
114 sb1_file = xmalloc(sizeof(struct sb1_file_t)); 144 file = xmalloc(sizeof(struct sb1_file_t));
115 memset(sb1_file, 0, sizeof(struct sb1_file_t)); 145 memset(file, 0, sizeof(struct sb1_file_t));
116 struct sb1_header_t *header = (struct sb1_header_t *)buf; 146 struct sb1_header_t *header = (struct sb1_header_t *)buf;
117 147
118 if(memcmp(header->signature, "STMP", 4) != 0) 148 if(memcmp(header->signature, "STMP", 4) != 0)
@@ -136,9 +166,6 @@ struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
136 struct sb1_version_t component_ver = header->component_ver; 166 struct sb1_version_t component_ver = header->component_ver;
137 fix_version(&component_ver); 167 fix_version(&component_ver);
138 168
139 memcpy(&sb1_file->product_ver, &product_ver, sizeof(product_ver));
140 memcpy(&sb1_file->component_ver, &component_ver, sizeof(component_ver));
141
142 printf(GREEN, " Product version: "); 169 printf(GREEN, " Product version: ");
143 printf(YELLOW, "%X.%X.%X\n", product_ver.major, product_ver.minor, product_ver.revision); 170 printf(YELLOW, "%X.%X.%X\n", product_ver.major, product_ver.minor, product_ver.revision);
144 printf(GREEN, " Component version: "); 171 printf(GREEN, " Component version: ");
@@ -147,6 +174,14 @@ struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
147 printf(GREEN, " Drive tag: "); 174 printf(GREEN, " Drive tag: ");
148 printf(YELLOW, "%x\n", header->drive_tag); 175 printf(YELLOW, "%x\n", header->drive_tag);
149 176
177 /* copy rom version, padding and drive tag */
178 /* copy versions */
179 memcpy(&file->product_ver, &product_ver, sizeof(product_ver));
180 memcpy(&file->component_ver, &component_ver, sizeof(component_ver));
181 file->rom_version = header->rom_version;
182 file->pad2 = header->pad2;
183 file->drive_tag = header->drive_tag;
184
150 /* reduce size w.r.t to userdata part */ 185 /* reduce size w.r.t to userdata part */
151 uint32_t userdata_size = 0; 186 uint32_t userdata_size = 0;
152 if(header->userdata_offset != 0) 187 if(header->userdata_offset != 0)
@@ -217,6 +252,7 @@ struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
217 if(mark != *(uint32_t *)(ptr + size)) 252 if(mark != *(uint32_t *)(ptr + size))
218 fatal(SB1_CHECKSUM_ERROR, "Crypto mark mismatch\n"); 253 fatal(SB1_CHECKSUM_ERROR, "Crypto mark mismatch\n");
219 memmove(copy_ptr, ptr, size); 254 memmove(copy_ptr, ptr, size);
255
220 ptr += size + 4; 256 ptr += size + 4;
221 copy_ptr += size; 257 copy_ptr += size;
222 offset = 0; 258 offset = 0;
@@ -236,13 +272,54 @@ struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
236 printf(YELLOW, " Critical:"); 272 printf(YELLOW, " Critical:");
237 printf(RED, " %d\n", SB1_CMD_CRITICAL(cmd->cmd)); 273 printf(RED, " %d\n", SB1_CMD_CRITICAL(cmd->cmd));
238 printf(YELLOW, " Data Type:"); 274 printf(YELLOW, " Data Type:");
239 printf(RED, " %#x\n", SB1_CMD_DATATYPE(cmd->cmd)); 275 printf(RED, " %#x ", SB1_CMD_DATATYPE(cmd->cmd));
276 printf(GREEN, "(%s)\n", sb1_datatype_name(SB1_CMD_DATATYPE(cmd->cmd)));
240 printf(YELLOW, " Bytes:"); 277 printf(YELLOW, " Bytes:");
241 printf(RED, " %#x\n", SB1_CMD_BYTES(cmd->cmd)); 278 printf(RED, " %#x\n", SB1_CMD_BYTES(cmd->cmd));
242 printf(YELLOW, " Boot:"); 279 printf(YELLOW, " Boot:");
243 printf(RED, " %#x (%s)\n", SB1_CMD_BOOT(cmd->cmd), sb1_cmd_name(SB1_CMD_BOOT(cmd->cmd))); 280 printf(RED, " %#x ", SB1_CMD_BOOT(cmd->cmd));
281 printf(GREEN, "(%s)\n", sb1_cmd_name(SB1_CMD_BOOT(cmd->cmd)));
244 printf(YELLOW, " Addr:"); 282 printf(YELLOW, " Addr:");
245 printf(RED, " %#x\n", cmd->addr); 283 printf(RED, " %#x", cmd->addr);
284
285 if(SB1_CMD_BOOT(cmd->cmd) == SB1_INST_SDRAM)
286 printf(GREEN, " (Chip Select=%d, Size=%d)", SB1_ADDR_SDRAM_CS(cmd->addr),
287 sb1_sdram_size_by_index(SB1_ADDR_SDRAM_SZ(cmd->addr)));
288 printf(OFF, "\n");
289 if(SB1_CMD_BOOT(cmd->cmd) == SB1_INST_FILL)
290 {
291 printf(YELLOW, " Pattern:");
292 printf(RED, " %#x\n", *(uint32_t *)(cmd + 1));
293 }
294
295 /* copy command */
296 struct sb1_inst_t inst;
297 memset(&inst, 0, sizeof(inst));
298 inst.cmd = SB1_CMD_BOOT(cmd->cmd);
299 inst.critical = SB1_CMD_CRITICAL(cmd->cmd);
300 inst.datatype = SB1_CMD_DATATYPE(cmd->cmd);
301 inst.size = SB1_CMD_BYTES(cmd->cmd);
302
303 switch(SB1_CMD_BOOT(cmd->cmd))
304 {
305 case SB1_INST_SDRAM:
306 inst.sdram.chip_select = SB1_ADDR_SDRAM_CS(cmd->addr);
307 inst.sdram.size_index = SB1_ADDR_SDRAM_SZ(cmd->addr);
308 break;
309 case SB1_INST_MODE:
310 inst.mode = cmd->addr;
311 break;
312 case SB1_INST_LOAD:
313 inst.data = malloc(inst.size);
314 memcpy(inst.data, cmd + 1, inst.size);
315 /* fallthrough */
316 default:
317 inst.addr = cmd->addr;
318 break;
319 }
320
321 file->insts = augment_array(file->insts, sizeof(inst), file->nr_insts, &inst, 1);
322 file->nr_insts++;
246 323
247 /* last instruction ? */ 324 /* last instruction ? */
248 if(SB1_CMD_BOOT(cmd->cmd) == SB1_INST_JUMP || 325 if(SB1_CMD_BOOT(cmd->cmd) == SB1_INST_JUMP ||
@@ -252,11 +329,15 @@ struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
252 cmd = (void *)cmd + 4 + 4 * SB1_CMD_SIZE(cmd->cmd); 329 cmd = (void *)cmd + 4 + 4 * SB1_CMD_SIZE(cmd->cmd);
253 } 330 }
254 331
255 sb1_file->data_size = header->image_size - header->header_size; 332 /* copy userdata */
256 sb1_file->data = malloc(sb1_file->data_size); 333 file->userdata_size = userdata_size;
257 memcpy(sb1_file->data, header + 1, sb1_file->data_size); 334 if(userdata_size > 0)
335 {
336 file->userdata = malloc(userdata_size);
337 memcpy(file->userdata, (void *)header + header->userdata_offset, userdata_size);
338 }
258 339
259 return sb1_file; 340 return file;
260 #undef printf 341 #undef printf
261 #undef fatal 342 #undef fatal
262 #undef print_hex 343 #undef print_hex
@@ -266,7 +347,10 @@ void sb1_free(struct sb1_file_t *file)
266{ 347{
267 if(!file) return; 348 if(!file) return;
268 349
269 free(file->data); 350 for(int i = 0; i < file->nr_insts; i++)
351 free(file->insts[i].data);
352 free(file->insts);
353 free(file->userdata);
270 free(file); 354 free(file);
271} 355}
272 356
@@ -280,8 +364,86 @@ void sb1_dump(struct sb1_file_t *file, void *u, sb1_color_printf cprintf)
280 #define HEADER GREEN 364 #define HEADER GREEN
281 #define TEXT YELLOW 365 #define TEXT YELLOW
282 #define TEXT2 BLUE 366 #define TEXT2 BLUE
367 #define TEXT3 RED
283 #define SEP OFF 368 #define SEP OFF
284 369
370 printf(BLUE, "SB1 File\n");
371 printf(TREE, "+-");
372 printf(HEADER, "Rom Ver: ");
373 printf(TEXT, "%x\n", file->rom_version);
374 printf(TREE, "+-");
375 printf(HEADER, "Pad: ");
376 printf(TEXT, "%x\n", file->pad2);
377 printf(TREE, "+-");
378 printf(HEADER, "Drive Tag: ");
379 printf(TEXT, "%x\n", file->drive_tag);
380 printf(TREE, "+-");
381 printf(HEADER, "Product Version: ");
382 printf(TEXT, "%X.%X.%X\n", file->product_ver.major, file->product_ver.minor,
383 file->product_ver.revision);
384 printf(TREE, "+-");
385 printf(HEADER, "Component Version: ");
386 printf(TEXT, "%X.%X.%X\n", file->component_ver.major, file->component_ver.minor,
387 file->component_ver.revision);
388
389 for(int j = 0; j < file->nr_insts; j++)
390 {
391 struct sb1_inst_t *inst = &file->insts[j];
392 printf(TREE, "+-");
393 printf(HEADER, "Command\n");
394 printf(TREE, "| +-");
395 switch(inst->cmd)
396 {
397 case SB1_INST_CALL:
398 case SB1_INST_JUMP:
399 printf(HEADER, "%s", inst->cmd == SB1_INST_CALL ? "CALL" : "JUMP");
400 printf(SEP, " | ");
401 printf(TEXT3, "crit=%d", inst->critical);
402 printf(SEP, " | ");
403 printf(TEXT, "addr=0x%08x\n", inst->addr);
404 break;
405 case SB1_INST_LOAD:
406 printf(HEADER, "LOAD");
407 printf(SEP, " | ");
408 printf(TEXT3, "crit=%d", inst->critical);
409 printf(SEP, " | ");
410 printf(TEXT, "addr=0x%08x", inst->addr);
411 printf(SEP, " | ");
412 printf(TEXT2, "len=0x%08x\n", inst->size);
413 break;
414 case SB1_INST_FILL:
415 printf(HEADER, "FILL");
416 printf(SEP, " | ");
417 printf(TEXT3, "crit=%d", inst->critical);
418 printf(SEP, " | ");
419 printf(TEXT, "addr=0x%08x", inst->addr);
420 printf(SEP, " | ");
421 printf(TEXT2, "len=0x%08x", inst->size);
422 printf(SEP, " | ");
423 printf(TEXT2, "pattern=0x%08x\n", inst->pattern);
424 break;
425 case SB1_INST_MODE:
426 printf(HEADER, "MODE");
427 printf(SEP, " | ");
428 printf(TEXT3, "crit=%d", inst->critical);
429 printf(SEP, " | ");
430 printf(TEXT, "mode=0x%08x\n", inst->addr);
431 break;
432 case SB1_INST_SDRAM:
433 printf(HEADER, "SRAM");
434 printf(SEP, " | ");
435 printf(TEXT3, "crit=%d", inst->critical);
436 printf(SEP, " | ");
437 printf(TEXT, "chip_select=%d", inst->sdram.chip_select);
438 printf(SEP, " | ");
439 printf(TEXT2, "chip_size=%d\n", sb1_sdram_size_by_index(inst->sdram.size_index));
440 break;
441 default:
442 printf(GREY, "[Unknown instruction %x]\n", inst->cmd);
443 break;
444 }
445 }
446
285 #undef printf 447 #undef printf
286 #undef print_hex 448 #undef print_hex
287} 449}
diff --git a/utils/imxtools/sbtools/sb1.h b/utils/imxtools/sbtools/sb1.h
index f0a7a4ebc8..8d8c2d2296 100644
--- a/utils/imxtools/sbtools/sb1.h
+++ b/utils/imxtools/sbtools/sb1.h
@@ -58,12 +58,20 @@ struct sb1_cmd_header_t
58 uint32_t addr; 58 uint32_t addr;
59} __attribute__((packed)); 59} __attribute__((packed));
60 60
61#define SB1_CMD_MAX_SIZE 0x1ff8
62
61#define SB1_CMD_SIZE(cmd) ((cmd) >> 21) 63#define SB1_CMD_SIZE(cmd) ((cmd) >> 21)
62#define SB1_CMD_CRITICAL(cmd) !!(cmd & (1 << 20)) 64#define SB1_CMD_CRITICAL(cmd) !!(cmd & (1 << 20))
63#define SB1_CMD_BYTES(cmd) (((cmd) >> 6) & 0x3fff) 65#define SB1_CMD_BYTES(cmd) (((cmd) >> 6) & 0x3fff)
64#define SB1_CMD_DATATYPE(cmd) (((cmd) >> 4) & 0x3) 66#define SB1_CMD_DATATYPE(cmd) (((cmd) >> 4) & 0x3)
65#define SB1_CMD_BOOT(cmd) ((cmd) & 0xf) 67#define SB1_CMD_BOOT(cmd) ((cmd) & 0xf)
66 68
69#define SB1_ADDR_SDRAM_CS(addr) ((addr) & 0x3)
70#define SB1_ADDR_SDRAM_SZ(addr) ((addr) >> 16)
71
72int sb1_sdram_size_by_index(int index); // returns - 1 on error
73int sb1_sdram_index_by_size(int size); // returns -1 on error
74
67#define SB1_INST_LOAD 0x1 75#define SB1_INST_LOAD 0x1
68#define SB1_INST_FILL 0x2 76#define SB1_INST_FILL 0x2
69#define SB1_INST_JUMP 0x3 77#define SB1_INST_JUMP 0x3
@@ -71,12 +79,46 @@ struct sb1_cmd_header_t
71#define SB1_INST_MODE 0x5 79#define SB1_INST_MODE 0x5
72#define SB1_INST_SDRAM 0x6 80#define SB1_INST_SDRAM 0x6
73 81
82#define SB1_DATATYPE_UINT32 0
83#define SB1_DATATYPE_UINT16 1
84#define SB1_DATATYPE_UINT8 2
85
86/*******
87 * API *
88 *******/
89
90struct sb1_inst_t
91{
92 uint8_t cmd;
93 uint16_t size;
94 // <union>
95 struct
96 {
97 uint8_t chip_select;
98 uint8_t size_index;
99 }sdram;
100 uint8_t mode;
101 uint32_t addr;
102 // </union>
103 uint8_t datatype;
104 uint8_t critical;
105 // <union>
106 void *data;
107 uint32_t pattern;
108 // </union>
109};
110
74struct sb1_file_t 111struct sb1_file_t
75{ 112{
113 uint32_t rom_version;
114 uint32_t pad2; // unknown meaning but copy it anyway !
115 uint32_t drive_tag;
76 struct sb1_version_t product_ver; 116 struct sb1_version_t product_ver;
77 struct sb1_version_t component_ver; 117 struct sb1_version_t component_ver;
78 void *data; 118 int nr_insts;
79 int data_size; 119 struct sb1_inst_t *insts;
120 void *userdata;
121 int userdata_size;
80}; 122};
81 123
82enum sb1_error_t 124enum sb1_error_t
diff --git a/utils/imxtools/sbtools/sbtoelf.c b/utils/imxtools/sbtools/sbtoelf.c
index 0445c4a366..01a51cae90 100644
--- a/utils/imxtools/sbtools/sbtoelf.c
+++ b/utils/imxtools/sbtools/sbtoelf.c
@@ -162,7 +162,6 @@ static void extract_sb1_file(struct sb1_file_t *file)
162 FILE *f = fopen(g_out_prefix, "wb"); 162 FILE *f = fopen(g_out_prefix, "wb");
163 if(f == NULL) 163 if(f == NULL)
164 bugp("Cannot open %s for writing\n", g_out_prefix); 164 bugp("Cannot open %s for writing\n", g_out_prefix);
165 fwrite(file->data, file->data_size, 1, f);
166 fclose(f); 165 fclose(f);
167} 166}
168 167
@@ -228,33 +227,35 @@ enum sb_version_guess_t
228 227
229enum sb_version_guess_t guess_sb_version(const char *filename) 228enum sb_version_guess_t guess_sb_version(const char *filename)
230{ 229{
230#define ret(x) do { fclose(f); return x; } while(0)
231 FILE *f = fopen(filename, "rb"); 231 FILE *f = fopen(filename, "rb");
232 if(f == NULL) 232 if(f == NULL)
233 bugp("Cannot open file for reading\n"); 233 bugp("Cannot open file for reading\n");
234 // check signature 234 // check signature
235 uint8_t sig[4]; 235 uint8_t sig[4];
236 if(fseek(f, 20, SEEK_SET)) 236 if(fseek(f, 20, SEEK_SET))
237 return SB_VERSION_UNK; 237 ret(SB_VERSION_UNK);
238 if(fread(sig, 4, 1, f) != 1) 238 if(fread(sig, 4, 1, f) != 1)
239 return SB_VERSION_UNK; 239 ret(SB_VERSION_UNK);
240 if(memcmp(sig, "STMP", 4) != 0) 240 if(memcmp(sig, "STMP", 4) != 0)
241 return SB_VERSION_UNK; 241 ret(SB_VERSION_UNK);
242 // check header size (v1) 242 // check header size (v1)
243 uint32_t hdr_size; 243 uint32_t hdr_size;
244 if(fseek(f, 8, SEEK_SET)) 244 if(fseek(f, 8, SEEK_SET))
245 return SB_VERSION_UNK; 245 ret(SB_VERSION_UNK);
246 if(fread(&hdr_size, 4, 1, f) != 1) 246 if(fread(&hdr_size, 4, 1, f) != 1)
247 return SB_VERSION_UNK; 247 ret(SB_VERSION_UNK);
248 if(hdr_size == 0x34) 248 if(hdr_size == 0x34)
249 return SB_VERSION_1; 249 ret(SB_VERSION_1);
250 // check header size (v2) 250 // check header size (v2)
251 if(fseek(f, 32, SEEK_SET)) 251 if(fseek(f, 32, SEEK_SET))
252 return SB_VERSION_UNK; 252 ret(SB_VERSION_UNK);
253 if(fread(&hdr_size, 4, 1, f) != 1) 253 if(fread(&hdr_size, 4, 1, f) != 1)
254 return SB_VERSION_UNK; 254 ret(SB_VERSION_UNK);
255 if(hdr_size == 0xc) 255 if(hdr_size == 0xc)
256 return SB_VERSION_2; 256 ret(SB_VERSION_2);
257 return SB_VERSION_UNK; 257 ret(SB_VERSION_UNK);
258#undef ret
258} 259}
259 260
260int main(int argc, char **argv) 261int main(int argc, char **argv)