diff --git a/core/loader/cmod.c b/core/loader/cmod.c new file mode 100644 index 000000000..1abc0f683 --- /dev/null +++ b/core/loader/cmod.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: cmod.c,v 1.1 2007/01/05 18:01:06 bg- Exp $ + */ + +#include +#include + +#include "contiki.h" + +#include "loader/cle.h" +#include "loader/cmod.h" + +#include "lib/malloc.h" + +#include "lib/assert.h" + +#if 1 +#define PRINTF(...) do {} while (0) +#else +#define PRINTF(...) printf(__VA_ARGS__) +#endif + +#ifndef CMOD_NMODULES +#define CMOD_NMODULES 4 +#endif +struct cmod_info cmod_module[CMOD_NMODULES]; + +int +cmod_load(unsigned imod, + cle_scratch scratch, + int (*pread)(void *, int, off_t), + off_t off) +{ + struct cle_info h; + int ret; + void (*init)(void); + + if(imod >= CMOD_NMODULES) { + PRINTF("imod to large"); + return 100; + } + + if(cmod_module[imod].ram != NULL || cmod_module[imod].fini != NULL) { + PRINTF("module busy\n"); + return 101; + } + + /* The (ELF) header is located at the start of the buffer. */ + ret = cle_read_info(&h, pread, off); + + if(ret != CLE_OK) { + strcpy(scratch, h.name); + return ret; + } + + cmod_module[imod].ram = malloc(h.datasize + h.bsssize + h.textsize); + if(cmod_module[imod].ram == NULL) { + return CMOD_DATA_TO_LARGE; + } + + /* + * Here we specify where we want to relocate to. + */ + h.data = cmod_module[imod].ram; + h.bss = h.data + h.datasize; + h.text = h.bss + h.bsssize; + + PRINTF("cmod: copy text segment to RAM %p %p\n", + h.text, h.text + h.textsize); + ret = pread(h.text, h.textsize, off + h.textoff); + assert(ret > 0); + if(h.textrelasize > 0) { + PRINTF("cmod: relocate text in RAM\n"); + ret = cle_relocate(&h, + pread, + off, + h.text, + h.textrelaoff, h.textrelasize); + if(ret != CLE_OK) { + strcpy(scratch, h.name); + return ret; + } + } + + PRINTF("cmod: copy data segment to RAM %p %p\n", + h.data, h.data + h.datasize); + ret = pread(h.data, h.datasize, off + h.dataoff); + assert(ret > 0); + if(h.datarelasize > 0) { + PRINTF("cmod: relocate data segment\n"); + ret = cle_relocate(&h, + pread, + off, + h.data, + h.datarelaoff, h.datarelasize); + if(ret != CLE_OK) { + strcpy(scratch, h.name); + return ret; + } + } + + PRINTF("cmod: zero bss %p %p\n", h.bss, h.bss + h.bsssize); + memset(h.bss, 0, h.bsssize); + + cmod_module[imod].fini = cle_lookup(&h, pread, off, "_fini"); + init = cle_lookup(&h, pread, off, "_init"); + + if(init != NULL) { + PRINTF("init=%p fini=%p\n", init, cmod_module[imod].fini); + (*init)(); + return CLE_OK; + } else + return CMOD_NO_STARTPOINT; +} + +void +cmod_unload(int imod) +{ + if(cmod_module[imod].fini != NULL) { + (*cmod_module[imod].fini)(); + cmod_module[imod].fini = NULL; + } + if(cmod_module[imod].ram != NULL) { + free(cmod_module[imod].ram); + cmod_module[imod].ram = NULL; + } +} + +#if 0 +void +cmod_status(void) +{ + unsigned i; + PRINTF("Id Module Address Fini\n"); + for(i = 0; i < CMOD_NMODULES; i++) + if(cmod_module[i].ram != NULL) + PRINTF("%2d %-8s %7p %4p\n", i, + cmod_module[i].name, cmod_module[i].ram, cmod_module[i].fini); +} +#endif diff --git a/core/loader/cmod.h b/core/loader/cmod.h new file mode 100644 index 000000000..68b213ba6 --- /dev/null +++ b/core/loader/cmod.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: cmod.h,v 1.1 2007/01/05 18:00:55 bg- Exp $ + */ + +#ifndef CMOD_H +#define CMOD_H + +struct cmod_info { + cle_addr ram; + /* cle_addr rom; */ + void (*fini)(void); +}; + +extern struct cmod_info cmod_module[]; + +int +cmod_load(unsigned imod, + cle_scratch name, + int (*pread)(void *, int, off_t), + off_t off); + +void cmod_unload(int imod); + +/* Most error codes are chared with elfloader and cle. */ +#define CMOD_OK 0 +#define CMOD_NO_STARTPOINT 7 +#define CMOD_DATA_TO_LARGE 9 + +#endif /* CMOD_H */