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
0037
0038 #include <sys/cdefs.h>
0039
0040 #include <errno.h>
0041 #include <stdio.h>
0042 #include <sys/types.h>
0043 #include <sys/stat.h>
0044
0045 #include <rtems/rtl/rtl.h>
0046 #include "rtl-elf.h"
0047 #include "rtl-error.h"
0048 #include <rtems/rtl/rtl-trace.h>
0049 #include "rtl-unwind.h"
0050 #include "rtl-unwind-dw2.h"
0051
0052 uint32_t
0053 rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
0054 const Elf_Shdr* shdr) {
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 (void) obj;
0065 (void) section;
0066 (void) name;
0067 (void) shdr;
0068 return flags;
0069 }
0070
0071 bool
0072 rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
0073 rtems_rtl_obj_sect* sect) {
0074 (void) obj;
0075 (void) sect;
0076 return false;
0077 }
0078
0079 bool
0080 rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
0081 rtems_rtl_obj_sect* sect) {
0082 (void) obj;
0083 (void) sect;
0084 return false;
0085 }
0086
0087 bool
0088 rtems_rtl_elf_rel_resolve_sym (Elf_Word type) {
0089 return true;
0090 }
0091
0092 uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
0093 {
0094 (void) obj;
0095 return sizeof(uint32_t);
0096 }
0097
0098 size_t
0099 rtems_rtl_elf_relocate_tramp_max_size (void) {
0100
0101
0102
0103 return 0;
0104 }
0105
0106 rtems_rtl_elf_rel_status
0107 rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
0108 const Elf_Rel* rel,
0109 const rtems_rtl_obj_sect* sect,
0110 const char* symname,
0111 const Elf_Byte syminfo,
0112 const Elf_Word symvalue) {
0113 (void) obj;
0114 (void) rel;
0115 (void) sect;
0116 (void) symname;
0117 (void) syminfo;
0118 (void) symvalue;
0119 return rtems_rtl_elf_rel_no_error;
0120 }
0121
0122
0123 static uint32_t extractBits(uint64_t v, uint32_t begin, uint32_t end) {
0124 return (v & ((1ULL << (begin + 1)) - 1)) >> end;
0125 }
0126
0127 static int64_t SignExtend64(uint64_t val, unsigned bits) {
0128 return (int64_t )(((int64_t) (val << (64 - bits))) >> (64 - bits));
0129 }
0130
0131 static void write16le(void *loc, uint16_t val) {
0132 *((uint16_t *) loc) = val;
0133 }
0134
0135 static void write32le(void *loc, uint32_t val) {
0136 *((uint32_t *) loc) = val;
0137 }
0138
0139 static void write64le(void *loc, uint64_t val) {
0140 *((uint64_t *) loc) = val;
0141 }
0142
0143 static uint16_t read16le(void *loc) {
0144 return *((uint16_t *) loc);
0145 }
0146
0147 static uint32_t read32le(void *loc) {
0148 return *((uint32_t *) loc);
0149 }
0150
0151 static uint64_t read64le(void *loc) {
0152 return *((uint64_t *) loc);
0153 }
0154
0155 static rtems_rtl_elf_rel_status
0156 rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
0157 const Elf_Rela* rela,
0158 const rtems_rtl_obj_sect* sect,
0159 const char* symname,
0160 const Elf_Byte syminfo,
0161 const Elf_Word symvalue,
0162 const bool parsing) {
0163 Elf_Addr *where;
0164
0165 char bits = (sizeof(Elf_Word) * 8);
0166 where = (Elf_Addr *)(sect->base + rela->r_offset);
0167
0168
0169 Elf_Word pcrel_val = symvalue - ((Elf_Word)(uintptr_t) where);
0170
0171 if (syminfo == STT_SECTION) {
0172 return rtems_rtl_elf_rel_no_error;
0173 }
0174
0175 if (parsing) {
0176 return rtems_rtl_elf_rel_no_error;
0177 }
0178
0179 switch (ELF_R_TYPE(rela->r_info)) {
0180 case R_TYPE(NONE):
0181 break;
0182
0183 case R_TYPE(RVC_BRANCH): {
0184 uint16_t insn = ((*where) & 0xFFFF) & 0xE383;
0185 uint16_t imm8 = extractBits(pcrel_val, 8, 8) << 12;
0186 uint16_t imm4_3 = extractBits(pcrel_val, 4, 3) << 10;
0187 uint16_t imm7_6 = extractBits(pcrel_val, 7, 6) << 5;
0188 uint16_t imm2_1 = extractBits(pcrel_val, 2, 1) << 3;
0189 uint16_t imm5 = extractBits(pcrel_val, 5, 5) << 2;
0190 insn |= imm8 | imm4_3 | imm7_6 | imm2_1 | imm5;
0191
0192 write16le(where, insn);
0193 }
0194 break;
0195
0196 case R_TYPE(RVC_JUMP): {
0197 uint16_t insn = ((*where) & 0xFFFF) & 0xE003;
0198 uint16_t imm11 = extractBits(pcrel_val, 11, 11) << 12;
0199 uint16_t imm4 = extractBits(pcrel_val, 4, 4) << 11;
0200 uint16_t imm9_8 = extractBits(pcrel_val, 9, 8) << 9;
0201 uint16_t imm10 = extractBits(pcrel_val, 10, 10) << 8;
0202 uint16_t imm6 = extractBits(pcrel_val, 6, 6) << 7;
0203 uint16_t imm7 = extractBits(pcrel_val, 7, 7) << 6;
0204 uint16_t imm3_1 = extractBits(pcrel_val, 3, 1) << 3;
0205 uint16_t imm5 = extractBits(pcrel_val, 5, 5) << 2;
0206 insn |= imm11 | imm4 | imm9_8 | imm10 | imm6 | imm7 | imm3_1 | imm5;
0207
0208 write16le(where, insn);
0209 }
0210 break;
0211
0212 case R_TYPE(RVC_LUI): {
0213 int64_t imm = SignExtend64(symvalue + 0x800, bits) >> 12;
0214 if (imm == 0) {
0215 write16le(where, (read16le(where) & 0x0F83) | 0x4000);
0216 } else {
0217 uint16_t imm17 = extractBits(symvalue + 0x800, 17, 17) << 12;
0218 uint16_t imm16_12 = extractBits(symvalue + 0x800, 16, 12) << 2;
0219 write16le(where, (read16le(where) & 0xEF83) | imm17 | imm16_12);
0220 }
0221 }
0222 break;
0223
0224 case R_TYPE(JAL): {
0225 uint32_t insn = read32le(where) & 0xFFF;
0226 uint32_t imm20 = extractBits(pcrel_val, 20, 20) << 31;
0227 uint32_t imm10_1 = extractBits(pcrel_val, 10, 1) << 21;
0228 uint32_t imm11 = extractBits(pcrel_val, 11, 11) << 20;
0229 uint32_t imm19_12 = extractBits(pcrel_val, 19, 12) << 12;
0230 insn |= imm20 | imm10_1 | imm11 | imm19_12;
0231
0232 write32le(where, insn);
0233 }
0234 break;
0235
0236 case R_TYPE(BRANCH): {
0237
0238 uint32_t insn = read32le(where) & 0x1FFF07F;
0239 uint32_t imm12 = extractBits(pcrel_val, 12, 12) << 31;
0240 uint32_t imm10_5 = extractBits(pcrel_val, 10, 5) << 25;
0241 uint32_t imm4_1 = extractBits(pcrel_val, 4, 1) << 8;
0242 uint32_t imm11 = extractBits(pcrel_val, 11, 11) << 7;
0243 insn |= imm12 | imm10_5 | imm4_1 | imm11;
0244
0245 write32le(where, insn);
0246 }
0247 break;
0248
0249 case R_TYPE(64):
0250 write64le(where, symvalue);
0251 break;
0252 case R_TYPE(32):
0253 write32le(where, symvalue);
0254 break;
0255
0256 case R_TYPE(SET6):
0257 *((uint8_t *) where) = (*where & 0xc0) | (symvalue & 0x3f);
0258 break;
0259 case R_TYPE(SET8):
0260 *((uint8_t *) where) = symvalue;
0261 break;
0262 case R_TYPE(SET16):
0263 write16le(where, symvalue);
0264 break;
0265 case R_TYPE(SET32):
0266 write32le(where, symvalue);
0267 break;
0268
0269 case R_TYPE(ADD8):
0270 *((uint8_t *) where) = *((uint8_t *) where) + symvalue;
0271 break;
0272 case R_TYPE(ADD16):
0273 write16le(where, read16le(where) + symvalue);
0274 break;
0275 case R_TYPE(ADD32):
0276 write32le(where, read32le(where) + symvalue);
0277 break;
0278 case R_TYPE(ADD64):
0279 write64le(where, read64le(where) + symvalue);
0280 break;
0281
0282 case R_TYPE(SUB6):
0283 *((uint8_t *) where) = (*where & 0xc0) | (((*where & 0x3f) - symvalue) & 0x3f);
0284 break;
0285 case R_TYPE(SUB8):
0286 *((uint8_t *) where) = *((uint8_t *) where) - symvalue;
0287 break;
0288 case R_TYPE(SUB16):
0289 write16le(where, read16le(where) - symvalue);
0290 break;
0291 case R_TYPE(SUB32):
0292 write32le(where, read32le(where) - symvalue);
0293 break;
0294 case R_TYPE(SUB64):
0295 write64le(where, read64le(where) - symvalue);
0296 break;
0297
0298 case R_TYPE(32_PCREL): {
0299 write32le(where, pcrel_val);
0300
0301 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0302 printf ("rtl: R_RISCV_32_PCREL %p @ %p in %s\n",
0303 (void *) * (where), where, rtems_rtl_obj_oname (obj));
0304
0305 }
0306 break;
0307
0308 case R_TYPE(PCREL_HI20): {
0309 int64_t hi = SignExtend64(pcrel_val + 0x800, bits);
0310 write32le(where, (read32le(where) & 0xFFF) | (hi & 0xFFFFF000));
0311
0312 }
0313 break;
0314
0315 case R_TYPE(GOT_HI20):
0316 case R_TYPE(HI20): {
0317
0318 uint64_t hi = symvalue + 0x800;
0319 write32le(where, (read32le(where) & 0xFFF) | (hi & 0xFFFFF000));
0320 }
0321 break;
0322
0323 case R_TYPE(PCREL_LO12_I): {
0324 uint64_t hi = (pcrel_val + 0x800) >> 12;
0325 uint64_t lo = pcrel_val - (hi << 12);
0326 write32le(where, (read32le(where) & 0xFFFFF) | ((lo & 0xFFF) << 20));
0327 }
0328 break;
0329
0330 case R_TYPE(LO12_I): {
0331
0332 uint64_t hi = (symvalue + 0x800) >> 12;
0333 uint64_t lo = symvalue - (hi << 12);
0334 write32le(where, (read32le(where) & 0xFFFFF) | ((lo & 0xFFF) << 20));
0335
0336 }
0337 break;
0338
0339 case R_TYPE(PCREL_LO12_S): {
0340 uint64_t hi = (pcrel_val + 0x800) >> 12;
0341 uint64_t lo = pcrel_val - (hi << 12);
0342 uint32_t imm11_5 = extractBits(lo, 11, 5) << 25;
0343 uint32_t imm4_0 = extractBits(lo, 4, 0) << 7;
0344 write32le(where, (read32le(where) & 0x1FFF07F) | imm11_5 | imm4_0);
0345
0346 }
0347 break;
0348
0349 case R_TYPE(LO12_S): {
0350 uint64_t hi = (symvalue + 0x800) >> 12;
0351 uint64_t lo = symvalue - (hi << 12);
0352 uint32_t imm11_5 = extractBits(lo, 11, 5) << 25;
0353 uint32_t imm4_0 = extractBits(lo, 4, 0) << 7;
0354 write32le(where, (read32le(where) & 0x1FFF07F) | imm11_5 | imm4_0);
0355 }
0356 break;
0357
0358 case R_TYPE(CALL_PLT):
0359 case R_TYPE(CALL): {
0360 int64_t hi = SignExtend64(pcrel_val + 0x800, bits);
0361 write32le(where, (read32le(where) & 0xFFF) | (hi & 0xFFFFF000));
0362 int64_t hi20 = SignExtend64(pcrel_val + 0x800, bits);
0363 int64_t lo = pcrel_val - (hi20 << 12);
0364 write32le(((char *) where) + 4, (read32le(((char *) where) + 4) & 0xFFFFF) | ((lo & 0xFFF) << 20));
0365 }
0366 break;
0367
0368 default:
0369 rtems_rtl_set_error (EINVAL,
0370 "%s: Unsupported relocation type %u "
0371 "in non-PLT relocations",
0372 sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
0373 return rtems_rtl_elf_rel_failure;
0374 }
0375
0376 return rtems_rtl_elf_rel_no_error;
0377 }
0378
0379 rtems_rtl_elf_rel_status
0380 rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
0381 const Elf_Rela* rela,
0382 const rtems_rtl_obj_sect* sect,
0383 const char* symname,
0384 const Elf_Byte syminfo,
0385 const Elf_Word symvalue) {
0386 return rtems_rtl_elf_reloc_rela (obj,
0387 rela,
0388 sect,
0389 symname,
0390 syminfo,
0391 symvalue,
0392 false);
0393 }
0394
0395 rtems_rtl_elf_rel_status
0396 rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
0397 const Elf_Rela* rela,
0398 const rtems_rtl_obj_sect* sect,
0399 const char* symname,
0400 const Elf_Byte syminfo,
0401 const Elf_Word symvalue) {
0402 return rtems_rtl_elf_reloc_rela (obj,
0403 rela,
0404 sect,
0405 symname,
0406 syminfo,
0407 symvalue,
0408 true);
0409 }
0410
0411 rtems_rtl_elf_rel_status
0412 rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
0413 const Elf_Rel* rel,
0414 const rtems_rtl_obj_sect* sect,
0415 const char* symname,
0416 const Elf_Byte syminfo,
0417 const Elf_Word symvalue) {
0418 rtems_rtl_set_error (EINVAL, "rel type record not supported");
0419 return rtems_rtl_elf_rel_failure;
0420 }
0421
0422 bool
0423 rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
0424 const char* name,
0425 uint32_t flags) {
0426 return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
0427 }
0428
0429 bool
0430 rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj) {
0431 return rtems_rtl_elf_unwind_dw2_register (obj);
0432 }
0433
0434 bool
0435 rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj) {
0436 return rtems_rtl_elf_unwind_dw2_deregister (obj);
0437 }