summaryrefslogtreecommitdiff
path: root/utils/sbtools
diff options
context:
space:
mode:
Diffstat (limited to 'utils/sbtools')
-rw-r--r--utils/sbtools/elf.c240
-rw-r--r--utils/sbtools/elf.h141
-rw-r--r--utils/sbtools/elftosb.c215
-rw-r--r--utils/sbtools/sbtoelf.c2
4 files changed, 449 insertions, 149 deletions
diff --git a/utils/sbtools/elf.c b/utils/sbtools/elf.c
index f146bcc111..4b95025d8f 100644
--- a/utils/sbtools/elf.c
+++ b/utils/sbtools/elf.c
@@ -1,5 +1,135 @@
1#include "elf.h" 1#include "elf.h"
2 2
3/**
4 * Definitions
5 * taken from elf.h linux header
6 * based on ELF specification
7 * based on ARM ELF specification
8 */
9typedef uint16_t Elf32_Half;
10
11typedef uint32_t Elf32_Word;
12typedef int32_t Elf32_Sword;
13typedef uint32_t Elf32_Addr;
14typedef uint32_t Elf32_Off;
15typedef uint16_t Elf32_Section;
16
17#define EI_NIDENT 16
18
19typedef struct
20{
21 unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
22 Elf32_Half e_type; /* Object file type */
23 Elf32_Half e_machine; /* Architecture */
24 Elf32_Word e_version; /* Object file version */
25 Elf32_Addr e_entry; /* Entry point virtual address */
26 Elf32_Off e_phoff; /* Program header table file offset */
27 Elf32_Off e_shoff; /* Section header table file offset */
28 Elf32_Word e_flags; /* Processor-specific flags */
29 Elf32_Half e_ehsize; /* ELF header size in bytes */
30 Elf32_Half e_phentsize; /* Program header table entry size */
31 Elf32_Half e_phnum; /* Program header table entry count */
32 Elf32_Half e_shentsize; /* Section header table entry size */
33 Elf32_Half e_shnum; /* Section header table entry count */
34 Elf32_Half e_shstrndx; /* Section header string table index */
35}Elf32_Ehdr;
36
37#define EI_MAG0 0 /* File identification byte 0 index */
38#define ELFMAG0 0x7f /* Magic number byte 0 */
39
40#define EI_MAG1 1 /* File identification byte 1 index */
41#define ELFMAG1 'E' /* Magic number byte 1 */
42
43#define EI_MAG2 2 /* File identification byte 2 index */
44#define ELFMAG2 'L' /* Magic number byte 2 */
45
46#define EI_MAG3 3 /* File identification byte 3 index */
47#define ELFMAG3 'F' /* Magic number byte 3 */
48
49#define EI_CLASS 4 /* File class byte index */
50#define ELFCLASS32 1 /* 32-bit objects */
51
52#define EI_DATA 5 /* Data encoding byte index */
53#define ELFDATA2LSB 1 /* 2's complement, little endian */
54
55#define EI_VERSION 6 /* File version byte index, Value must be EV_CURRENT */
56
57#define EI_OSABI 7 /* OS ABI identification */
58#define ELFOSABI_NONE 0 /* UNIX System V ABI */
59#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
60#define ELFOSABI_ARM 97 /* ARM */
61
62#define EI_ABIVERSION 8 /* ABI version */
63
64#define EI_PAD 9 /* Byte index of padding bytes */
65
66#define ET_EXEC 2 /* Executable file */
67
68#define EM_ARM 40 /* ARM */
69
70#define EV_CURRENT 1 /* Current version */
71
72#define EF_ARM_HASENTRY 0x00000002
73
74#define SHN_UNDEF 0 /* Undefined section */
75
76typedef struct
77{
78 Elf32_Word sh_name; /* Section name (string tbl index) */
79 Elf32_Word sh_type; /* Section type */
80 Elf32_Word sh_flags; /* Section flags */
81 Elf32_Addr sh_addr; /* Section virtual addr at execution */
82 Elf32_Off sh_offset; /* Section file offset */
83 Elf32_Word sh_size; /* Section size in bytes */
84 Elf32_Word sh_link; /* Link to another section */
85 Elf32_Word sh_info; /* Additional section information */
86 Elf32_Word sh_addralign; /* Section alignment */
87 Elf32_Word sh_entsize; /* Entry size if section holds table */
88}Elf32_Shdr;
89
90#define SHT_NULL 0 /* Section header table entry unused */
91#define SHT_PROGBITS 1 /* Program data */
92#define SHT_SYMTAB 2 /* Symbol table */
93#define SHT_STRTAB 3 /* String table */
94#define SHT_RELA 4 /* Relocation entries with addends */
95#define SHT_HASH 5 /* Symbol hash table */
96#define SHT_DYNAMIC 6 /* Dynamic linking information */
97#define SHT_NOTE 7 /* Notes */
98#define SHT_NOBITS 8 /* Program space with no data (bss) */
99#define SHT_REL 9 /* Relocation entries, no addends */
100#define SHT_SHLIB 10 /* Reserved */
101#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
102#define SHT_INIT_ARRAY 14 /* Array of constructors */
103#define SHT_FINI_ARRAY 15 /* Array of destructors */
104#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
105#define SHT_GROUP 17 /* Section group */
106#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
107#define SHT_NUM 19 /* Number of defined types. */
108
109#define SHF_WRITE (1 << 0) /* Writable */
110#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
111#define SHF_EXECINSTR (1 << 2) /* Executable */
112#define SHF_MERGE (1 << 4) /* Might be merged */
113#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
114
115typedef struct
116{
117 Elf32_Word p_type; /* Segment type */
118 Elf32_Off p_offset; /* Segment file offset */
119 Elf32_Addr p_vaddr; /* Segment virtual address */
120 Elf32_Addr p_paddr; /* Segment physical address */
121 Elf32_Word p_filesz; /* Segment size in file */
122 Elf32_Word p_memsz; /* Segment size in memory */
123 Elf32_Word p_flags; /* Segment flags */
124 Elf32_Word p_align; /* Segment alignment */
125}Elf32_Phdr;
126
127#define PT_LOAD 1 /* Loadable program segment */
128
129#define PF_X (1 << 0) /* Segment is executable */
130#define PF_W (1 << 1) /* Segment is writable */
131#define PF_R (1 << 2) /* Segment is readable */
132
3void elf_init(struct elf_params_t *params) 133void elf_init(struct elf_params_t *params)
4{ 134{
5 params->has_start_addr = false; 135 params->has_start_addr = false;
@@ -54,7 +184,7 @@ void elf_add_fill_section(struct elf_params_t *params,
54 sec->pattern = pattern; 184 sec->pattern = pattern;
55} 185}
56 186
57void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user) 187void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, void *user)
58{ 188{
59 Elf32_Ehdr ehdr; 189 Elf32_Ehdr ehdr;
60 uint32_t phnum = 0; 190 uint32_t phnum = 0;
@@ -64,9 +194,11 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
64 Elf32_Shdr shdr; 194 Elf32_Shdr shdr;
65 memset(&ehdr, 0, EI_NIDENT); 195 memset(&ehdr, 0, EI_NIDENT);
66 196
67 uint32_t bss_strtbl = 0; 197 uint32_t bss_strtbl = 1;
68 uint32_t text_strtbl = bss_strtbl + strlen(".bss") + 1; 198 uint32_t text_strtbl = bss_strtbl + strlen(".bss") + 1;
69 uint32_t strtbl_size = text_strtbl + strlen(".text") + 1; 199 uint32_t shstrtab_strtbl = text_strtbl + strlen(".text") + 1;
200 uint32_t strtbl_size = shstrtab_strtbl + strlen(".shstrtab") + 1;
201
70 202
71 while(sec) 203 while(sec)
72 { 204 {
@@ -182,7 +314,7 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
182 } 314 }
183 315
184 { 316 {
185 shdr.sh_name = bss_strtbl; 317 shdr.sh_name = shstrtab_strtbl;
186 shdr.sh_type = SHT_STRTAB; 318 shdr.sh_type = SHT_STRTAB;
187 shdr.sh_flags = 0; 319 shdr.sh_flags = 0;
188 shdr.sh_addr = 0; 320 shdr.sh_addr = 0;
@@ -206,7 +338,86 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
206 sec = sec->next; 338 sec = sec->next;
207 } 339 }
208 340
209 write(user, strtbl_offset + data_offset, ".bss\0.text\0", strtbl_size); 341 write(user, strtbl_offset + data_offset, "\0.bss\0.text\0.shstrtab\0", strtbl_size);
342}
343
344bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read,
345 elf_printf_fn_t printf, void *user)
346{
347 #define error_printf(...) ({printf(user, true, __VA_ARGS__); return false;})
348 /* read header */
349 Elf32_Ehdr ehdr;
350 if(!read(user, 0, &ehdr, sizeof(ehdr)))
351 {
352 printf(user, true, "error reading elf header\n");
353 return false;
354 }
355 /* basic checks */
356 if(ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
357 ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3)
358 error_printf("invalid elf header\n");
359 if(ehdr.e_ident[EI_CLASS] != ELFCLASS32)
360 error_printf("invalid elf class: must be a 32-bit object\n");
361 if(ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
362 error_printf("invalid elf data encoding: must be 32-bit lsb\n");
363 if(ehdr.e_ident[EI_VERSION] != EV_CURRENT)
364 error_printf("invalid elf version");
365 if(ehdr.e_type != ET_EXEC)
366 error_printf("invalid elf file: must be an executable file\n");
367 if(ehdr.e_machine != EM_ARM)
368 error_printf("invalid elf file: must target an arm machine\n");
369 if(ehdr.e_ehsize != sizeof(ehdr))
370 error_printf("invalid elf file: size header mismatch\n");
371 if(ehdr.e_phentsize != sizeof(Elf32_Phdr))
372 error_printf("invalid elf file: program header size mismatch\n");
373 if(ehdr.e_shentsize != sizeof(Elf32_Shdr))
374 error_printf("invalid elf file: section header size mismatch\n");
375 if(ehdr.e_flags & EF_ARM_HASENTRY)
376 elf_set_start_addr(params, ehdr.e_entry);
377
378 char *strtab = NULL;
379 {
380 Elf32_Shdr shstrtab;
381 if(read(user, ehdr.e_shoff + ehdr.e_shstrndx * ehdr.e_shentsize,
382 &shstrtab, sizeof(shstrtab)))
383 {
384 strtab = xmalloc(shstrtab.sh_size);
385 if(!read(user, shstrtab.sh_offset, strtab, shstrtab.sh_size))
386 {
387 free(strtab);
388 strtab = NULL;
389 }
390 }
391 }
392 /* run through sections */
393 printf(user, false, "ELF file:\n");
394 for(int i = 1; i< ehdr.e_shnum; i++)
395 {
396 uint32_t off = ehdr.e_shoff + i * ehdr.e_shentsize;
397 Elf32_Shdr shdr;
398 memset(&shdr, 0, sizeof(shdr));
399 if(!read(user, off, &shdr, sizeof(shdr)))
400 error_printf("error reading elf section header");
401
402 if(shdr.sh_type == SHT_PROGBITS && shdr.sh_flags & SHF_ALLOC)
403 {
404 void *data = xmalloc(shdr.sh_size);
405 if(!read(user, shdr.sh_offset, data, shdr.sh_size))
406 error_printf("error read self section data");
407 elf_add_load_section(params, shdr.sh_addr, shdr.sh_size, data);
408
409 printf(user, false, "create load segment for %s\n", &strtab[shdr.sh_name]);
410 }
411 else if(shdr.sh_type == SHT_NOBITS && shdr.sh_flags & SHF_ALLOC)
412 {
413 elf_add_fill_section(params, shdr.sh_addr, shdr.sh_size, 0);
414 printf(user, false, "create fill segment for %s\n", &strtab[shdr.sh_name]);
415 }
416 else
417 printf(user, false, "filter out %s\n", &strtab[shdr.sh_name], shdr.sh_type);
418
419 }
420 return true;
210} 421}
211 422
212bool elf_is_empty(struct elf_params_t *params) 423bool elf_is_empty(struct elf_params_t *params)
@@ -220,6 +431,25 @@ void elf_set_start_addr(struct elf_params_t *params, uint32_t addr)
220 params->start_addr = addr; 431 params->start_addr = addr;
221} 432}
222 433
434bool elf_get_start_addr(struct elf_params_t *params, uint32_t *addr)
435{
436 if(params->has_start_addr && addr != NULL)
437 *addr = params->start_addr;
438 return params->has_start_addr;
439}
440
441int elf_get_nr_sections(struct elf_params_t *params)
442{
443 int nr = 0;
444 struct elf_section_t *sec = params->first_section;
445 while(sec)
446 {
447 nr++;
448 sec = sec->next;
449 }
450 return nr;
451}
452
223void elf_release(struct elf_params_t *params) 453void elf_release(struct elf_params_t *params)
224{ 454{
225 struct elf_section_t *sec, *next_sec; 455 struct elf_section_t *sec, *next_sec;
diff --git a/utils/sbtools/elf.h b/utils/sbtools/elf.h
index d2bf210c5c..b145bfffc5 100644
--- a/utils/sbtools/elf.h
+++ b/utils/sbtools/elf.h
@@ -6,136 +6,6 @@
6#include <unistd.h> 6#include <unistd.h>
7 7
8/** 8/**
9 * Definitions
10 * taken from elf.h linux header
11 * based on ELF specification
12 * based on ARM ELF specification
13 */
14typedef uint16_t Elf32_Half;
15
16typedef uint32_t Elf32_Word;
17typedef int32_t Elf32_Sword;
18typedef uint32_t Elf32_Addr;
19typedef uint32_t Elf32_Off;
20typedef uint16_t Elf32_Section;
21
22#define EI_NIDENT 16
23
24typedef struct
25{
26 unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
27 Elf32_Half e_type; /* Object file type */
28 Elf32_Half e_machine; /* Architecture */
29 Elf32_Word e_version; /* Object file version */
30 Elf32_Addr e_entry; /* Entry point virtual address */
31 Elf32_Off e_phoff; /* Program header table file offset */
32 Elf32_Off e_shoff; /* Section header table file offset */
33 Elf32_Word e_flags; /* Processor-specific flags */
34 Elf32_Half e_ehsize; /* ELF header size in bytes */
35 Elf32_Half e_phentsize; /* Program header table entry size */
36 Elf32_Half e_phnum; /* Program header table entry count */
37 Elf32_Half e_shentsize; /* Section header table entry size */
38 Elf32_Half e_shnum; /* Section header table entry count */
39 Elf32_Half e_shstrndx; /* Section header string table index */
40}Elf32_Ehdr;
41
42#define EI_MAG0 0 /* File identification byte 0 index */
43#define ELFMAG0 0x7f /* Magic number byte 0 */
44
45#define EI_MAG1 1 /* File identification byte 1 index */
46#define ELFMAG1 'E' /* Magic number byte 1 */
47
48#define EI_MAG2 2 /* File identification byte 2 index */
49#define ELFMAG2 'L' /* Magic number byte 2 */
50
51#define EI_MAG3 3 /* File identification byte 3 index */
52#define ELFMAG3 'F' /* Magic number byte 3 */
53
54#define EI_CLASS 4 /* File class byte index */
55#define ELFCLASS32 1 /* 32-bit objects */
56
57#define EI_DATA 5 /* Data encoding byte index */
58#define ELFDATA2LSB 1 /* 2's complement, little endian */
59
60#define EI_VERSION 6 /* File version byte index, Value must be EV_CURRENT */
61
62#define EI_OSABI 7 /* OS ABI identification */
63#define ELFOSABI_NONE 0 /* UNIX System V ABI */
64#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
65#define ELFOSABI_ARM 97 /* ARM */
66
67#define EI_ABIVERSION 8 /* ABI version */
68
69#define EI_PAD 9 /* Byte index of padding bytes */
70
71#define ET_EXEC 2 /* Executable file */
72
73#define EM_ARM 40 /* ARM */
74
75#define EV_CURRENT 1 /* Current version */
76
77#define EF_ARM_HASENTRY 0x00000002
78
79#define SHN_UNDEF 0 /* Undefined section */
80
81typedef struct
82{
83 Elf32_Word sh_name; /* Section name (string tbl index) */
84 Elf32_Word sh_type; /* Section type */
85 Elf32_Word sh_flags; /* Section flags */
86 Elf32_Addr sh_addr; /* Section virtual addr at execution */
87 Elf32_Off sh_offset; /* Section file offset */
88 Elf32_Word sh_size; /* Section size in bytes */
89 Elf32_Word sh_link; /* Link to another section */
90 Elf32_Word sh_info; /* Additional section information */
91 Elf32_Word sh_addralign; /* Section alignment */
92 Elf32_Word sh_entsize; /* Entry size if section holds table */
93}Elf32_Shdr;
94
95#define SHT_NULL 0 /* Section header table entry unused */
96#define SHT_PROGBITS 1 /* Program data */
97#define SHT_SYMTAB 2 /* Symbol table */
98#define SHT_STRTAB 3 /* String table */
99#define SHT_RELA 4 /* Relocation entries with addends */
100#define SHT_HASH 5 /* Symbol hash table */
101#define SHT_DYNAMIC 6 /* Dynamic linking information */
102#define SHT_NOTE 7 /* Notes */
103#define SHT_NOBITS 8 /* Program space with no data (bss) */
104#define SHT_REL 9 /* Relocation entries, no addends */
105#define SHT_SHLIB 10 /* Reserved */
106#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
107#define SHT_INIT_ARRAY 14 /* Array of constructors */
108#define SHT_FINI_ARRAY 15 /* Array of destructors */
109#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
110#define SHT_GROUP 17 /* Section group */
111#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
112#define SHT_NUM 19 /* Number of defined types. */
113
114#define SHF_WRITE (1 << 0) /* Writable */
115#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
116#define SHF_EXECINSTR (1 << 2) /* Executable */
117#define SHF_MERGE (1 << 4) /* Might be merged */
118#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
119
120typedef struct
121{
122 Elf32_Word p_type; /* Segment type */
123 Elf32_Off p_offset; /* Segment file offset */
124 Elf32_Addr p_vaddr; /* Segment virtual address */
125 Elf32_Addr p_paddr; /* Segment physical address */
126 Elf32_Word p_filesz; /* Segment size in file */
127 Elf32_Word p_memsz; /* Segment size in memory */
128 Elf32_Word p_flags; /* Segment flags */
129 Elf32_Word p_align; /* Segment alignment */
130}Elf32_Phdr;
131
132#define PT_LOAD 1 /* Loadable program segment */
133
134#define PF_X (1 << 0) /* Segment is executable */
135#define PF_W (1 << 1) /* Segment is writable */
136#define PF_R (1 << 2) /* Segment is readable */
137
138/**
139 * API 9 * API
140 */ 10 */
141enum elf_section_type_t 11enum elf_section_type_t
@@ -154,7 +24,7 @@ struct elf_section_t
154 uint32_t pattern; 24 uint32_t pattern;
155 /* </union> */ 25 /* </union> */
156 struct elf_section_t *next; 26 struct elf_section_t *next;
157 /* Internal to elf_output */ 27 /* Internal to elf_write_file */
158 uint32_t offset; 28 uint32_t offset;
159}; 29};
160 30
@@ -166,14 +36,21 @@ struct elf_params_t
166 struct elf_section_t *last_section; 36 struct elf_section_t *last_section;
167}; 37};
168 38
39typedef bool (*elf_read_fn_t)(void *user, uint32_t addr, void *buf, size_t count);
40/* write function manages it's own error state */
169typedef void (*elf_write_fn_t)(void *user, uint32_t addr, const void *buf, size_t count); 41typedef void (*elf_write_fn_t)(void *user, uint32_t addr, const void *buf, size_t count);
42typedef void (*elf_printf_fn_t)(void *user, bool error, const char *fmt, ...);
170 43
171void elf_init(struct elf_params_t *params); 44void elf_init(struct elf_params_t *params);
172void elf_add_load_section(struct elf_params_t *params, 45void elf_add_load_section(struct elf_params_t *params,
173 uint32_t load_addr, uint32_t size, const void *section); 46 uint32_t load_addr, uint32_t size, const void *section);
174void elf_add_fill_section(struct elf_params_t *params, 47void elf_add_fill_section(struct elf_params_t *params,
175 uint32_t fill_addr, uint32_t size, uint32_t pattern); 48 uint32_t fill_addr, uint32_t size, uint32_t pattern);
176void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user); 49void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, void *user);
50bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, elf_printf_fn_t printf,
51 void *user);
177bool elf_is_empty(struct elf_params_t *params); 52bool elf_is_empty(struct elf_params_t *params);
178void elf_set_start_addr(struct elf_params_t *params, uint32_t addr); 53void elf_set_start_addr(struct elf_params_t *params, uint32_t addr);
54bool elf_get_start_addr(struct elf_params_t *params, uint32_t *addr);
55int elf_get_nr_sections(struct elf_params_t *params);
179void elf_release(struct elf_params_t *params); 56void elf_release(struct elf_params_t *params);
diff --git a/utils/sbtools/elftosb.c b/utils/sbtools/elftosb.c
index 73768dd9a3..c4887ab47a 100644
--- a/utils/sbtools/elftosb.c
+++ b/utils/sbtools/elftosb.c
@@ -31,6 +31,7 @@
31#include <string.h> 31#include <string.h>
32#include <ctype.h> 32#include <ctype.h>
33#include <time.h> 33#include <time.h>
34#include <stdarg.h>
34 35
35#include "crypto.h" 36#include "crypto.h"
36#include "elf.h" 37#include "elf.h"
@@ -39,6 +40,12 @@
39#define bug(...) do { fprintf(stderr,"ERROR: "__VA_ARGS__); exit(1); } while(0) 40#define bug(...) do { fprintf(stderr,"ERROR: "__VA_ARGS__); exit(1); } while(0)
40#define bugp(a) do { perror("ERROR: "a); exit(1); } while(0) 41#define bugp(a) do { perror("ERROR: "a); exit(1); } while(0)
41 42
43bool g_debug = false;
44
45/**
46 * Misc
47 */
48
42void *xmalloc(size_t s) /* malloc helper, used in elf.c */ 49void *xmalloc(size_t s) /* malloc helper, used in elf.c */
43{ 50{
44 void * r = malloc(s); 51 void * r = malloc(s);
@@ -67,6 +74,10 @@ static int convxdigit(char digit, byte *val)
67 return 1; 74 return 1;
68} 75}
69 76
77/**
78 * Key file parsing
79 */
80
70typedef byte (*key_array_t)[16]; 81typedef byte (*key_array_t)[16];
71 82
72static key_array_t read_keys(const char *key_file, int *num_keys) 83static key_array_t read_keys(const char *key_file, int *num_keys)
@@ -117,11 +128,18 @@ static key_array_t read_keys(const char *key_file, int *num_keys)
117 return keys; 128 return keys;
118} 129}
119 130
131/**
132 * Command file parsing
133 */
134
120struct cmd_source_t 135struct cmd_source_t
121{ 136{
122 char *identifier; 137 char *identifier;
123 char *filename; 138 char *filename;
124 struct cmd_source_t *next; 139 struct cmd_source_t *next;
140 /* for later use */
141 bool elf_loaded;
142 struct elf_params_t elf;
125}; 143};
126 144
127enum cmd_inst_type_t 145enum cmd_inst_type_t
@@ -142,6 +160,7 @@ struct cmd_section_t
142{ 160{
143 uint32_t identifier; 161 uint32_t identifier;
144 struct cmd_inst_t *inst_list; 162 struct cmd_inst_t *inst_list;
163 struct cmd_section_t *next;
145}; 164};
146 165
147struct cmd_file_t 166struct cmd_file_t
@@ -171,7 +190,7 @@ struct lexem_t
171 uint32_t num; 190 uint32_t num;
172}; 191};
173 192
174void __parse_string(char **ptr, char *end, void *user, void (*emit_fn)(void *user, char c)) 193static void __parse_string(char **ptr, char *end, void *user, void (*emit_fn)(void *user, char c))
175{ 194{
176 while(*ptr != end) 195 while(*ptr != end)
177 { 196 {
@@ -196,19 +215,19 @@ void __parse_string(char **ptr, char *end, void *user, void (*emit_fn)(void *use
196 (*ptr)++; 215 (*ptr)++;
197} 216}
198 217
199void __parse_string_emit(void *user, char c) 218static void __parse_string_emit(void *user, char c)
200{ 219{
201 char **pstr = (char **)user; 220 char **pstr = (char **)user;
202 *(*pstr)++ = c; 221 *(*pstr)++ = c;
203} 222}
204 223
205void __parse_string_count(void *user, char c) 224static void __parse_string_count(void *user, char c)
206{ 225{
207 (void) c; 226 (void) c;
208 (*(int *)user)++; 227 (*(int *)user)++;
209} 228}
210 229
211void parse_string(char **ptr, char *end, struct lexem_t *lexem) 230static void parse_string(char **ptr, char *end, struct lexem_t *lexem)
212{ 231{
213 /* skip " */ 232 /* skip " */
214 (*ptr)++; 233 (*ptr)++;
@@ -224,7 +243,7 @@ void parse_string(char **ptr, char *end, struct lexem_t *lexem)
224 __parse_string(ptr, end, (void *)&pstr, __parse_string_emit); 243 __parse_string(ptr, end, (void *)&pstr, __parse_string_emit);
225} 244}
226 245
227void parse_number(char **ptr, char *end, struct lexem_t *lexem) 246static void parse_number(char **ptr, char *end, struct lexem_t *lexem)
228{ 247{
229 int base = 10; 248 int base = 10;
230 if(**ptr == '0' && (*ptr) + 1 != end && (*ptr)[1] == 'x') 249 if(**ptr == '0' && (*ptr) + 1 != end && (*ptr)[1] == 'x')
@@ -247,7 +266,7 @@ void parse_number(char **ptr, char *end, struct lexem_t *lexem)
247 } 266 }
248} 267}
249 268
250void parse_identifier(char **ptr, char *end, struct lexem_t *lexem) 269static void parse_identifier(char **ptr, char *end, struct lexem_t *lexem)
251{ 270{
252 /* remember position */ 271 /* remember position */
253 char *old = *ptr; 272 char *old = *ptr;
@@ -260,7 +279,7 @@ void parse_identifier(char **ptr, char *end, struct lexem_t *lexem)
260 memcpy(lexem->str, old, len); 279 memcpy(lexem->str, old, len);
261} 280}
262 281
263void next_lexem(char **ptr, char *end, struct lexem_t *lexem) 282static void next_lexem(char **ptr, char *end, struct lexem_t *lexem)
264{ 283{
265 #define ret_simple(t, advance) ({(*ptr) += advance; lexem->type = t; return;}) 284 #define ret_simple(t, advance) ({(*ptr) += advance; lexem->type = t; return;})
266 while(true) 285 while(true)
@@ -294,7 +313,7 @@ void next_lexem(char **ptr, char *end, struct lexem_t *lexem)
294 #undef ret_simple 313 #undef ret_simple
295} 314}
296 315
297void log_lexem(struct lexem_t *lexem) 316static void log_lexem(struct lexem_t *lexem)
298{ 317{
299 switch(lexem->type) 318 switch(lexem->type)
300 { 319 {
@@ -312,19 +331,19 @@ void log_lexem(struct lexem_t *lexem)
312 } 331 }
313} 332}
314 333
315char *find_source_by_id(struct cmd_file_t *cmd_file, const char *id) 334static struct cmd_source_t *find_source_by_id(struct cmd_file_t *cmd_file, const char *id)
316{ 335{
317 struct cmd_source_t *src = cmd_file->source_list; 336 struct cmd_source_t *src = cmd_file->source_list;
318 while(src) 337 while(src)
319 { 338 {
320 if(strcmp(src->identifier, id) == 0) 339 if(strcmp(src->identifier, id) == 0)
321 return src->filename; 340 return src;
322 src = src->next; 341 src = src->next;
323 } 342 }
324 return NULL; 343 return NULL;
325} 344}
326 345
327struct cmd_file_t *read_command_file(const char *file) 346static struct cmd_file_t *read_command_file(const char *file)
328{ 347{
329 int size; 348 int size;
330 struct stat st; 349 struct stat st;
@@ -380,6 +399,7 @@ struct cmd_file_t *read_command_file(const char *file)
380 } 399 }
381 400
382 /* sections */ 401 /* sections */
402 struct cmd_section_t *end_sec = NULL;
383 while(true) 403 while(true)
384 { 404 {
385 struct cmd_section_t *sec = xmalloc(sizeof(struct cmd_section_t)); 405 struct cmd_section_t *sec = xmalloc(sizeof(struct cmd_section_t));
@@ -442,12 +462,184 @@ struct cmd_file_t *read_command_file(const char *file)
442 end_list = inst; 462 end_list = inst;
443 } 463 }
444 } 464 }
465
466 if(end_sec == NULL)
467 {
468 cmd_file->section_list = sec;
469 end_sec = sec;
470 }
471 else
472 {
473 end_sec->next = sec;
474 end_sec = sec;
475 }
445 } 476 }
446 #undef next 477 #undef next
447 478
448 return cmd_file; 479 return cmd_file;
449} 480}
450 481
482/**
483 * command file to sb conversion
484 */
485
486struct sb_inst_t
487{
488 uint8_t inst; /* SB_INST_* */
489 uint32_t size;
490 // <union>
491 void *data;
492 uint32_t pattern;
493 uint32_t addr;
494 // </union>
495};
496
497struct sb_section_t
498{
499 uint32_t identifier;
500 int nr_insts;
501 struct sb_inst_t *insts;
502};
503
504struct sb_file_t
505{
506 int nr_sections;
507 struct sb_section_t *sections;
508};
509
510static bool elf_read(void *user, uint32_t addr, void *buf, size_t count)
511{
512 if(lseek(*(int *)user, addr, SEEK_SET) == (off_t)-1)
513 return false;
514 return read(*(int *)user, buf, count) == (ssize_t)count;
515}
516
517static void elf_printf(void *user, bool error, const char *fmt, ...)
518{
519 if(!g_debug && !error)
520 return;
521 (void) user;
522 va_list args;
523 va_start(args, fmt);
524 vprintf(fmt, args);
525 va_end(args);
526}
527
528static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id)
529{
530 struct cmd_source_t *src = find_source_by_id(cmd_file, id);
531 if(src == NULL)
532 bug("undefined reference to source '%s'\n", id);
533 /* avoid reloading */
534 if(src->elf_loaded)
535 return;
536 int fd = open(src->filename, O_RDONLY);
537 if(fd < 0)
538 bug("cannot open '%s' (id '%s')\n", src->filename, id);
539 elf_init(&src->elf);
540 src->elf_loaded = elf_read_file(&src->elf, elf_read, elf_printf, &fd);
541 close(fd);
542 if(!src->elf_loaded)
543 bug("error loading elf file '%s' (id '%s')\n", src->filename, id);
544}
545
546static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
547{
548 struct sb_file_t *sb = xmalloc(sizeof(struct sb_file_t));
549 memset(sb, 0, sizeof(struct sb_file_t));
550 /* count sections */
551 struct cmd_section_t *csec = cmd_file->section_list;
552 while(csec)
553 {
554 sb->nr_sections++;
555 csec = csec->next;
556 }
557
558 sb->sections = xmalloc(sb->nr_sections * sizeof(struct sb_section_t));
559 memset(sb->sections, 0, sb->nr_sections * sizeof(struct sb_section_t));
560 /* flatten sections */
561 csec = cmd_file->section_list;
562 for(int i = 0; i < sb->nr_sections; i++, csec = csec->next)
563 {
564 struct sb_section_t *sec = &sb->sections[i];
565 sec->identifier = csec->identifier;
566 /* count instructions */
567 struct cmd_inst_t *cinst = csec->inst_list;
568 while(cinst)
569 {
570 load_elf_by_id(cmd_file, cinst->identifier);
571 struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf;
572
573 if(cinst->type == CMD_LOAD)
574 sec->nr_insts += elf_get_nr_sections(elf);
575 else if(cinst->type == CMD_JUMP || cinst->type == CMD_LOAD)
576 {
577 if(!elf_get_start_addr(elf, NULL))
578 bug("cannot jump/call '%s' because it has no starting point !", cinst->identifier);
579 sec->nr_insts++;
580 }
581
582 cinst = cinst->next;
583 }
584
585 sec->insts = xmalloc(sec->nr_insts * sizeof(struct sb_inst_t));
586 memset(sec->insts, 0, sec->nr_insts * sizeof(struct sb_inst_t));
587 /* flatten */
588 int idx = 0;
589 cinst = csec->inst_list;
590 while(cinst)
591 {
592 struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf;
593
594 if(cinst->type == CMD_LOAD)
595 {
596 struct elf_section_t *esec = elf->first_section;
597 while(esec)
598 {
599 if(esec->type == EST_LOAD)
600 {
601 sec->insts[idx].inst = SB_INST_LOAD;
602 sec->insts[idx].addr = esec->addr;
603 sec->insts[idx].size = esec->size;
604 sec->insts[idx++].data = esec->section;
605 if(g_debug)
606 printf("LOAD | addr=0x%08x | len=0x%08x | crc=0x%08x\n",
607 esec->addr, esec->size, 0);
608 }
609 else if(esec->type == EST_FILL)
610 {
611 sec->insts[idx].inst = SB_INST_FILL;
612 sec->insts[idx].addr = esec->addr;
613 sec->insts[idx].size = esec->size;
614 sec->insts[idx++].pattern = esec->pattern;
615 if(g_debug)
616 printf("FILL | addr=0x%08x | len=0x%08x | pattern=0x%08x\n",
617 esec->addr, esec->size, esec->pattern);
618 }
619 esec = esec->next;
620 }
621 }
622 else if(cinst->type == CMD_JUMP || cinst->type == CMD_LOAD)
623 {
624 sec->insts[idx].inst = (cinst->type == CMD_JUMP) ? SB_INST_JUMP : SB_INST_CALL;
625 sec->insts[idx++].addr = elf->start_addr;
626 if(g_debug)
627 printf("%s | addr=0x%08x | arg=0x%08x\n",
628 (cinst->type == CMD_JUMP) ? "JUMP" : "CALL",
629 elf->start_addr, 0);
630 }
631
632 cinst = cinst->next;
633 }
634 }
635
636 return sb;
637}
638
639/**
640 * Sb file production
641 */
642
451#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round)) 643#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round))
452 644
453static uint8_t instruction_checksum(struct sb_instruction_header_t *hdr) 645static uint8_t instruction_checksum(struct sb_instruction_header_t *hdr)
@@ -467,6 +659,7 @@ int main(int argc, const char **argv)
467 int nr_keys; 659 int nr_keys;
468 key_array_t key_array = read_keys(argv[2], &nr_keys); 660 key_array_t key_array = read_keys(argv[2], &nr_keys);
469 struct cmd_file_t *cmd_file = read_command_file(argv[1]); 661 struct cmd_file_t *cmd_file = read_command_file(argv[1]);
662 struct sb_file_t *sb_file = apply_cmd_file(cmd_file);
470 663
471 return 0; 664 return 0;
472} 665}
diff --git a/utils/sbtools/sbtoelf.c b/utils/sbtools/sbtoelf.c
index 3eb168ddd1..3a3d9a7bb7 100644
--- a/utils/sbtools/sbtoelf.c
+++ b/utils/sbtools/sbtoelf.c
@@ -183,7 +183,7 @@ static void extract_elf_section(struct elf_params_t *elf, int count, const char
183 183
184 if(fd == NULL) 184 if(fd == NULL)
185 return ; 185 return ;
186 elf_output(elf, elf_write, fd); 186 elf_write_file(elf, elf_write, fd);
187 fclose(fd); 187 fclose(fd);
188} 188}
189 189