1
0
Fork 0
forked from len0rd/rockbox

rsrctool: produce an actually usuable entry list of the rsrc file

Change-Id: I6c8e5f3faf04741e4a13c1e705e9e869ccf8cfec
This commit is contained in:
Amaury Pouly 2012-12-02 11:48:57 +01:00
parent a6713a5e36
commit 9f19209c77
5 changed files with 73 additions and 14 deletions

View file

@ -84,6 +84,26 @@ void *augment_array(void *arr, size_t elem_sz, size_t cnt, void *aug, size_t aug
return p; return p;
} }
void augment_array_ex(void **arr, size_t elem_sz, int *cnt, int *capacity,
void *aug, int aug_cnt)
{
/* if capacity is not large enough, double it */
if(*cnt + aug_cnt > *capacity)
{
if(*capacity == 0)
*capacity = 1;
while(*cnt + aug_cnt > *capacity)
*capacity *= 2;
void *p = xmalloc(elem_sz * (*capacity));
memcpy(p, *arr, elem_sz * (*cnt));
free(*arr);
*arr = p;
}
/* copy elements */
memcpy(*arr + elem_sz * (*cnt), aug, elem_sz * aug_cnt);
*cnt += aug_cnt;
}
/** /**
* Key file parsing * Key file parsing
*/ */

View file

@ -41,6 +41,8 @@ key_array_t g_key_array;
void *memdup(const void *p, size_t len); void *memdup(const void *p, size_t len);
void *augment_array(void *arr, size_t elem_sz, size_t cnt, void *aug, size_t aug_cnt); void *augment_array(void *arr, size_t elem_sz, size_t cnt, void *aug, size_t aug_cnt);
void augment_array_ex(void **arr, size_t elem_sz, int *cnt, int *capacity,
void *aug, int aug_cnt);
void generate_random_data(void *buf, size_t sz); void generate_random_data(void *buf, size_t sz);
void *xmalloc(size_t s); void *xmalloc(size_t s);
int convxdigit(char digit, byte *val); int convxdigit(char digit, byte *val);

View file

@ -103,7 +103,7 @@ static const char *rsrc_table_entry_type_str(int type)
} }
} }
static bool read_entries(void *buf, int filesize, void *u, static bool read_entries(struct rsrc_file_t *f, void *u,
rsrc_color_printf cprintf, enum rsrc_error_t *err, rsrc_color_printf cprintf, enum rsrc_error_t *err,
int offset, uint32_t base_index, int level, char *prefix) int offset, uint32_t base_index, int level, char *prefix)
{ {
@ -113,24 +113,37 @@ static bool read_entries(void *buf, int filesize, void *u,
cprintf(u, true, GREY, __VA_ARGS__); \ cprintf(u, true, GREY, __VA_ARGS__); \
return e; } while(0) return e; } while(0)
if(offset >= filesize) if(offset >= f->size)
fatal(RSRC_FORMAT_ERROR, "Out of bounds at off=%x base=%x level=%d\n ouch\n"); fatal(RSRC_FORMAT_ERROR, "Out of bounds at off=%x base=%x level=%d\n ouch\n");
if(level < 0) if(level < 0)
fatal(RSRC_FORMAT_ERROR, "Out of levels at off=%x base=%x level=%d\n aie\n"); fatal(RSRC_FORMAT_ERROR, "Out of levels at off=%x base=%x level=%d\n aie\n");
for(int i = 0; i < 256; i++) for(int i = 0; i < 256; i++)
{ {
uint32_t te = *(uint32_t *)(buf + offset + 4 * i); uint32_t te = *(uint32_t *)(f->data + offset + 4 * i);
if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_NONE) if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_NONE)
continue; continue;
uint32_t sz = 0; uint32_t sz = 0;
uint32_t off_off = 0;
if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_VALUE) if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_VALUE)
sz = 2; sz = 2;
else if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_NESTED) else if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_NESTED)
sz = 4 * 256; sz = 4 * 256;
else else
sz = *(uint32_t *)(buf + RSRC_TABLE_ENTRY_OFFSET(te)); {
sz = *(uint32_t *)(f->data + RSRC_TABLE_ENTRY_OFFSET(te));
off_off = 4;
}
uint32_t index = base_index | i << (level * 8); uint32_t index = base_index | i << (level * 8);
struct rsrc_entry_t ent;
memset(&ent, 0, sizeof(ent));
ent.id = index;
ent.offset = RSRC_TABLE_ENTRY_OFFSET(te) + off_off;
ent.size = sz;
augment_array_ex((void **)&f->entries, sizeof(ent), &f->nr_entries, &f->capacity, &ent, 1);
printf(OFF, "%s+-%s%#08x %s[%s]%s[size=%#x]\n", prefix, YELLOW, index, BLUE, printf(OFF, "%s+-%s%#08x %s[%s]%s[size=%#x]\n", prefix, YELLOW, index, BLUE,
rsrc_table_entry_type_str(RSRC_TABLE_ENTRY_TYPE(te)), rsrc_table_entry_type_str(RSRC_TABLE_ENTRY_TYPE(te)),
GREEN, sz); GREEN, sz);
@ -140,7 +153,7 @@ static bool read_entries(void *buf, int filesize, void *u,
char *p = prefix + strlen(prefix); char *p = prefix + strlen(prefix);
sprintf(p, "%s| ", RED); sprintf(p, "%s| ", RED);
bool ok = read_entries(buf, filesize, u, cprintf, err, bool ok = read_entries(f, u, cprintf, err,
RSRC_TABLE_ENTRY_OFFSET(te), index, RSRC_TABLE_ENTRY_OFFSET(te), index,
level - 1, prefix); level - 1, prefix);
if(!ok) if(!ok)
@ -183,18 +196,17 @@ struct rsrc_file_t *rsrc_read_memory(void *_buf, size_t filesize, void *u,
fatal(RSRC_FORMAT_ERROR, "Missing RSRC signature\n"); fatal(RSRC_FORMAT_ERROR, "Missing RSRC signature\n");
} }
printf(BLUE, "Entries\n");
char prefix[1024];
sprintf(prefix, "%s", RED);
bool ok = read_entries(buf, filesize, u, cprintf, err,
RSRC_SECTOR_SIZE, 0, 3, prefix);
if(!ok)
fatal(*err, "Error while parsing rsrc table\n");
rsrc_file->data = malloc(filesize); rsrc_file->data = malloc(filesize);
memcpy(rsrc_file->data, _buf, filesize); memcpy(rsrc_file->data, _buf, filesize);
rsrc_file->size = filesize; rsrc_file->size = filesize;
printf(BLUE, "Entries\n");
char prefix[1024];
sprintf(prefix, "%s", RED);
bool ok = read_entries(rsrc_file, u, cprintf, err, RSRC_SECTOR_SIZE, 0, 3, prefix);
if(!ok)
fatal(*err, "Error while parsing rsrc table\n");
return rsrc_file; return rsrc_file;
#undef printf #undef printf
#undef fatal #undef fatal
@ -204,6 +216,8 @@ struct rsrc_file_t *rsrc_read_memory(void *_buf, size_t filesize, void *u,
void rsrc_free(struct rsrc_file_t *file) void rsrc_free(struct rsrc_file_t *file)
{ {
if(!file) return; if(!file) return;
free(file->data);
free(file->entries);
free(file); free(file);
} }

View file

@ -26,6 +26,10 @@
#include "misc.h" #include "misc.h"
/**
* Low-Level
**/
#define RSRC_SECTOR_SIZE 2048 #define RSRC_SECTOR_SIZE 2048
#define RSRC_TABLE_ENTRY_TYPE(e) ((e) >> 28) #define RSRC_TABLE_ENTRY_TYPE(e) ((e) >> 28)
@ -38,10 +42,25 @@
#define RSRC_TYPE_AUDIO 4 /* audio entry */ #define RSRC_TYPE_AUDIO 4 /* audio entry */
#define RSRC_TYPE_DATA 5 /* data entry */ #define RSRC_TYPE_DATA 5 /* data entry */
/**
* API
**/
struct rsrc_entry_t
{
uint32_t id;
uint32_t offset; // contains value of RSRC_TYPE_VALUE
int size;
};
struct rsrc_file_t struct rsrc_file_t
{ {
void *data; void *data;
int size; int size;
int nr_entries;
int capacity;
struct rsrc_entry_t *entries;
}; };
enum rsrc_error_t enum rsrc_error_t

View file

@ -52,7 +52,7 @@ char *g_out_prefix;
static void extract_rsrc_file(struct rsrc_file_t *file) static void extract_rsrc_file(struct rsrc_file_t *file)
{ {
(void) file;
} }
static void usage(void) static void usage(void)
@ -76,6 +76,8 @@ static void rsrc_printf(void *user, bool error, color_t c, const char *fmt, ...)
{ {
(void) user; (void) user;
(void) error; (void) error;
if(!g_debug)
return;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
color(c); color(c);
@ -176,6 +178,8 @@ int main(int argc, char **argv)
printf("RSRC read failed: %d\n", err); printf("RSRC read failed: %d\n", err);
return 1; return 1;
} }
if(g_debug)
printf("%d entries read from file\n", file->nr_entries);
color(OFF); color(OFF);
if(g_out_prefix) if(g_out_prefix)