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;
}
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
*/

View file

@ -41,6 +41,8 @@ key_array_t g_key_array;
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_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 *xmalloc(size_t s);
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,
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__); \
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");
if(level < 0)
fatal(RSRC_FORMAT_ERROR, "Out of levels at off=%x base=%x level=%d\n aie\n");
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)
continue;
uint32_t sz = 0;
uint32_t off_off = 0;
if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_VALUE)
sz = 2;
else if(RSRC_TABLE_ENTRY_TYPE(te) == RSRC_TYPE_NESTED)
sz = 4 * 256;
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);
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,
rsrc_table_entry_type_str(RSRC_TABLE_ENTRY_TYPE(te)),
GREEN, sz);
@ -140,7 +153,7 @@ static bool read_entries(void *buf, int filesize, void *u,
char *p = prefix + strlen(prefix);
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,
level - 1, prefix);
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");
}
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);
memcpy(rsrc_file->data, _buf, 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;
#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)
{
if(!file) return;
free(file->data);
free(file->entries);
free(file);
}

View file

@ -26,6 +26,10 @@
#include "misc.h"
/**
* Low-Level
**/
#define RSRC_SECTOR_SIZE 2048
#define RSRC_TABLE_ENTRY_TYPE(e) ((e) >> 28)
@ -38,10 +42,25 @@
#define RSRC_TYPE_AUDIO 4 /* audio 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
{
void *data;
int size;
int nr_entries;
int capacity;
struct rsrc_entry_t *entries;
};
enum rsrc_error_t

View file

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