From 9f106aa6fca3620c41fed53a0672c69f687f97d5 Mon Sep 17 00:00:00 2001 From: bg- Date: Thu, 26 Apr 2007 13:37:28 +0000 Subject: [PATCH] * Rename cle_upd_reloc to cle_write_reloc and changed first arg to point to position to be updated. * Factor cle.c into multiple files. --- core/loader/cle.c | 150 +-------------------------------- core/loader/cle.h | 6 +- core/loader/cle_avr.c | 178 +++++++++++++++++++++++++++++++++++++++ core/loader/cle_msp430.c | 63 ++++++++++++++ core/loader/cmod.c | 3 +- 5 files changed, 251 insertions(+), 149 deletions(-) create mode 100644 core/loader/cle_avr.c create mode 100644 core/loader/cle_msp430.c diff --git a/core/loader/cle.c b/core/loader/cle.c index c4e07c851..5ae3ad53a 100644 --- a/core/loader/cle.c +++ b/core/loader/cle.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)$Id: cle.c,v 1.5 2007/04/26 12:52:52 bg- Exp $ + * @(#)$Id: cle.c,v 1.6 2007/04/26 13:37:28 bg- Exp $ */ /* @@ -38,8 +38,8 @@ #include "contiki.h" -#include "loader/cle.h" #include "loader/elf32.h" +#include "loader/cle.h" #include "loader/sym.h" #define NDEBUG @@ -185,25 +185,6 @@ cle_read_info(struct cle_info *info, return CLE_OK; } -/* - * Update one reloc. - * - * Writing relocs is machine dependent and this function is MSP430 - * specific! - */ -#ifdef __MSP430__ -static inline int -cle_upd_reloc(unsigned char *segmem, struct elf32_rela *rela, cle_addr addr) -{ - memcpy((char *)segmem + rela->r_offset, &addr, 2); /* Write reloc */ - return CLE_OK; -} -#else -static int -cle_upd_reloc(unsigned char *segmem, struct elf32_rela *rela, cle_addr addr); -#endif - - /* * Relocate one segment that has been copied to the location pointed * to by segmem. @@ -279,7 +260,7 @@ cle_relocate(struct cle_info *info, addr += rela.r_addend; - ret = cle_upd_reloc(segmem, &rela, addr); + ret = cle_write_reloc(segmem + rela.r_offset, &rela, addr); if(ret != CLE_OK) { return ret; } @@ -335,128 +316,3 @@ cle_lookup(struct cle_info *info, } return NULL; } - -#if defined(__AVR__) && defined(__GNUC__) -#define R_AVR_NONE 0 -#define R_AVR_32 1 -#define R_AVR_7_PCREL 2 -#define R_AVR_13_PCREL 3 -#define R_AVR_16 4 -#define R_AVR_16_PM 5 -#define R_AVR_LO8_LDI 6 -#define R_AVR_HI8_LDI 7 -#define R_AVR_HH8_LDI 8 -#define R_AVR_LO8_LDI_NEG 9 -#define R_AVR_HI8_LDI_NEG 10 -#define R_AVR_HH8_LDI_NEG 11 -#define R_AVR_LO8_LDI_PM 12 -#define R_AVR_HI8_LDI_PM 13 -#define R_AVR_HH8_LDI_PM 14 -#define R_AVR_LO8_LDI_PM_NEG 15 -#define R_AVR_HI8_LDI_PM_NEG 16 -#define R_AVR_HH8_LDI_PM_NEG 17 -#define R_AVR_CALL 18 - -static int -cle_upd_reloc(unsigned char *segmem, struct elf32_rela *rela, cle_addr addr) -{ - unsigned char *instr = segmem + rela->r_offset; - unsigned char byte; - - switch(ELF32_R_TYPE(rela->r_info)) { - default: - PRINTF("cle_upd_reloc: unsupported relocation type: %d\n", - ELF32_R_TYPE(rela->r_info)); - return CLE_UNKNOWN_RELOC; - -#if VERIFY_BEFORE_ENABLE - case R_AVR_7_PCREL: /* 2 */ - /* Reloc in bits 0x03f8 (0000 00kk kkkk k000). */ - byte = (addr - rela->r_offset - 2)/2; - instr[0] = (instr[0] & 0x07) | (byte << 3); /* 0xf8 */ - instr[1] = (instr[1] & 0xfc) | (byte >> 5); /* 0x03 */ - return CLE_OK; - - case R_AVR_13_PCREL: /* 3 */ - /* Reloc in bits 0x0fff (0000 kkkk kkkk kkkk). */ - addr = (addr - rela->r_offset - 2)/2; - instr[0] = addr; - instr[1] = (instr[1] & 0xf0) | ((addr >> 8) & 0x0f); - return CLE_OK; -#endif - - case R_AVR_CALL: /* 18 */ - addr = addr >> 1; - instr[2] = addr; - instr[3] = addr >> 8; - return CLE_OK; - - case R_AVR_16: /* 4 */ - instr[0] = addr; - instr[1] = addr >> 8; - return CLE_OK; - - case R_AVR_16_PM: /* 5 */ - addr = addr >> 1; - instr[0] = addr; - instr[1] = addr >> 8; - return CLE_OK; - - /* - * Remaining relocs all have immediate value in bits 0x0f0f. - */ - case R_AVR_LO8_LDI: /* 6 */ - byte = addr; - break; - - case R_AVR_HI8_LDI: /* 7 */ - byte = addr >> 8; - break; - - case R_AVR_HH8_LDI: /* 8 */ - byte = addr >> 16; - break; - - case R_AVR_LO8_LDI_NEG: /* 9 */ - byte = (-addr); - break; - - case R_AVR_HI8_LDI_NEG: /* 10 */ - byte = (-addr) >> 8; - break; - - case R_AVR_HH8_LDI_NEG: /* 11 */ - byte = (-addr) >> 16; - break; - - case R_AVR_LO8_LDI_PM: /* 12 */ - byte = addr >> 1; - break; - - case R_AVR_HI8_LDI_PM: /* 13 */ - byte = addr >> 9; - break; - - case R_AVR_HH8_LDI_PM: /* 14 */ - byte = addr >> 17; - break; - - case R_AVR_LO8_LDI_PM_NEG: /* 15 */ - byte = (-addr) >> 1; - break; - - case R_AVR_HI8_LDI_PM_NEG: /* 16 */ - byte = (-addr) >> 9; - break; - - case R_AVR_HH8_LDI_PM_NEG: /* 17 */ - byte = (-addr) >> 17; - break; - } - /* Relocation in bits 0x0f0f (0000 kkkk 0000 kkkk). */ - instr[0] = (instr[0] & 0xf0) | (byte & 0x0f); - instr[1] = (instr[1] & 0xf0) | (byte >> 4); - - return CLE_OK; -} -#endif /* __AVR__ */ diff --git a/core/loader/cle.h b/core/loader/cle.h index 80c6b0d91..accc2f260 100644 --- a/core/loader/cle.h +++ b/core/loader/cle.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)$Id: cle.h,v 1.4 2007/04/26 12:53:49 bg- Exp $ + * @(#)$Id: cle.h,v 1.5 2007/04/26 13:37:41 bg- Exp $ */ #ifndef CLE_H @@ -90,6 +90,10 @@ cle_lookup(struct cle_info *info, off_t hdr, /* Offset to start of file. */ const char *symbol); +struct elf32_rela; /* Struct forward decl. */ + +int cle_write_reloc(unsigned char *, const struct elf32_rela *, cle_addr); + /* * Error codes that apply in general to linking and loading. */ diff --git a/core/loader/cle_avr.c b/core/loader/cle_avr.c new file mode 100644 index 000000000..f94abaac4 --- /dev/null +++ b/core/loader/cle_avr.c @@ -0,0 +1,178 @@ +/* + * 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: cle_avr.c,v 1.1 2007/04/26 13:38:22 bg- Exp $ + */ + +/* + * The Contiki dynamic Link Editor (CLE), ELF version. + */ + +#include + +#include "contiki.h" + +#include "loader/elf32.h" +#include "loader/cle.h" + +#define NDEBUG +#include "lib/assert.h" + +#ifdef NDEBUG +#define PRINTF(...) do {} while (0) +#else +#define PRINTF(...) printf(__VA_ARGS__) +#endif + +#define R_AVR_NONE 0 +#define R_AVR_32 1 +#define R_AVR_7_PCREL 2 +#define R_AVR_13_PCREL 3 +#define R_AVR_16 4 +#define R_AVR_16_PM 5 +#define R_AVR_LO8_LDI 6 +#define R_AVR_HI8_LDI 7 +#define R_AVR_HH8_LDI 8 +#define R_AVR_LO8_LDI_NEG 9 +#define R_AVR_HI8_LDI_NEG 10 +#define R_AVR_HH8_LDI_NEG 11 +#define R_AVR_LO8_LDI_PM 12 +#define R_AVR_HI8_LDI_PM 13 +#define R_AVR_HH8_LDI_PM 14 +#define R_AVR_LO8_LDI_PM_NEG 15 +#define R_AVR_HI8_LDI_PM_NEG 16 +#define R_AVR_HH8_LDI_PM_NEG 17 +#define R_AVR_CALL 18 + +/* + * Writing relocs is machine dependent and this function is AVR + * specific! + */ +int +cle_write_reloc(unsigned char *pos, + const struct elf32_rela *rela, + cle_addr addr) +{ + unsigned char byte; + + switch(ELF32_R_TYPE(rela->r_info)) { + default: + PRINTF("cle_upd_reloc: unsupported relocation type: %d\n", + ELF32_R_TYPE(rela->r_info)); + return CLE_UNKNOWN_RELOC; + +#if VERIFY_BEFORE_ENABLE + case R_AVR_7_PCREL: /* 2 */ + /* Reloc in bits 0x03f8 (0000 00kk kkkk k000). */ + byte = (addr - rela->r_offset - 2)/2; + pos[0] = (pos[0] & 0x07) | (byte << 3); /* 0xf8 */ + pos[1] = (pos[1] & 0xfc) | (byte >> 5); /* 0x03 */ + return CLE_OK; + + case R_AVR_13_PCREL: /* 3 */ + /* Reloc in bits 0x0fff (0000 kkkk kkkk kkkk). */ + addr = (addr - rela->r_offset - 2)/2; + pos[0] = addr; + pos[1] = (pos[1] & 0xf0) | ((addr >> 8) & 0x0f); + return CLE_OK; +#endif + + case R_AVR_CALL: /* 18 */ + addr = addr >> 1; + pos[2] = addr; + pos[3] = addr >> 8; + return CLE_OK; + + case R_AVR_16: /* 4 */ + pos[0] = addr; + pos[1] = addr >> 8; + return CLE_OK; + + case R_AVR_16_PM: /* 5 */ + addr = addr >> 1; + pos[0] = addr; + pos[1] = addr >> 8; + return CLE_OK; + + /* + * Remaining relocs all have immediate value in bits 0x0f0f. + */ + case R_AVR_LO8_LDI: /* 6 */ + byte = addr; + break; + + case R_AVR_HI8_LDI: /* 7 */ + byte = addr >> 8; + break; + + case R_AVR_HH8_LDI: /* 8 */ + byte = addr >> 16; + break; + + case R_AVR_LO8_LDI_NEG: /* 9 */ + byte = (-addr); + break; + + case R_AVR_HI8_LDI_NEG: /* 10 */ + byte = (-addr) >> 8; + break; + + case R_AVR_HH8_LDI_NEG: /* 11 */ + byte = (-addr) >> 16; + break; + + case R_AVR_LO8_LDI_PM: /* 12 */ + byte = addr >> 1; + break; + + case R_AVR_HI8_LDI_PM: /* 13 */ + byte = addr >> 9; + break; + + case R_AVR_HH8_LDI_PM: /* 14 */ + byte = addr >> 17; + break; + + case R_AVR_LO8_LDI_PM_NEG: /* 15 */ + byte = (-addr) >> 1; + break; + + case R_AVR_HI8_LDI_PM_NEG: /* 16 */ + byte = (-addr) >> 9; + break; + + case R_AVR_HH8_LDI_PM_NEG: /* 17 */ + byte = (-addr) >> 17; + break; + } + /* Relocation in bits 0x0f0f (0000 kkkk 0000 kkkk). */ + pos[0] = (pos[0] & 0xf0) | (byte & 0x0f); + pos[1] = (pos[1] & 0xf0) | (byte >> 4); + + return CLE_OK; +} diff --git a/core/loader/cle_msp430.c b/core/loader/cle_msp430.c new file mode 100644 index 000000000..0f2250bfb --- /dev/null +++ b/core/loader/cle_msp430.c @@ -0,0 +1,63 @@ +/* + * 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: cle_msp430.c,v 1.1 2007/04/26 13:38:00 bg- Exp $ + */ + +/* + * The Contiki dynamic Link Editor (CLE), ELF version. + */ + +#include + +#include "contiki.h" + +#include "loader/elf32.h" +#include "loader/cle.h" + +#define NDEBUG +#include "lib/assert.h" + +#ifdef NDEBUG +#define PRINTF(...) do {} while (0) +#else +#define PRINTF(...) printf(__VA_ARGS__) +#endif + +/* + * Writing relocs is machine dependent and this function is MSP430 + * specific! + */ +int +cle_write_reloc(unsigned char *pos, + const struct elf32_rela *rela, + cle_addr addr) +{ + memcpy(pos, &addr, 2); /* Write reloc */ + return CLE_OK; +} diff --git a/core/loader/cmod.c b/core/loader/cmod.c index 5a665c0c6..5c0ee2444 100644 --- a/core/loader/cmod.c +++ b/core/loader/cmod.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)$Id: cmod.c,v 1.2 2007/04/25 15:37:41 bg- Exp $ + * @(#)$Id: cmod.c,v 1.3 2007/04/26 13:38:52 bg- Exp $ */ #include @@ -34,6 +34,7 @@ #include "contiki.h" +#include "loader/elf32.h" #include "loader/cle.h" #include "loader/cmod.h"