summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-03-03 09:22:32 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-03-03 09:22:32 +0000
commitf85c04469ea397f73e86161966fae7ffd84560e2 (patch)
treed462cdf34fc003bb59504ea2a8325bded4757377
parent708f5508adfdeb5763a5fb918488e83e20324437 (diff)
downloadrockbox-f85c04469ea397f73e86161966fae7ffd84560e2.tar.gz
rockbox-f85c04469ea397f73e86161966fae7ffd84560e2.zip
sbinfo: fix a few typos (thanks to Kane Xie), correct coding style, now generate segments along with program sections to make elf files appear more valid (this allows to rebuild an .sb file using elftosb2)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29510 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--utils/sbinfo/elf.c74
-rw-r--r--utils/sbinfo/elf.h39
-rw-r--r--utils/sbinfo/sbinfo.c59
3 files changed, 129 insertions, 43 deletions
diff --git a/utils/sbinfo/elf.c b/utils/sbinfo/elf.c
index 0fe6792e1d..6c5ed2e762 100644
--- a/utils/sbinfo/elf.c
+++ b/utils/sbinfo/elf.c
@@ -57,13 +57,16 @@ void elf_add_fill_section(struct elf_params_t *params,
57void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user) 57void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
58{ 58{
59 Elf32_Ehdr ehdr; 59 Elf32_Ehdr ehdr;
60 uint32_t phoff = sizeof(Elf32_Ehdr);
61 uint32_t phentsize = sizeof(Elf32_Phdr);
62 uint32_t phnum = 0; 60 uint32_t phnum = 0;
63 uint32_t shstrndx = SHN_UNDEF;
64 struct elf_section_t *sec = params->first_section; 61 struct elf_section_t *sec = params->first_section;
65 uint32_t offset = 0; 62 uint32_t offset = 0;
66 Elf32_Phdr phdr; 63 Elf32_Phdr phdr;
64 Elf32_Shdr shdr;
65 memset(&ehdr, 0, EI_NIDENT);
66
67 uint32_t bss_strtbl = 0;
68 uint32_t text_strtbl = bss_strtbl + strlen(".bss") + 1;
69 uint32_t strtbl_size = text_strtbl + strlen(".text") + 1;
67 70
68 while(sec) 71 while(sec)
69 { 72 {
@@ -77,7 +80,8 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
77 sec = sec->next; 80 sec = sec->next;
78 } 81 }
79 82
80 memset(&ehdr, 0, EI_NIDENT); 83 uint32_t strtbl_offset = offset;
84
81 ehdr.e_ident[EI_MAG0] = ELFMAG0; 85 ehdr.e_ident[EI_MAG0] = ELFMAG0;
82 ehdr.e_ident[EI_MAG1] = ELFMAG1; 86 ehdr.e_ident[EI_MAG1] = ELFMAG1;
83 ehdr.e_ident[EI_MAG2] = ELFMAG2; 87 ehdr.e_ident[EI_MAG2] = ELFMAG2;
@@ -91,25 +95,28 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
91 ehdr.e_machine = EM_ARM; 95 ehdr.e_machine = EM_ARM;
92 ehdr.e_version = EV_CURRENT; 96 ehdr.e_version = EV_CURRENT;
93 ehdr.e_entry = params->start_addr; 97 ehdr.e_entry = params->start_addr;
94 ehdr.e_phoff = phoff;
95 ehdr.e_shoff = 0;
96 ehdr.e_flags = 0; 98 ehdr.e_flags = 0;
97 if(params->has_start_addr) 99 if(params->has_start_addr)
98 ehdr.e_flags |= EF_ARM_HASENTRY; 100 ehdr.e_flags |= EF_ARM_HASENTRY;
99 ehdr.e_ehsize = sizeof ehdr; 101 ehdr.e_ehsize = sizeof ehdr;
100 ehdr.e_phentsize = phentsize; 102 ehdr.e_phentsize = sizeof phdr;
101 ehdr.e_phnum = phnum; 103 ehdr.e_phnum = phnum;
102 ehdr.e_shentsize = 0; 104 ehdr.e_shentsize = sizeof shdr;
103 ehdr.e_shnum = 0; 105 ehdr.e_shnum = phnum + 1;
104 ehdr.e_shstrndx = shstrndx; 106 ehdr.e_shstrndx = ehdr.e_shnum - 1;
107 ehdr.e_phoff = ehdr.e_ehsize;
108 ehdr.e_shoff = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize;
105 109
106 write(user, 0, &ehdr, sizeof ehdr); 110 write(user, 0, &ehdr, sizeof ehdr);
107 111
112 uint32_t data_offset = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize +
113 ehdr.e_shnum * ehdr.e_shentsize;
114
108 sec = params->first_section; 115 sec = params->first_section;
109 offset = phoff; 116 offset = ehdr.e_phoff;
110 while(sec) 117 while(sec)
111 { 118 {
112 sec->offset += phoff + phnum * phentsize; 119 sec->offset += data_offset;
113 120
114 phdr.p_type = PT_LOAD; 121 phdr.p_type = PT_LOAD;
115 if(sec->type == EST_LOAD) 122 if(sec->type == EST_LOAD)
@@ -133,12 +140,55 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
133 } 140 }
134 141
135 sec = params->first_section; 142 sec = params->first_section;
143 offset = ehdr.e_shoff;
144 while(sec)
145 {
146 shdr.sh_name = text_strtbl;
147 if(sec->type == EST_LOAD)
148 shdr.sh_type = SHT_PROGBITS;
149 else
150 shdr.sh_type = SHT_NOBITS;
151 shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR;
152 shdr.sh_addr = sec->addr;
153 shdr.sh_offset = sec->offset;
154 shdr.sh_size = sec->size;
155 shdr.sh_link = SHN_UNDEF;
156 shdr.sh_info = 0;
157 shdr.sh_addralign = 1;
158 shdr.sh_entsize = 0;
159
160 write(user, offset, &shdr, sizeof shdr);
161
162 offset += sizeof(Elf32_Shdr);
163 sec = sec->next;
164 }
165
166 {
167 shdr.sh_name = bss_strtbl;
168 shdr.sh_type = SHT_STRTAB;
169 shdr.sh_flags = 0;
170 shdr.sh_addr = 0;
171 shdr.sh_offset = strtbl_offset + data_offset;
172 shdr.sh_size = strtbl_size;
173 shdr.sh_link = SHN_UNDEF;
174 shdr.sh_info = 0;
175 shdr.sh_addralign = 1;
176 shdr.sh_entsize = 0;
177
178 write(user, offset, &shdr, sizeof shdr);
179
180 offset += sizeof(Elf32_Shdr);
181 }
182
183 sec = params->first_section;
136 while(sec) 184 while(sec)
137 { 185 {
138 if(sec->type == EST_LOAD) 186 if(sec->type == EST_LOAD)
139 write(user, sec->offset, sec->section, sec->size); 187 write(user, sec->offset, sec->section, sec->size);
140 sec = sec->next; 188 sec = sec->next;
141 } 189 }
190
191 write(user, strtbl_offset + data_offset, ".bss\0.text\0", strtbl_size);
142} 192}
143 193
144bool elf_is_empty(struct elf_params_t *params) 194bool elf_is_empty(struct elf_params_t *params)
diff --git a/utils/sbinfo/elf.h b/utils/sbinfo/elf.h
index eb990389d9..d2bf210c5c 100644
--- a/utils/sbinfo/elf.h
+++ b/utils/sbinfo/elf.h
@@ -80,6 +80,45 @@ typedef struct
80 80
81typedef struct 81typedef struct
82{ 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{
83 Elf32_Word p_type; /* Segment type */ 122 Elf32_Word p_type; /* Segment type */
84 Elf32_Off p_offset; /* Segment file offset */ 123 Elf32_Off p_offset; /* Segment file offset */
85 Elf32_Addr p_vaddr; /* Segment virtual address */ 124 Elf32_Addr p_vaddr; /* Segment virtual address */
diff --git a/utils/sbinfo/sbinfo.c b/utils/sbinfo/sbinfo.c
index d065fc9eed..710c481deb 100644
--- a/utils/sbinfo/sbinfo.c
+++ b/utils/sbinfo/sbinfo.c
@@ -63,8 +63,8 @@ char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
63 63
64/* byte swapping */ 64/* byte swapping */
65#define get32le(a) ((uint32_t) \ 65#define get32le(a) ((uint32_t) \
66 ( buf[a+3] << 24 | buf[a+2] << 16 | buf[a+1] << 8 | buf[a] )) 66 ( g_buf[a+3] << 24 | g_buf[a+2] << 16 | g_buf[a+1] << 8 | g_buf[a] ))
67#define get16le(a) ((uint16_t)( buf[a+1] << 8 | buf[a] )) 67#define get16le(a) ((uint16_t)( g_buf[a+1] << 8 | g_buf[a] ))
68 68
69/* all blocks are sized as a multiple of 0x1ff */ 69/* all blocks are sized as a multiple of 0x1ff */
70#define PAD_TO_BOUNDARY(x) (((x) + 0x1ff) & ~0x1ff) 70#define PAD_TO_BOUNDARY(x) (((x) + 0x1ff) & ~0x1ff)
@@ -74,8 +74,8 @@ char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
74 74
75/* globals */ 75/* globals */
76 76
77size_t sz; /* file size */ 77size_t g_sz; /* file size */
78uint8_t *buf; /* file content */ 78uint8_t *g_buf; /* file content */
79#define PREFIX_SIZE 128 79#define PREFIX_SIZE 128
80char out_prefix[PREFIX_SIZE]; 80char out_prefix[PREFIX_SIZE];
81const char *key_file; 81const char *key_file;
@@ -129,25 +129,23 @@ void *xmalloc(size_t s) /* malloc helper, used in elf.c */
129static char getchr(int offset) 129static char getchr(int offset)
130{ 130{
131 char c; 131 char c;
132 c = buf[offset]; 132 c = g_buf[offset];
133 return isprint(c) ? c : '_'; 133 return isprint(c) ? c : '_';
134} 134}
135 135
136static void getstrle(char string[], int offset) 136static void getstrle(char string[], int offset)
137{ 137{
138 int i; 138 int i;
139 for (i = 0; i < 4; i++) { 139 for (i = 0; i < 4; i++)
140 string[i] = getchr(offset + 3 - i); 140 string[i] = getchr(offset + 3 - i);
141 }
142 string[4] = 0; 141 string[4] = 0;
143} 142}
144 143
145static void getstrbe(char string[], int offset) 144static void getstrbe(char string[], int offset)
146{ 145{
147 int i; 146 int i;
148 for (i = 0; i < 4; i++) { 147 for (i = 0; i < 4; i++)
149 string[i] = getchr(offset + i); 148 string[i] = getchr(offset + i);
150 }
151 string[4] = 0; 149 string[4] = 0;
152} 150}
153 151
@@ -155,9 +153,8 @@ static void printhex(int offset, int len)
155{ 153{
156 int i; 154 int i;
157 155
158 for (i = 0; i < len; i++) { 156 for (i = 0; i < len; i++)
159 printf("%02X ", buf[offset + i]); 157 printf("%02X ", g_buf[offset + i]);
160 }
161 printf("\n"); 158 printf("\n");
162} 159}
163 160
@@ -222,7 +219,7 @@ static key_array_t read_keys(int num_keys)
222 bugp("key file stat() failed"); 219 bugp("key file stat() failed");
223 size = st.st_size; 220 size = st.st_size;
224 char *buf = xmalloc(size); 221 char *buf = xmalloc(size);
225 if(read(fd,buf,sz)!=(ssize_t)size) 222 if(read(fd, buf, size) != (ssize_t)size)
226 bugp("reading key file"); 223 bugp("reading key file");
227 close(fd); 224 close(fd);
228 225
@@ -417,13 +414,13 @@ static void extract(unsigned long filesize)
417 printf("Basic info:\n"); 414 printf("Basic info:\n");
418 color(GREEN); 415 color(GREEN);
419 printf("\tHeader SHA-1: "); 416 printf("\tHeader SHA-1: ");
420 byte *hdr_sha1 = &buf[0]; 417 byte *hdr_sha1 = &g_buf[0];
421 color(YELLOW); 418 color(YELLOW);
422 print_sha1(hdr_sha1); 419 print_sha1(hdr_sha1);
423 /* Check SHA1 sum */ 420 /* Check SHA1 sum */
424 byte computed_sha1[20]; 421 byte computed_sha1[20];
425 sha_1_init(&sha_1_params); 422 sha_1_init(&sha_1_params);
426 sha_1_update(&sha_1_params, &buf[0x14], 0x4C); 423 sha_1_update(&sha_1_params, &g_buf[0x14], 0x4C);
427 sha_1_finish(&sha_1_params); 424 sha_1_finish(&sha_1_params);
428 sha_1_output(&sha_1_params, computed_sha1); 425 sha_1_output(&sha_1_params, computed_sha1);
429 color(RED); 426 color(RED);
@@ -480,7 +477,7 @@ static void extract(unsigned long filesize)
480 if(num_enc > 0) 477 if(num_enc > 0)
481 { 478 {
482 keys = read_keys(num_enc); 479 keys = read_keys(num_enc);
483 color(BLUE), 480 color(BLUE);
484 printf("Encryption data\n"); 481 printf("Encryption data\n");
485 for(int i = 0; i < num_enc; i++) 482 for(int i = 0; i < num_enc; i++)
486 { 483 {
@@ -492,14 +489,14 @@ static void extract(unsigned long filesize)
492 printf("\t\tCBC-MAC of headers: "); 489 printf("\t\tCBC-MAC of headers: ");
493 /* copy the cbc mac */ 490 /* copy the cbc mac */
494 byte hdr_cbc_mac[16]; 491 byte hdr_cbc_mac[16];
495 memcpy(hdr_cbc_mac, &buf[0x60 + 16 * num_chunks + 32 * i], 16); 492 memcpy(hdr_cbc_mac, &g_buf[0x60 + 16 * num_chunks + 32 * i], 16);
496 color(YELLOW); 493 color(YELLOW);
497 print_key(hdr_cbc_mac); 494 print_key(hdr_cbc_mac);
498 /* check it */ 495 /* check it */
499 byte computed_cbc_mac[16]; 496 byte computed_cbc_mac[16];
500 byte zero[16]; 497 byte zero[16];
501 memset(zero, 0, 16); 498 memset(zero, 0, 16);
502 cbc_mac(buf, NULL, 6 + num_chunks, keys[i], zero, &computed_cbc_mac, 1); 499 cbc_mac(g_buf, NULL, 6 + num_chunks, keys[i], zero, &computed_cbc_mac, 1);
503 color(RED); 500 color(RED);
504 if(memcmp(hdr_cbc_mac, computed_cbc_mac, 16) == 0) 501 if(memcmp(hdr_cbc_mac, computed_cbc_mac, 16) == 0)
505 printf(" Ok\n"); 502 printf(" Ok\n");
@@ -509,7 +506,7 @@ static void extract(unsigned long filesize)
509 506
510 printf("\t\tEncrypted key : "); 507 printf("\t\tEncrypted key : ");
511 byte (*encrypted_key)[16]; 508 byte (*encrypted_key)[16];
512 encrypted_key = (key_array_t)&buf[0x60 + 16 * num_chunks + 32 * i + 16]; 509 encrypted_key = (key_array_t)&g_buf[0x60 + 16 * num_chunks + 32 * i + 16];
513 color(YELLOW); 510 color(YELLOW);
514 print_key(*encrypted_key); 511 print_key(*encrypted_key);
515 printf("\n"); 512 printf("\n");
@@ -517,7 +514,7 @@ static void extract(unsigned long filesize)
517 /* decrypt */ 514 /* decrypt */
518 byte decrypted_key[16]; 515 byte decrypted_key[16];
519 byte iv[16]; 516 byte iv[16];
520 memcpy(iv, buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */ 517 memcpy(iv, g_buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */
521 cbc_mac(*encrypted_key, decrypted_key, 1, keys[i], iv, NULL, 0); 518 cbc_mac(*encrypted_key, decrypted_key, 1, keys[i], iv, NULL, 0);
522 printf("\t\tDecrypted key : "); 519 printf("\t\tDecrypted key : ");
523 color(YELLOW); 520 color(YELLOW);
@@ -571,9 +568,9 @@ static void extract(unsigned long filesize)
571 /* save it */ 568 /* save it */
572 byte *sec = xmalloc(size); 569 byte *sec = xmalloc(size);
573 if(encrypted) 570 if(encrypted)
574 cbc_mac(buf + pos, sec, size / 16, real_key, buf, NULL, 0); 571 cbc_mac(g_buf + pos, sec, size / 16, real_key, g_buf, NULL, 0);
575 else 572 else
576 memcpy(sec, buf + pos, size); 573 memcpy(sec, g_buf + pos, size);
577 574
578 extract_section(data_sec, name, sec, size, "\t\t\t"); 575 extract_section(data_sec, name, sec, size, "\t\t\t");
579 free(sec); 576 free(sec);
@@ -590,16 +587,16 @@ static void extract(unsigned long filesize)
590 printf("\t\t"); 587 printf("\t\t");
591 printhex(filesize - 16, 16); 588 printhex(filesize - 16, 16);
592 /* decrypt it */ 589 /* decrypt it */
593 byte *encrypted_block = &buf[filesize - 32]; 590 byte *encrypted_block = &g_buf[filesize - 32];
594 byte decrypted_block[32]; 591 byte decrypted_block[32];
595 cbc_mac(encrypted_block, decrypted_block, 2, real_key, buf, NULL, 0); 592 cbc_mac(encrypted_block, decrypted_block, 2, real_key, g_buf, NULL, 0);
596 color(GREEN); 593 color(GREEN);
597 printf("\tDecrypted SHA-1:\n\t\t"); 594 printf("\tDecrypted SHA-1:\n\t\t");
598 color(YELLOW); 595 color(YELLOW);
599 print_sha1(decrypted_block); 596 print_sha1(decrypted_block);
600 /* check it */ 597 /* check it */
601 sha_1_init(&sha_1_params); 598 sha_1_init(&sha_1_params);
602 sha_1_update(&sha_1_params, buf, filesize - 32); 599 sha_1_update(&sha_1_params, g_buf, filesize - 32);
603 sha_1_finish(&sha_1_params); 600 sha_1_finish(&sha_1_params);
604 sha_1_output(&sha_1_params, computed_sha1); 601 sha_1_output(&sha_1_params, computed_sha1);
605 color(RED); 602 color(RED);
@@ -621,17 +618,17 @@ int main(int argc, const char **argv)
621 else 618 else
622 strcpy(out_prefix, ""); 619 strcpy(out_prefix, "");
623 620
624 if( (fd = open(argv[1],O_RDONLY)) == -1 ) 621 if( (fd = open(argv[1], O_RDONLY)) == -1 )
625 bugp("opening firmware failed"); 622 bugp("opening firmware failed");
626 623
627 key_file = argv[2]; 624 key_file = argv[2];
628 625
629 if(fstat(fd,&st) == -1) 626 if(fstat(fd, &st) == -1)
630 bugp("firmware stat() failed"); 627 bugp("firmware stat() failed");
631 sz = st.st_size; 628 g_sz = st.st_size;
632 629
633 buf=xmalloc(sz); 630 g_buf = xmalloc(g_sz);
634 if(read(fd,buf,sz)!=(ssize_t)sz) /* load the whole file into memory */ 631 if(read(fd, g_buf, g_sz) != (ssize_t)g_sz) /* load the whole file into memory */
635 bugp("reading firmware"); 632 bugp("reading firmware");
636 633
637 close(fd); 634 close(fd);
@@ -641,6 +638,6 @@ int main(int argc, const char **argv)
641 638
642 color(OFF); 639 color(OFF);
643 640
644 free(buf); 641 free(g_buf);
645 return 0; 642 return 0;
646} 643}