File indexing completed on 2025-05-11 08:24:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <sys/cdefs.h>
0037
0038 #include <errno.h>
0039 #include <inttypes.h>
0040 #include <stdio.h>
0041 #include <sys/types.h>
0042 #include <sys/stat.h>
0043
0044 #include <rtems/rtl/rtl.h>
0045 #include "rtl-elf.h"
0046 #include "rtl-error.h"
0047 #include <rtems/rtl/rtl-trace.h>
0048 #include "rtl-unwind.h"
0049 #include "rtl-unwind-dw2.h"
0050
0051 uint32_t
0052 rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
0053 const Elf_Shdr* shdr)
0054 {
0055 return 0;
0056 }
0057
0058 uint32_t
0059 rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
0060 int section,
0061 const char* name,
0062 const Elf_Shdr* shdr,
0063 const uint32_t flags)
0064 {
0065 (void) obj;
0066 (void) section;
0067 (void) name;
0068 (void) shdr;
0069 return flags;
0070 }
0071
0072 bool
0073 rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
0074 rtems_rtl_obj_sect* sect)
0075 {
0076 (void) obj;
0077 (void) sect;
0078 return false;
0079 }
0080
0081 bool
0082 rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
0083 rtems_rtl_obj_sect* sect)
0084 {
0085 (void) obj;
0086 (void) sect;
0087 return false;
0088 }
0089
0090 bool
0091 rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
0092 {
0093 return true;
0094 }
0095
0096 uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
0097 {
0098 (void) obj;
0099 return sizeof(uint32_t);
0100 }
0101
0102 size_t
0103 rtems_rtl_elf_relocate_tramp_max_size (void)
0104 {
0105
0106
0107
0108 return 0;
0109 }
0110
0111 rtems_rtl_elf_rel_status
0112 rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
0113 const Elf_Rela* rela,
0114 const rtems_rtl_obj_sect* sect,
0115 const char* symname,
0116 const Elf_Byte syminfo,
0117 const Elf_Word symvalue)
0118 {
0119 (void) obj;
0120 (void) rela;
0121 (void) sect;
0122 (void) symname;
0123 (void) syminfo;
0124 (void) symvalue;
0125 rtems_rtl_set_error (EINVAL, "rela type record not supported");
0126 return rtems_rtl_elf_rel_failure;
0127 }
0128
0129 rtems_rtl_elf_rel_status
0130 rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
0131 const Elf_Rela* rela,
0132 const rtems_rtl_obj_sect* sect,
0133 const char* symname,
0134 const Elf_Byte syminfo,
0135 const Elf_Word symvalue)
0136 {
0137 (void) obj;
0138 (void) rela;
0139 (void) sect;
0140 (void) symname;
0141 (void) syminfo;
0142 (void) symvalue;
0143 rtems_rtl_set_error (EINVAL, "rela type record not supported");
0144 return rtems_rtl_elf_rel_failure;
0145 }
0146
0147 rtems_rtl_elf_rel_status
0148 rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
0149 const Elf_Rel* rel,
0150 const rtems_rtl_obj_sect* sect,
0151 const char* symname,
0152 const Elf_Byte syminfo,
0153 const Elf_Word symvalue)
0154 {
0155 (void) obj;
0156 (void) rel;
0157 (void) sect;
0158 (void) symname;
0159 (void) syminfo;
0160 (void) symvalue;
0161 return rtems_rtl_elf_rel_no_error;
0162 }
0163
0164 #define RTEMS_RTL_MIPS_HI16_MAX (128)
0165
0166 static struct {
0167 Elf_Addr* where_hi16;
0168 Elf_Addr ahl;
0169 } mips_hi16_list[RTEMS_RTL_MIPS_HI16_MAX];
0170 static size_t mips_hi16_list_cnt;
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 rtems_rtl_elf_rel_status
0181 rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
0182 const Elf_Rel* rel,
0183 const rtems_rtl_obj_sect* sect,
0184 const char* symname,
0185 const Elf_Byte syminfo,
0186 const Elf_Word symvalue)
0187 {
0188 Elf_Addr *where;
0189 Elf_Word tmp;
0190 Elf_Word addend = (Elf_Word)0;
0191 Elf_Word local = 0;
0192 Elf_Addr *where_hi16;
0193 Elf_Addr ahl;
0194 uint32_t t;
0195
0196 where = (Elf_Addr *)(sect->base + rel->r_offset);
0197 addend = *where;
0198
0199 if (syminfo == STT_SECTION)
0200 local = 1;
0201
0202 switch (ELF_R_TYPE(rel->r_info)) {
0203 case R_TYPE(NONE):
0204 break;
0205
0206 case R_TYPE(16):
0207 tmp = addend & 0xffff;
0208 if ((tmp & 0x8000) == 0x8000)
0209 tmp |= 0xffff0000;
0210 tmp = symvalue + (int)tmp;
0211 if ((tmp & 0xffff0000) != 0) {
0212 printf("R_MIPS_16 Overflow\n");
0213 return rtems_rtl_elf_rel_failure;
0214 }
0215
0216 *where = (tmp & 0xffff) | (*where & 0xffff0000);
0217
0218 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0219 printf ("rtl: R_MIPS_16 %p @ %p in %s\n",
0220 (void *)*(where), where, rtems_rtl_obj_oname (obj));
0221 break;
0222
0223 case R_TYPE(32):
0224 tmp = symvalue + addend;
0225 if (addend != tmp)
0226 *where = tmp;
0227
0228 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0229 printf ("rtl: R_MIPS_32 %p @ %p in %s\n",
0230 (void *)*(where), where, rtems_rtl_obj_oname (obj));
0231 break;
0232
0233 case R_TYPE(26):
0234
0235 addend &= 0x03ffffff;
0236 addend <<= 2;
0237
0238 if (local == 1) {
0239 tmp = symvalue + (((Elf_Addr)where & 0xf0000000) | addend);
0240 tmp >>= 2;
0241
0242 } else {
0243
0244 tmp = addend;
0245
0246 if ((tmp & 0x08000000) == 0x08000000)
0247 tmp |= 0xf0000000;
0248 tmp = ((int)tmp + symvalue) >> 2;
0249
0250 }
0251
0252 *where &= ~0x03ffffff;
0253 *where |= tmp & 0x03ffffff;
0254
0255 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0256 printf ("rtl: R_MIPS_26 local=%" PRIu32 " @ %p in %s\n",
0257 local, (void *)*(where), rtems_rtl_obj_oname (obj));
0258 break;
0259
0260 case R_TYPE(HI16):
0261 if (mips_hi16_list_cnt >= RTEMS_RTL_MIPS_HI16_MAX) {
0262 rtems_rtl_set_error (ENOMEM,
0263 "%s: too many MIPS_HI16 relocs", sect->name);
0264 return false;
0265 }
0266 mips_hi16_list[mips_hi16_list_cnt].where_hi16 = where;
0267 mips_hi16_list[mips_hi16_list_cnt].ahl = addend << 16;
0268 ++mips_hi16_list_cnt;
0269
0270 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0271 printf ("rtl: R_MIPS_HI16 %p @ %p in %s\n",
0272 (void *)*(where), where, rtems_rtl_obj_oname (obj));
0273 break;
0274
0275 case R_TYPE(LO16):
0276 t = (int16_t) addend;
0277 tmp = symvalue;
0278 if (tmp == 0) {
0279 rtems_rtl_set_error (EINVAL,
0280 "%s: symvalue is 0 in MIPS_LO16", sect->name);
0281 return rtems_rtl_elf_rel_failure;
0282 }
0283
0284
0285 addend &= 0xffff0000;
0286 addend |= (uint16_t)(t + tmp);
0287 *where = addend;
0288
0289 if (rtems_rtl_trace(RTEMS_RTL_TRACE_RELOC))
0290 printf("*where %x where %p\n", *where, where);
0291
0292
0293 while (mips_hi16_list_cnt != 0) {
0294 --mips_hi16_list_cnt;
0295 ahl = mips_hi16_list[mips_hi16_list_cnt].ahl;
0296 where_hi16 = mips_hi16_list[mips_hi16_list_cnt].where_hi16;
0297 addend = *(where_hi16);
0298 addend &= 0xffff0000;
0299 addend |= ((ahl + t + tmp) - (int16_t) (ahl + t + tmp)) >> 16;
0300 *(where_hi16) = addend;
0301 if (rtems_rtl_trace(RTEMS_RTL_TRACE_RELOC))
0302 printf("*where_hi %x where_hi %p ahl=%08x\n",
0303 *(where_hi16), where_hi16, ahl);
0304 }
0305
0306 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0307 printf ("rtl: R_MIPS_LO16 %p @ %p in %s\n",
0308 (void *)*(where), where, rtems_rtl_obj_oname (obj));
0309 break;
0310
0311 case R_TYPE(PC16):
0312 tmp = addend & 0xffff;
0313 if ((tmp & 0x8000) == 0x8000)
0314 tmp |= 0xffff0000;
0315 tmp = symvalue + ((int)tmp*4) - (Elf_Addr)where;
0316 tmp = (Elf_Sword)tmp >> 2;
0317 if (((Elf_Sword)tmp > 0x7fff) || ((Elf_Sword)tmp < -0x8000)) {
0318 printf("R_MIPS_PC16 Overflow\n");
0319 return rtems_rtl_elf_rel_failure;
0320 }
0321
0322 *where = (tmp & 0xffff) | (*where & 0xffff0000);
0323
0324 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0325 printf ("rtl: R_MIPS_PC16 %p @ %p in %s\n",
0326 (void *)*(where), where, rtems_rtl_obj_oname (obj));
0327
0328 break;
0329
0330 default:
0331 printf ("rtl: reloc unknown: sym = %" PRIu32 ", type = %" PRIu32 ", offset = %p, "
0332 "contents = %p\n",
0333 ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
0334 (void *)rel->r_offset, (void *)*where);
0335 rtems_rtl_set_error (EINVAL,
0336 "%s: Unsupported relocation type %" PRIu32
0337 "in non-PLT relocations",
0338 sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
0339 return rtems_rtl_elf_rel_failure;
0340 }
0341
0342 return rtems_rtl_elf_rel_no_error;
0343 }
0344
0345 bool
0346 rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
0347 const char* name,
0348 uint32_t flags)
0349 {
0350 return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
0351 }
0352
0353 bool
0354 rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
0355 {
0356 return rtems_rtl_elf_unwind_dw2_register (obj);
0357 }
0358
0359 bool
0360 rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
0361 {
0362 return rtems_rtl_elf_unwind_dw2_deregister (obj);
0363 }