File indexing completed on 2025-05-11 08:24:16
0001
0002
0003
0004
0005
0006
0007 #include <sys/cdefs.h>
0008
0009 #include <errno.h>
0010 #include <inttypes.h>
0011 #include <stdio.h>
0012 #include <string.h>
0013 #include <sys/types.h>
0014 #include <sys/stat.h>
0015
0016 #include <rtems/rtl/rtl.h>
0017 #include "rtl-elf.h"
0018 #include "rtl-error.h"
0019 #include <rtems/rtl/rtl-trace.h>
0020 #include "rtl-unwind-arm.h"
0021
0022
0023
0024
0025
0026 #define ALLOW_UNTESTED_RELOCS 1
0027
0028
0029
0030
0031
0032 #define RELOC_ALIGNED_P(x) \
0033 (((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
0034
0035 #define SHT_ARM_EXIDX 0x70000001
0036
0037 static inline Elf_Addr
0038 load_ptr(void *where)
0039 {
0040 Elf_Addr res;
0041
0042 memcpy(&res, where, sizeof(res));
0043
0044 return (res);
0045 }
0046
0047 static inline void
0048 store_ptr(void *where, Elf_Addr val)
0049 {
0050 memcpy(where, &val, sizeof(val));
0051 }
0052
0053
0054
0055
0056
0057 static inline int
0058 isThumb(Elf_Word symvalue)
0059 {
0060 if ((symvalue & 0x1) == 0x1)
0061 return true;
0062 else return false;
0063 }
0064
0065 static inline Elf_SOff
0066 sign_extend31(Elf_Addr val)
0067 {
0068 if (0x40000000 & val)
0069 val = ~((Elf_Addr)0x7fffffff) | (0x7fffffff & val);
0070 return 0x7fffffff & val;
0071 }
0072
0073 static void*
0074 set_arm_veneer(void* trampoline, Elf_Addr target)
0075 {
0076
0077
0078
0079
0080 uint32_t* tramp = (uint32_t*) trampoline;
0081 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
0082 *tramp++ = 0xe51ff004;
0083 #else
0084 *tramp++ = 0xe51ff004;
0085 #endif
0086 *tramp++ = (uint32_t) target;
0087 return tramp;
0088 }
0089
0090 static void*
0091 set_veneer(void* trampoline, Elf_Addr target)
0092 {
0093
0094
0095
0096
0097
0098
0099
0100 #if defined(__thumb__)
0101 uint32_t* tramp = (uint32_t*) trampoline;
0102 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
0103 *tramp++ = 0xf000f8df;
0104 #else
0105 *tramp++ = 0xf8dff000;
0106 #endif
0107 *tramp++ = (uint32_t) target;
0108 return tramp;
0109 #else
0110 return set_arm_veneer(trampoline, target);
0111 #endif
0112 }
0113
0114 static void*
0115 set_thumb_bx_veneer(void* trampoline, Elf_Addr target)
0116 {
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 uint16_t* tramp = (uint16_t*) trampoline;
0127
0128 *tramp++ = 0xf8df;
0129 *tramp++ = 0xc002;
0130
0131 *tramp++ = 0x4760;
0132 *tramp++ = (uint16_t) target & 0xffff;
0133 *tramp++ = (uint16_t) ((target >> 16) & 0xffff);
0134 return tramp;
0135 }
0136
0137 static size_t
0138 get_veneer_size(int type)
0139 {
0140 (void) type;
0141
0142 return 10;
0143 }
0144
0145 uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
0146 {
0147 (void) obj;
0148 return sizeof(uint32_t);
0149 }
0150
0151 size_t
0152 rtems_rtl_elf_relocate_tramp_max_size (void)
0153 {
0154 return 8;
0155 }
0156
0157 uint32_t
0158 rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
0159 const Elf_Shdr* shdr)
0160 {
0161 uint32_t flags = 0;
0162 if (shdr->sh_type == SHT_ARM_EXIDX)
0163 flags = RTEMS_RTL_OBJ_SECT_EH | RTEMS_RTL_OBJ_SECT_LOAD;
0164 return flags;
0165 }
0166
0167 uint32_t
0168 rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
0169 int section,
0170 const char* name,
0171 const Elf_Shdr* shdr,
0172 const uint32_t flags)
0173 {
0174 (void) obj;
0175 (void) section;
0176 (void) name;
0177 (void) shdr;
0178 return flags;
0179 }
0180
0181 bool
0182 rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
0183 rtems_rtl_obj_sect* sect)
0184 {
0185 (void) obj;
0186 (void) sect;
0187 return false;
0188 }
0189
0190 bool
0191 rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
0192 rtems_rtl_obj_sect* sect)
0193 {
0194 (void) obj;
0195 (void) sect;
0196 return false;
0197 }
0198
0199 bool
0200 rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
0201 {
0202 return true;
0203 }
0204
0205 rtems_rtl_elf_rel_status
0206 rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
0207 const Elf_Rela* rela,
0208 const rtems_rtl_obj_sect* sect,
0209 const char* symname,
0210 const Elf_Byte syminfo,
0211 const Elf_Word symvalue)
0212 {
0213 (void) obj;
0214 (void) rela;
0215 (void) sect;
0216 (void) symname;
0217 (void) syminfo;
0218 (void) symvalue;
0219 rtems_rtl_set_error (EINVAL, "rela type record not supported");
0220 return rtems_rtl_elf_rel_failure;
0221 }
0222
0223 rtems_rtl_elf_rel_status
0224 rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
0225 const Elf_Rela* rela,
0226 const rtems_rtl_obj_sect* sect,
0227 const char* symname,
0228 const Elf_Byte syminfo,
0229 const Elf_Word symvalue)
0230 {
0231 (void) obj;
0232 (void) rela;
0233 (void) sect;
0234 (void) symname;
0235 (void) syminfo;
0236 (void) symvalue;
0237 rtems_rtl_set_error (EINVAL, "rela type record not supported");
0238 return rtems_rtl_elf_rel_failure;
0239 }
0240
0241 static rtems_rtl_elf_rel_status
0242 rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj,
0243 const Elf_Rel* rel,
0244 const rtems_rtl_obj_sect* sect,
0245 const char* symname,
0246 const Elf_Byte syminfo,
0247 const Elf_Word symvalue,
0248 const bool parsing)
0249 {
0250 Elf_Addr *where;
0251 Elf_Addr tmp;
0252 Elf_Word insn, addend;
0253 Elf_Word sign, i1, i2;
0254 uint16_t lower_insn, upper_insn;
0255
0256 where = (Elf_Addr *)(sect->base + rel->r_offset);
0257
0258 switch (ELF_R_TYPE(rel->r_info)) {
0259 case R_TYPE(NONE):
0260 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
0261 printf ("rtl: NONE %p in %s\n", where, rtems_rtl_obj_oname (obj));
0262 }
0263 break;
0264
0265 case R_TYPE(CALL):
0266 case R_TYPE(JUMP24):
0267 if (parsing)
0268 {
0269 addend = 0;
0270 }
0271 else
0272 {
0273 insn = *where;
0274
0275 if (insn & 0x00800000)
0276 addend = insn | 0xff000000;
0277 else addend = insn & 0x00ffffff;
0278
0279 if (isThumb(symvalue)) {
0280 if ((insn & 0xfe000000) == 0xfa000000);
0281 else {
0282 if ((insn & 0xff000000) == 0xeb000000) {
0283 *where = (insn & 0x00ffffff) | 0xfa000000;
0284 } else {
0285 printf("JUMP24 is not suppored from arm to thumb\n");
0286 return rtems_rtl_elf_rel_failure;
0287 }
0288 }
0289 }
0290 }
0291
0292 if (parsing && sect->base == 0) {
0293 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0294 printf ("rtl: JUMP24/PC24/CALL tramp cache\n");
0295 return rtems_rtl_elf_rel_tramp_cache;
0296 }
0297
0298 tmp = symvalue + (addend << 2) - (Elf_Addr)where;
0299 tmp = (Elf_Sword)tmp >> 2;
0300
0301 if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
0302 Elf_Word tramp_addr;
0303 size_t tramp_size = get_veneer_size(ELF_R_TYPE(rel->r_info));
0304
0305 if (parsing) {
0306 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0307 printf ("rtl: JUMP24/PC24/CALL tramp add\n");
0308 return rtems_rtl_elf_rel_tramp_add;
0309 }
0310
0311 if (!rtems_rtl_obj_has_tramp_space (obj, tramp_size)) {
0312 rtems_rtl_set_error (EINVAL,
0313 "%s: CALL/JUMP24: overflow: no tramp memory",
0314 sect->name);
0315 return rtems_rtl_elf_rel_failure;
0316 }
0317
0318 tramp_addr = ((Elf_Addr) obj->tramp_brk) | (symvalue & 1);
0319 obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue);
0320
0321 tmp = tramp_addr + (addend << 2) - (Elf_Addr)where;
0322 tmp = (Elf_Sword)tmp >> 2;
0323 }
0324
0325 if (!parsing) {
0326 *where = (*where & 0xff000000) | (tmp & 0xffffff);
0327
0328 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0329 printf ("rtl: JUMP24/PC24/CALL %p @ %p in %s\n",
0330 (void *)*where, where, rtems_rtl_obj_oname (obj));
0331 }
0332 break;
0333
0334 case R_TYPE(V4BX):
0335
0336 if (!parsing && rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
0337 printf ("rtl: V4BX @ %p in %s\n",
0338 where, rtems_rtl_obj_oname (obj));
0339 }
0340 break;
0341
0342 case R_TYPE(MOVT_ABS):
0343 case R_TYPE(MOVW_ABS_NC):
0344 if (!parsing) {
0345 insn = *where;
0346
0347 addend = ((insn >> 4) & 0xf000) | (insn & 0x0fff);
0348 if (addend & 0x8000)
0349 addend |= 0xffff0000;
0350
0351 tmp = symvalue + addend;
0352
0353 if (ELF_R_TYPE(rel->r_info) == R_TYPE(MOVW_ABS_NC))
0354 tmp &= 0xffff;
0355 else {
0356 tmp = (Elf_Sword)tmp >> 16;
0357 if (((Elf_Sword)tmp > 0x7fff) || ((Elf_Sword)tmp < -0x8000)) {
0358 printf("MOVT_ABS Overflow\n");
0359 return rtems_rtl_elf_rel_failure;
0360 }
0361 }
0362
0363 *where = (insn & 0xfff0f000) | ((tmp & 0xf000) << 4) | (tmp & 0xfff);
0364
0365 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0366 printf ("rtl: MOVT_ABS/MOVW_ABS_NC %p @ %p in %s\n",
0367 (void *)*where, where, rtems_rtl_obj_oname (obj));
0368 }
0369 break;
0370
0371 case R_TYPE(REL32):
0372 case R_TYPE(ABS32):
0373 case R_TYPE(GLOB_DAT):
0374 case R_TYPE(PREL31):
0375 case R_TYPE(TARGET1):
0376 case R_TYPE(TARGET2):
0377 if (!parsing) {
0378 if (__predict_true(RELOC_ALIGNED_P(where))) {
0379 tmp = *where + symvalue;
0380 if (isThumb(symvalue))
0381 tmp |= 1;
0382 if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
0383 ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
0384 tmp -= (Elf_Addr)where;
0385 else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
0386 tmp = sign_extend31(tmp - (Elf_Addr)where);
0387 if (!parsing) {
0388 *where = tmp;
0389 }
0390 } else {
0391 tmp = load_ptr(where) + symvalue;
0392 if (isThumb(symvalue))
0393 tmp |= 1;
0394 if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
0395 ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
0396 tmp -= (Elf_Addr)where;
0397 else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
0398 tmp = sign_extend31(tmp - (Elf_Addr)where);
0399 store_ptr(where, tmp);
0400 }
0401
0402 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0403 printf ("rtl: REL32/ABS32/GLOB_DAT/PREL31/TARGET2 %p @ %p in %s\n",
0404 (void *)tmp, where, rtems_rtl_obj_oname (obj));
0405 }
0406 break;
0407
0408 case R_TYPE(THM_MOVT_ABS):
0409 case R_TYPE(THM_MOVW_ABS_NC):
0410 if (!parsing) {
0411 upper_insn = *(uint16_t *)where;
0412 lower_insn = *((uint16_t *)where + 1);
0413
0414 addend = ((upper_insn & 0x000f) << 12) | ((upper_insn & 0x0400) << 1) |
0415 ((lower_insn & 0x7000) >> 4) | (lower_insn & 0x00ff);
0416 addend = (addend ^ 0x8000) - 0x8000;
0417
0418 tmp = addend + symvalue;
0419 if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
0420 tmp >>= 16;
0421
0422 *(uint16_t *)where = (uint16_t)((upper_insn & 0xfbf0) |
0423 ((tmp & 0xf000) >> 12) |
0424 ((tmp & 0x0800) >> 1));
0425 *((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0x8f00) |
0426 ((tmp & 0x0700) << 4) |
0427 (tmp & 0x00ff));
0428
0429 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
0430 printf ("rtl: THM_MOVT_ABS/THM_MOVW_ABS_NC %p @ %p in %s\n",
0431 (void *)*where, where, rtems_rtl_obj_oname (obj));
0432 }
0433 }
0434 break;
0435
0436 case R_TYPE(THM_JUMP24):
0437
0438 case R_TYPE(THM_PC22):
0439 if (parsing)
0440 {
0441 addend = 0;
0442 upper_insn = 0;
0443 lower_insn = 0;
0444 }
0445 else
0446 {
0447 upper_insn = *(uint16_t *)where;
0448 lower_insn = *((uint16_t *)where + 1);
0449 sign = (upper_insn & (1 << 10)) >> 10;
0450 i1 = ((lower_insn >> 13) & 1) ^ sign ? 0 : 1;
0451 i2 = ((lower_insn >> 11) & 1) ^ sign ? 0 : 1;
0452 tmp = (i1 << 23) | (i2 << 22) | ((upper_insn & 0x3ff) << 12) | ((lower_insn & 0x7ff) << 1);
0453 addend = (tmp | ((sign ? 0 : 1) << 24)) - (1 << 24);
0454 }
0455
0456 if (isThumb(symvalue) == false
0457 && ELF_R_TYPE(rel->r_info) != R_TYPE(THM_JUMP24)) {
0458
0459 lower_insn &= ~(1<<12);
0460 }
0461
0462 if (parsing && sect->base == 0) {
0463 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0464 printf ("rtl: THM_CALL/JUMP24 tramp cache\n");
0465 return rtems_rtl_elf_rel_tramp_cache;
0466 }
0467
0468 tmp = symvalue + addend;
0469 if (isThumb(symvalue)) {
0470 tmp = tmp - (Elf_Addr)where;
0471 } else {
0472
0473
0474
0475
0476 tmp = tmp - (Elf_Addr)((uintptr_t)where & 0xfffffffc);
0477 }
0478
0479 if (isThumb(symvalue) == false && ELF_R_TYPE(rel->r_info) == R_TYPE(THM_JUMP24)) {
0480 Elf_Word tramp_addr;
0481 size_t tramp_size = get_veneer_size(ELF_R_TYPE(rel->r_info));
0482
0483 if (parsing) {
0484 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0485 printf ("rtl: THM_JUMP24 tramp add: %08x - %p = %i\n",
0486 symvalue + addend, where, (Elf_Sword) tmp);
0487 return rtems_rtl_elf_rel_tramp_add;
0488 }
0489
0490 if (!rtems_rtl_obj_has_tramp_space (obj, tramp_size)) {
0491 rtems_rtl_set_error (EINVAL,
0492 "%s: THM_JUMP24: overflow: no tramp memory",
0493 sect->name);
0494 return rtems_rtl_elf_rel_failure;
0495 }
0496
0497 tramp_addr = (Elf_Addr) obj->tramp_brk;
0498 obj->tramp_brk = set_thumb_bx_veneer(obj->tramp_brk, symvalue);
0499
0500
0501 tmp = tramp_addr + addend;
0502
0503 tmp = tmp - (Elf_Addr)where;
0504 } else if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
0505 Elf_Word tramp_addr;
0506 size_t tramp_size = get_veneer_size(ELF_R_TYPE(rel->r_info));
0507
0508 if (parsing) {
0509 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0510 printf ("rtl: THM_CALL/JUMP24 tramp add: %08x - %p = %i\n",
0511 symvalue + addend, where, (Elf_Sword) tmp);
0512 return rtems_rtl_elf_rel_tramp_add;
0513 }
0514
0515 if (!rtems_rtl_obj_has_tramp_space (obj, tramp_size)) {
0516 rtems_rtl_set_error (EINVAL,
0517 "%s: THM_CALL/JUMP24: overflow: no tramp memory",
0518 sect->name);
0519 return rtems_rtl_elf_rel_failure;
0520 }
0521
0522 tramp_addr = ((Elf_Addr) obj->tramp_brk) | (symvalue & 1);
0523 tmp = tramp_addr + addend;
0524 if (isThumb(symvalue)) {
0525 obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue);
0526 tmp = tmp - (Elf_Addr)where;
0527 } else {
0528
0529
0530
0531
0532 obj->tramp_brk = (void *)RTEMS_ALIGN_UP((uintptr_t)obj->tramp_brk, 4);
0533 tramp_addr = (Elf_Addr) obj->tramp_brk;
0534 obj->tramp_brk = set_arm_veneer(obj->tramp_brk, symvalue);
0535
0536
0537
0538
0539 tmp = tmp - (Elf_Addr)((uintptr_t)where & 0xfffffffc);
0540 }
0541 }
0542
0543 if (!parsing) {
0544 uint16_t bl_tmp;
0545
0546 sign = (tmp >> 24) & 1;
0547 *(uint16_t *)where = (uint16_t)((upper_insn & 0xf800) | (sign << 10) |
0548 ((tmp >> 12) & 0x3ff));
0549
0550 bl_tmp = (uint16_t)((lower_insn & 0xd000)|
0551 ((sign ^ (~(tmp >> 23) & 1)) << 13) |
0552 ((sign ^ (~(tmp >> 22) & 1)) << 11) |
0553 ((tmp >> 1) & 0x7ff));
0554
0555 if ((bl_tmp & 0xf000) == 0xe000) {
0556 bl_tmp &= 0xfffe;
0557 }
0558 *((uint16_t *)where + 1) = bl_tmp;
0559
0560 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)){
0561 printf ("rtl: THM_CALL/JUMP24 %p @ %p in %s\n",
0562 (void *)*where, where, rtems_rtl_obj_oname (obj));
0563 }
0564 }
0565 break;
0566
0567 case R_TYPE(THM_JUMP19):
0568
0569 if (!isThumb(symvalue)) {
0570 printf("THM_JUMP19 to arm not supported\n");
0571 return rtems_rtl_elf_rel_failure;
0572 }
0573
0574 upper_insn = *(uint16_t *)where;
0575 lower_insn = *((uint16_t *)where + 1);
0576 sign = (upper_insn >> 10) & 0x1;
0577
0578 if ((((upper_insn & 0x3f) >> 7) & 0x7) == 0x7) {
0579 printf("THM_JUMP19 failed\n");
0580 return false;
0581 }
0582
0583 i1 = (lower_insn >> 13) & 0x1;
0584 i2 = (lower_insn >> 11) & 0x1;
0585
0586 tmp = ((i2 << 19) | (i1 << 18) | ((upper_insn & 0x3f) << 12) | ((lower_insn & 0x7ff) << 1));
0587 addend = (tmp | ((sign ? 0 : 1) << 20)) - (1 << 20);
0588 tmp = symvalue + addend;
0589
0590 tmp = tmp - (Elf_Addr)where;
0591
0592 if (((Elf_Sword)tmp > 0x7ffffe) || ((Elf_Sword)tmp < -0x800000)) {
0593 rtems_rtl_set_error (EINVAL, "%s: Overflow %" PRIu32 " "
0594 "THM_JUMP19 relocations",
0595 sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
0596 return rtems_rtl_elf_rel_failure;
0597 }
0598
0599 sign = (tmp >> 20) & 0x1;
0600 i2 = (tmp >> 19) & 0x1;
0601 i1 = (tmp >> 18) & 0x1;
0602
0603 *(uint16_t*)where = (upper_insn & 0xfbc0) | (sign << 10) | ((tmp >> 12) & 0x3f);
0604 *((uint16_t*)where + 1) = (lower_insn & 0xd000) | (i1 << 13) |
0605 (i2 << 11) | ((tmp >> 1) & 0x7ff);
0606
0607 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0608 printf ("rtl: THM_JUMP19 %p @ %p in %s\n",
0609 (void *)*where, where, rtems_rtl_obj_oname (obj));
0610 break;
0611
0612 case R_TYPE(TLS_LE32):
0613 if (!parsing) {
0614 addend = *where;
0615 *where = symvalue + addend;
0616 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0617 printf ("rtl: TLS_LE32 %p @ %p in %s\n",
0618 (void *)*where, where, rtems_rtl_obj_oname (obj));
0619 }
0620 break;
0621
0622 case R_TYPE(TLS_GD32):
0623 case R_TYPE(TLS_LDM32):
0624 case R_TYPE(TLS_LDO32):
0625 case R_TYPE(TLS_IE32):
0626 case R_TYPE(TLS_LDO12):
0627 case R_TYPE(TLS_LE12):
0628 case R_TYPE(TLS_IE12GP):
0629 printf("TSL relocations not supported\n");
0630
0631 default:
0632 printf ("rtl: reloc unknown: sym = %" PRIu32 ", type = %" PRIu32 ", offset = %p",
0633 ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
0634 (void *)rel->r_offset);
0635 if (!parsing)
0636 printf("contents = %p", (void *)*where);
0637 printf("\n");
0638 rtems_rtl_set_error (EINVAL,
0639 "%s: Unsupported relocation type %" PRIu32 " "
0640 "in non-PLT relocations",
0641 sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
0642 return rtems_rtl_elf_rel_failure;
0643 }
0644
0645 return rtems_rtl_elf_rel_no_error;
0646 }
0647
0648 rtems_rtl_elf_rel_status
0649 rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
0650 const Elf_Rel* rel,
0651 const rtems_rtl_obj_sect* sect,
0652 const char* symname,
0653 const Elf_Byte syminfo,
0654 const Elf_Word symvalue)
0655 {
0656 return rtems_rtl_elf_reloc_rel (obj,
0657 rel,
0658 sect,
0659 symname,
0660 syminfo,
0661 symvalue,
0662 true);
0663 }
0664
0665 rtems_rtl_elf_rel_status
0666 rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
0667 const Elf_Rel* rel,
0668 const rtems_rtl_obj_sect* sect,
0669 const char* symname,
0670 const Elf_Byte syminfo,
0671 const Elf_Word symvalue)
0672 {
0673 return rtems_rtl_elf_reloc_rel (obj,
0674 rel,
0675 sect,
0676 symname,
0677 syminfo,
0678 symvalue,
0679 false);
0680 }