forked from len0rd/rockbox
rsrctool: produce an actually usuable entry list of the rsrc file
Change-Id: I6c8e5f3faf04741e4a13c1e705e9e869ccf8cfec
This commit is contained in:
parent
a6713a5e36
commit
9f19209c77
5 changed files with 73 additions and 14 deletions
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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,17 +196,16 @@ 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
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue