cle_avr.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
00074
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:
00092
00093 byte = addr - ( + rela->r_offset + 2);
00094 byte = byte >> 1;
00095 pos[0] = (pos[0] & 0x07) | (byte << 3);
00096 pos[1] = (pos[1] & 0xfc) | (byte >> 5);
00097 return CLE_OK;
00098
00099 case R_AVR_13_PCREL:
00100
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:
00108 addr = addr >> 1;
00109 pos[2] = addr;
00110 pos[3] = addr >> 8;
00111 return CLE_OK;
00112
00113 case R_AVR_16:
00114 pos[0] = addr;
00115 pos[1] = addr >> 8;
00116 return CLE_OK;
00117
00118 case R_AVR_16_PM:
00119 addr = addr >> 1;
00120 pos[0] = addr;
00121 pos[1] = addr >> 8;
00122 return CLE_OK;
00123
00124
00125
00126
00127 case R_AVR_LO8_LDI:
00128 byte = addr;
00129 break;
00130
00131 case R_AVR_HI8_LDI:
00132 byte = addr >> 8;
00133 break;
00134
00135 case R_AVR_HH8_LDI:
00136 byte = addr >> 16;
00137 break;
00138
00139 case R_AVR_LO8_LDI_NEG:
00140 byte = (-addr);
00141 break;
00142
00143 case R_AVR_HI8_LDI_NEG:
00144 byte = (-addr) >> 8;
00145 break;
00146
00147 case R_AVR_HH8_LDI_NEG:
00148 byte = (-addr) >> 16;
00149 break;
00150
00151 case R_AVR_LO8_LDI_PM:
00152 byte = addr >> 1;
00153 break;
00154
00155 case R_AVR_HI8_LDI_PM:
00156 byte = addr >> 9;
00157 break;
00158
00159 case R_AVR_HH8_LDI_PM:
00160 byte = addr >> 17;
00161 break;
00162
00163 case R_AVR_LO8_LDI_PM_NEG:
00164 byte = (-addr) >> 1;
00165 break;
00166
00167 case R_AVR_HI8_LDI_PM_NEG:
00168 byte = (-addr) >> 9;
00169 break;
00170
00171 case R_AVR_HH8_LDI_PM_NEG:
00172 byte = (-addr) >> 17;
00173 break;
00174 }
00175
00176 pos[0] = (pos[0] & 0xf0) | (byte & 0x0f);
00177 pos[1] = (pos[1] & 0xf0) | (byte >> 4);
00178
00179 return CLE_OK;
00180 }