Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2007, Swedish Institute of Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * @(#)$Id: cle_avr.c,v 1.3 2007/06/04 17:50:25 bg- Exp $ 00030 */ 00031 00032 /* 00033 * The Contiki dynamic Link Editor (CLE), ELF version. 00034 */ 00035 00036 #include <stdio.h> 00037 00038 #include "contiki.h" 00039 00040 #include "loader/elf32.h" 00041 #include "loader/cle.h" 00042 00043 #define NDEBUG 00044 #include "lib/assert.h" 00045 00046 #ifdef NDEBUG 00047 #define PRINTF(...) do {} while (0) 00048 #else 00049 #define PRINTF(...) printf(__VA_ARGS__) 00050 #endif 00051 00052 #define R_AVR_NONE 0 00053 #define R_AVR_32 1 00054 #define R_AVR_7_PCREL 2 00055 #define R_AVR_13_PCREL 3 00056 #define R_AVR_16 4 00057 #define R_AVR_16_PM 5 00058 #define R_AVR_LO8_LDI 6 00059 #define R_AVR_HI8_LDI 7 00060 #define R_AVR_HH8_LDI 8 00061 #define R_AVR_LO8_LDI_NEG 9 00062 #define R_AVR_HI8_LDI_NEG 10 00063 #define R_AVR_HH8_LDI_NEG 11 00064 #define R_AVR_LO8_LDI_PM 12 00065 #define R_AVR_HI8_LDI_PM 13 00066 #define R_AVR_HH8_LDI_PM 14 00067 #define R_AVR_LO8_LDI_PM_NEG 15 00068 #define R_AVR_HI8_LDI_PM_NEG 16 00069 #define R_AVR_HH8_LDI_PM_NEG 17 00070 #define R_AVR_CALL 18 00071 00072 /* 00073 * Writing relocs is machine dependent and this function is AVR 00074 * specific! 00075 */ 00076 int 00077 cle_write_reloc(void *pos_, 00078 const struct elf32_rela *rela, 00079 cle_addr addr, 00080 const struct cle_info *info) 00081 { 00082 unsigned char *pos = pos_; 00083 unsigned char byte; 00084 00085 switch(ELF32_R_TYPE(rela->r_info)) { 00086 default: 00087 PRINTF("cle_upd_reloc: unsupported relocation type: %d\n", 00088 ELF32_R_TYPE(rela->r_info)); 00089 return CLE_UNKNOWN_RELOC; 00090 00091 case R_AVR_7_PCREL: /* 2 */ 00092 /* Reloc in bits 0x03f8 (0000 00kk kkkk k000). */ 00093 byte = addr - (/* text */ + rela->r_offset + 2); 00094 byte = byte >> 1; 00095 pos[0] = (pos[0] & 0x07) | (byte << 3); /* 0xf8 */ 00096 pos[1] = (pos[1] & 0xfc) | (byte >> 5); /* 0x03 */ 00097 return CLE_OK; 00098 00099 case R_AVR_13_PCREL: /* 3 */ 00100 /* Reloc in bits 0x0fff (0000 kkkk kkkk kkkk). */ 00101 addr = addr - (info->text + rela->r_offset + 2); 00102 addr = addr >> 1; 00103 pos[0] = addr; 00104 pos[1] = (pos[1] & 0xf0) | ((addr >> 8) & 0x0f); 00105 return CLE_OK; 00106 00107 case R_AVR_CALL: /* 18 */ 00108 addr = addr >> 1; 00109 pos[2] = addr; 00110 pos[3] = addr >> 8; 00111 return CLE_OK; 00112 00113 case R_AVR_16: /* 4 */ 00114 pos[0] = addr; 00115 pos[1] = addr >> 8; 00116 return CLE_OK; 00117 00118 case R_AVR_16_PM: /* 5 */ 00119 addr = addr >> 1; 00120 pos[0] = addr; 00121 pos[1] = addr >> 8; 00122 return CLE_OK; 00123 00124 /* 00125 * Remaining relocs all have immediate value in bits 0x0f0f. 00126 */ 00127 case R_AVR_LO8_LDI: /* 6 */ 00128 byte = addr; 00129 break; 00130 00131 case R_AVR_HI8_LDI: /* 7 */ 00132 byte = addr >> 8; 00133 break; 00134 00135 case R_AVR_HH8_LDI: /* 8 */ 00136 byte = addr >> 16; 00137 break; 00138 00139 case R_AVR_LO8_LDI_NEG: /* 9 */ 00140 byte = (-addr); 00141 break; 00142 00143 case R_AVR_HI8_LDI_NEG: /* 10 */ 00144 byte = (-addr) >> 8; 00145 break; 00146 00147 case R_AVR_HH8_LDI_NEG: /* 11 */ 00148 byte = (-addr) >> 16; 00149 break; 00150 00151 case R_AVR_LO8_LDI_PM: /* 12 */ 00152 byte = addr >> 1; 00153 break; 00154 00155 case R_AVR_HI8_LDI_PM: /* 13 */ 00156 byte = addr >> 9; 00157 break; 00158 00159 case R_AVR_HH8_LDI_PM: /* 14 */ 00160 byte = addr >> 17; 00161 break; 00162 00163 case R_AVR_LO8_LDI_PM_NEG: /* 15 */ 00164 byte = (-addr) >> 1; 00165 break; 00166 00167 case R_AVR_HI8_LDI_PM_NEG: /* 16 */ 00168 byte = (-addr) >> 9; 00169 break; 00170 00171 case R_AVR_HH8_LDI_PM_NEG: /* 17 */ 00172 byte = (-addr) >> 17; 00173 break; 00174 } 00175 /* Relocation in bits 0x0f0f (0000 kkkk 0000 kkkk). */ 00176 pos[0] = (pos[0] & 0xf0) | (byte & 0x0f); 00177 pos[1] = (pos[1] & 0xf0) | (byte >> 4); 00178 00179 return CLE_OK; 00180 }