summaryrefslogtreecommitdiffstats
path: root/utils
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 /utils
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
Diffstat (limited to 'utils')
-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,
void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
{
Elf32_Ehdr ehdr;
- uint32_t phoff = sizeof(Elf32_Ehdr);
- uint32_t phentsize = sizeof(Elf32_Phdr);
uint32_t phnum = 0;
- uint32_t shstrndx = SHN_UNDEF;
struct elf_section_t *sec = params->first_section;
uint32_t offset = 0;
Elf32_Phdr phdr;
+ Elf32_Shdr shdr;
+ memset(&ehdr, 0, EI_NIDENT);
+
+ uint32_t bss_strtbl = 0;
+ uint32_t text_strtbl = bss_strtbl + strlen(".bss") + 1;
+ uint32_t strtbl_size = text_strtbl + strlen(".text") + 1;
while(sec)
{
@@ -77,7 +80,8 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
sec = sec->next;
}
- memset(&ehdr, 0, EI_NIDENT);
+ uint32_t strtbl_offset = offset;
+
ehdr.e_ident[EI_MAG0] = ELFMAG0;
ehdr.e_ident[EI_MAG1] = ELFMAG1;
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)
ehdr.e_machine = EM_ARM;
ehdr.e_version = EV_CURRENT;
ehdr.e_entry = params->start_addr;
- ehdr.e_phoff = phoff;
- ehdr.e_shoff = 0;
ehdr.e_flags = 0;
if(params->has_start_addr)
ehdr.e_flags |= EF_ARM_HASENTRY;
ehdr.e_ehsize = sizeof ehdr;
- ehdr.e_phentsize = phentsize;
+ ehdr.e_phentsize = sizeof phdr;
ehdr.e_phnum = phnum;
- ehdr.e_shentsize = 0;
- ehdr.e_shnum = 0;
- ehdr.e_shstrndx = shstrndx;
+ ehdr.e_shentsize = sizeof shdr;
+ ehdr.e_shnum = phnum + 1;
+ ehdr.e_shstrndx = ehdr.e_shnum - 1;
+ ehdr.e_phoff = ehdr.e_ehsize;
+ ehdr.e_shoff = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize;
write(user, 0, &ehdr, sizeof ehdr);
+ uint32_t data_offset = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize +
+ ehdr.e_shnum * ehdr.e_shentsize;
+
sec = params->first_section;
- offset = phoff;
+ offset = ehdr.e_phoff;
while(sec)
{
- sec->offset += phoff + phnum * phentsize;
+ sec->offset += data_offset;
phdr.p_type = PT_LOAD;
if(sec->type == EST_LOAD)
@@ -133,12 +140,55 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
}
sec = params->first_section;
+ offset = ehdr.e_shoff;
+ while(sec)
+ {
+ shdr.sh_name = text_strtbl;
+ if(sec->type == EST_LOAD)
+ shdr.sh_type = SHT_PROGBITS;
+ else
+ shdr.sh_type = SHT_NOBITS;
+ shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR;
+ shdr.sh_addr = sec->addr;
+ shdr.sh_offset = sec->offset;
+ shdr.sh_size = sec->size;
+ shdr.sh_link = SHN_UNDEF;
+ shdr.sh_info = 0;
+ shdr.sh_addralign = 1;
+ shdr.sh_entsize = 0;
+
+ write(user, offset, &shdr, sizeof shdr);
+
+ offset += sizeof(Elf32_Shdr);
+ sec = sec->next;
+ }
+
+ {
+ shdr.sh_name = bss_strtbl;
+ shdr.sh_type = SHT_STRTAB;
+ shdr.sh_flags = 0;
+ shdr.sh_addr = 0;
+ shdr.sh_offset = strtbl_offset + data_offset;
+ shdr.sh_size = strtbl_size;
+ shdr.sh_link = SHN_UNDEF;
+ shdr.sh_info = 0;
+ shdr.sh_addralign = 1;
+ shdr.sh_entsize = 0;
+
+ write(user, offset, &shdr, sizeof shdr);
+
+ offset += sizeof(Elf32_Shdr);
+ }
+
+ sec = params->first_section;
while(sec)
{
if(sec->type == EST_LOAD)
write(user, sec->offset, sec->section, sec->size);
sec = sec->next;
}
+
+ write(user, strtbl_offset + data_offset, ".bss\0.text\0", strtbl_size);
}
bool 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
typedef struct
{
+ Elf32_Word sh_name; /* Section name (string tbl index) */
+ Elf32_Word sh_type; /* Section type */
+ Elf32_Word sh_flags; /* Section flags */
+ Elf32_Addr sh_addr; /* Section virtual addr at execution */
+ Elf32_Off sh_offset; /* Section file offset */
+ Elf32_Word sh_size; /* Section size in bytes */
+ Elf32_Word sh_link; /* Link to another section */
+ Elf32_Word sh_info; /* Additional section information */
+ Elf32_Word sh_addralign; /* Section alignment */
+ Elf32_Word sh_entsize; /* Entry size if section holds table */
+}Elf32_Shdr;
+
+#define SHT_NULL 0 /* Section header table entry unused */
+#define SHT_PROGBITS 1 /* Program data */
+#define SHT_SYMTAB 2 /* Symbol table */
+#define SHT_STRTAB 3 /* String table */
+#define SHT_RELA 4 /* Relocation entries with addends */
+#define SHT_HASH 5 /* Symbol hash table */
+#define SHT_DYNAMIC 6 /* Dynamic linking information */
+#define SHT_NOTE 7 /* Notes */
+#define SHT_NOBITS 8 /* Program space with no data (bss) */
+#define SHT_REL 9 /* Relocation entries, no addends */
+#define SHT_SHLIB 10 /* Reserved */
+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY 14 /* Array of constructors */
+#define SHT_FINI_ARRAY 15 /* Array of destructors */
+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
+#define SHT_GROUP 17 /* Section group */
+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
+#define SHT_NUM 19 /* Number of defined types. */
+
+#define SHF_WRITE (1 << 0) /* Writable */
+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
+#define SHF_EXECINSTR (1 << 2) /* Executable */
+#define SHF_MERGE (1 << 4) /* Might be merged */
+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
+
+typedef struct
+{
Elf32_Word p_type; /* Segment type */
Elf32_Off p_offset; /* Segment file offset */
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' };
/* byte swapping */
#define get32le(a) ((uint32_t) \
- ( buf[a+3] << 24 | buf[a+2] << 16 | buf[a+1] << 8 | buf[a] ))
-#define get16le(a) ((uint16_t)( buf[a+1] << 8 | buf[a] ))
+ ( g_buf[a+3] << 24 | g_buf[a+2] << 16 | g_buf[a+1] << 8 | g_buf[a] ))
+#define get16le(a) ((uint16_t)( g_buf[a+1] << 8 | g_buf[a] ))
/* all blocks are sized as a multiple of 0x1ff */
#define PAD_TO_BOUNDARY(x) (((x) + 0x1ff) & ~0x1ff)
@@ -74,8 +74,8 @@ char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
/* globals */
-size_t sz; /* file size */
-uint8_t *buf; /* file content */
+size_t g_sz; /* file size */
+uint8_t *g_buf; /* file content */
#define PREFIX_SIZE 128
char out_prefix[PREFIX_SIZE];
const char *key_file;
@@ -129,25 +129,23 @@ void *xmalloc(size_t s) /* malloc helper, used in elf.c */
static char getchr(int offset)
{
char c;
- c = buf[offset];
+ c = g_buf[offset];
return isprint(c) ? c : '_';
}
static void getstrle(char string[], int offset)
{
int i;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 4; i++)
string[i] = getchr(offset + 3 - i);
- }
string[4] = 0;
}
static void getstrbe(char string[], int offset)
{
int i;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 4; i++)
string[i] = getchr(offset + i);
- }
string[4] = 0;
}
@@ -155,9 +153,8 @@ static void printhex(int offset, int len)
{
int i;
- for (i = 0; i < len; i++) {
- printf("%02X ", buf[offset + i]);
- }
+ for (i = 0; i < len; i++)
+ printf("%02X ", g_buf[offset + i]);
printf("\n");
}
@@ -222,7 +219,7 @@ static key_array_t read_keys(int num_keys)
bugp("key file stat() failed");
size = st.st_size;
char *buf = xmalloc(size);
- if(read(fd,buf,sz)!=(ssize_t)size)
+ if(read(fd, buf, size) != (ssize_t)size)
bugp("reading key file");
close(fd);
@@ -417,13 +414,13 @@ static void extract(unsigned long filesize)
printf("Basic info:\n");
color(GREEN);
printf("\tHeader SHA-1: ");
- byte *hdr_sha1 = &buf[0];
+ byte *hdr_sha1 = &g_buf[0];
color(YELLOW);
print_sha1(hdr_sha1);
/* Check SHA1 sum */
byte computed_sha1[20];
sha_1_init(&sha_1_params);
- sha_1_update(&sha_1_params, &buf[0x14], 0x4C);
+ sha_1_update(&sha_1_params, &g_buf[0x14], 0x4C);
sha_1_finish(&sha_1_params);
sha_1_output(&sha_1_params, computed_sha1);
color(RED);
@@ -480,7 +477,7 @@ static void extract(unsigned long filesize)
if(num_enc > 0)
{
keys = read_keys(num_enc);
- color(BLUE),
+ color(BLUE);
printf("Encryption data\n");
for(int i = 0; i < num_enc; i++)
{
@@ -492,14 +489,14 @@ static void extract(unsigned long filesize)
printf("\t\tCBC-MAC of headers: ");
/* copy the cbc mac */
byte hdr_cbc_mac[16];
- memcpy(hdr_cbc_mac, &buf[0x60 + 16 * num_chunks + 32 * i], 16);
+ memcpy(hdr_cbc_mac, &g_buf[0x60 + 16 * num_chunks + 32 * i], 16);
color(YELLOW);
print_key(hdr_cbc_mac);
/* check it */
byte computed_cbc_mac[16];
byte zero[16];
memset(zero, 0, 16);
- cbc_mac(buf, NULL, 6 + num_chunks, keys[i], zero, &computed_cbc_mac, 1);
+ cbc_mac(g_buf, NULL, 6 + num_chunks, keys[i], zero, &computed_cbc_mac, 1);
color(RED);
if(memcmp(hdr_cbc_mac, computed_cbc_mac, 16) == 0)
printf(" Ok\n");
@@ -509,7 +506,7 @@ static void extract(unsigned long filesize)
printf("\t\tEncrypted key : ");
byte (*encrypted_key)[16];
- encrypted_key = (key_array_t)&buf[0x60 + 16 * num_chunks + 32 * i + 16];
+ encrypted_key = (key_array_t)&g_buf[0x60 + 16 * num_chunks + 32 * i + 16];
color(YELLOW);
print_key(*encrypted_key);
printf("\n");
@@ -517,7 +514,7 @@ static void extract(unsigned long filesize)
/* decrypt */
byte decrypted_key[16];
byte iv[16];
- memcpy(iv, buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */
+ memcpy(iv, g_buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */
cbc_mac(*encrypted_key, decrypted_key, 1, keys[i], iv, NULL, 0);
printf("\t\tDecrypted key : ");
color(YELLOW);
@@ -571,9 +568,9 @@ static void extract(unsigned long filesize)
/* save it */
byte *sec = xmalloc(size);
if(encrypted)
- cbc_mac(buf + pos, sec, size / 16, real_key, buf, NULL, 0);
+ cbc_mac(g_buf + pos, sec, size / 16, real_key, g_buf, NULL, 0);
else
- memcpy(sec, buf + pos, size);
+ memcpy(sec, g_buf + pos, size);
extract_section(data_sec, name, sec, size, "\t\t\t");
free(sec);
@@ -590,16 +587,16 @@ static void extract(unsigned long filesize)
printf("\t\t");
printhex(filesize - 16, 16);
/* decrypt it */
- byte *encrypted_block = &buf[filesize - 32];
+ byte *encrypted_block = &g_buf[filesize - 32];
byte decrypted_block[32];
- cbc_mac(encrypted_block, decrypted_block, 2, real_key, buf, NULL, 0);
+ cbc_mac(encrypted_block, decrypted_block, 2, real_key, g_buf, NULL, 0);
color(GREEN);
printf("\tDecrypted SHA-1:\n\t\t");
color(YELLOW);
print_sha1(decrypted_block);
/* check it */
sha_1_init(&sha_1_params);
- sha_1_update(&sha_1_params, buf, filesize - 32);
+ sha_1_update(&sha_1_params, g_buf, filesize - 32);
sha_1_finish(&sha_1_params);
sha_1_output(&sha_1_params, computed_sha1);
color(RED);
@@ -621,17 +618,17 @@ int main(int argc, const char **argv)
else
strcpy(out_prefix, "");
- if( (fd = open(argv[1],O_RDONLY)) == -1 )
+ if( (fd = open(argv[1], O_RDONLY)) == -1 )
bugp("opening firmware failed");
key_file = argv[2];
- if(fstat(fd,&st) == -1)
+ if(fstat(fd, &st) == -1)
bugp("firmware stat() failed");
- sz = st.st_size;
+ g_sz = st.st_size;
- buf=xmalloc(sz);
- if(read(fd,buf,sz)!=(ssize_t)sz) /* load the whole file into memory */
+ g_buf = xmalloc(g_sz);
+ if(read(fd, g_buf, g_sz) != (ssize_t)g_sz) /* load the whole file into memory */
bugp("reading firmware");
close(fd);
@@ -641,6 +638,6 @@ int main(int argc, const char **argv)
color(OFF);
- free(buf);
+ free(g_buf);
return 0;
}