[app][loader] Odds and ends

- Fix a bug when doing bounds checking
- Don't run elf if the entrypoint is out of bounds
- Allow to specify the memory slot to download (slot is 512K)
- Default slot for elf is 1, 3 and for data is 0, 2
This commit is contained in:
Carlos Pizano
2015-09-23 12:46:43 -07:00
parent 065b344a7d
commit 13a1d4f530

View File

@@ -40,13 +40,13 @@
#endif
#if defined(SDRAM_BASE)
static unsigned char* download_start = (void*)SDRAM_BASE;
#define DOWNLOAD_BASE ((void*)SDRAM_BASE)
#else
static unsigned char* download_start = NULL;
#define DOWNLOAD_BASE ((void*)0)
#endif
#define FNAME_SIZE 64
#define DOWNLOAD_SLOT_SIZE (128 * 1024)
#define DOWNLOAD_SLOT_SIZE (512 * 1024)
typedef enum {
DOWNLOAD_ANY,
@@ -63,15 +63,17 @@ typedef struct {
static download_t* make_download(const char* name)
{
download_t* s = malloc(sizeof(download_t));
s->start = download_start;
s->end = s->start;
s->max = download_start + DOWNLOAD_SLOT_SIZE;
strncpy(s->name, name, FNAME_SIZE);
download_t* d = malloc(sizeof(download_t));
memset(d, 0, sizeof(download_t));
strncpy(d->name, name, FNAME_SIZE);
return d;
}
download_start = s->max;
memset(s->start, 0, DOWNLOAD_SLOT_SIZE);
return s;
static void set_ram_zone(download_t* d, int slot) {
d->start = DOWNLOAD_BASE + (DOWNLOAD_SLOT_SIZE * slot);
d->end = d->start;
d->max = d->end + DOWNLOAD_SLOT_SIZE;
memset(d->start, 0, DOWNLOAD_SLOT_SIZE);
}
static size_t output_result(const download_t* download)
@@ -95,7 +97,9 @@ static int run_elf(void* entry_point)
static void process_elf_blob(const void* start, size_t len)
{
void* entrypt;
elf_handle_t elf;
status_t st = elf_open_handle_memory(&elf, start, len);
if (st < 0) {
printf("unable to open elf handle\n");
@@ -105,13 +109,19 @@ static void process_elf_blob(const void* start, size_t len)
st = elf_load(&elf);
if (st < 0) {
printf("elf processing failed, status : %d\n", st);
elf_close_handle(&elf);
return;
goto exit;
}
entrypt = (void*)elf.entry;
if (entrypt < start || entrypt >= (void*)((char*)start + len)) {
printf("out of bounds entrypoint for elf : %p\n", entrypt);
goto exit;
}
printf("elf looks good\n");
thread_resume(thread_create("elf_runner", &run_elf, (void*)elf.entry,
thread_resume(thread_create("elf_runner", &run_elf, entrypt,
DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
exit:
elf_close_handle(&elf);
}
@@ -130,7 +140,7 @@ int tftp_callback(void* data, size_t len, void* arg)
return 0;
}
if ((download->start + len) > download->max) {
if ((download->end + len) > download->max) {
printf("transfer too big, aborting\n");
return -1;
}
@@ -143,17 +153,22 @@ int tftp_callback(void* data, size_t len, void* arg)
static int loader(int argc, const cmd_args *argv)
{
download_t* download;
static int any_slot = 0;
static int elf_slot = 1;
if (!download_start) {
download_t* download;
int slot;
if (!DOWNLOAD_BASE) {
printf("loader not available. it needs sdram\n");
return 0;
}
if (argc != 3) {
if (argc < 3) {
usage:
printf("load any [filename]\n" \
"load elf [filename]\n");
printf("load any [filename] <slot>\n"
"load elf [filename] <slot>\n"
"protocol is tftp and <slot> is optional\n");
return 0;
}
@@ -161,14 +176,23 @@ usage:
if (strcmp(argv[1].str, "any") == 0) {
download->type = DOWNLOAD_ANY;
slot = any_slot;
any_slot += 2;
} else if (strcmp(argv[1].str, "elf") == 0) {
download->type = DOWNLOAD_ELF;
slot = elf_slot;
elf_slot += 2;
} else {
goto usage;
}
if (argc == 4) {
slot = argv[3].i;
}
set_ram_zone(download, slot);
tftp_set_write_client(download->name, &tftp_callback, download);
printf("ready for %s over tftp\n", argv[2].str);
printf("ready for %s over tftp (at %p)\n", argv[2].str, download->start);
return 0;
}