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 <inttypes.h>
0039 #include <stdio.h>
0040
0041 #include <rtems/rtl/rtl.h>
0042 #include "rtl-elf.h"
0043 #include "rtl-error.h"
0044 #include <rtems/rtl/rtl-trace.h>
0045 #include "rtl-unwind.h"
0046 #include "rtl-unwind-dw2.h"
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 #define _RF_S 0x80000000
0063 #define _RF_A 0x40000000
0064 #define _RF_P 0x20000000
0065 #define _RF_G 0x10000000
0066 #define _RF_B 0x08000000
0067 #define _RF_U 0x04000000
0068 #define _RF_SZ(s) (((s) & 0xff) << 8)
0069 #define _RF_RS(s) ( (s) & 0xff)
0070
0071 static const uint32_t reloc_target_flags[] = {
0072 0,
0073 _RF_S|_RF_A| _RF_SZ(8) | _RF_RS(0),
0074 _RF_S|_RF_A| _RF_SZ(16) | _RF_RS(0),
0075 _RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0),
0076 _RF_S|_RF_A|_RF_P| _RF_SZ(8) | _RF_RS(0),
0077 _RF_S|_RF_A|_RF_P| _RF_SZ(16) | _RF_RS(0),
0078 _RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(0),
0079 _RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(2),
0080 _RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(2),
0081 _RF_S|_RF_A| _RF_SZ(32) | _RF_RS(10),
0082 _RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0),
0083 _RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0),
0084 _RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0),
0085 _RF_G| _RF_SZ(32) | _RF_RS(0),
0086 _RF_G| _RF_SZ(32) | _RF_RS(0),
0087 _RF_G| _RF_SZ(32) | _RF_RS(10),
0088 _RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(0),
0089 _RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(10),
0090 _RF_A|_RF_P| _RF_SZ(32) | _RF_RS(2),
0091 _RF_SZ(32) | _RF_RS(0),
0092 _RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0),
0093 _RF_SZ(32) | _RF_RS(0),
0094 _RF_A| _RF_B| _RF_SZ(32) | _RF_RS(0),
0095 _RF_S|_RF_A|_RF_U| _RF_SZ(32) | _RF_RS(0),
0096
0097
0098 };
0099 #define RELOC_TARGET_FLAGS_SIZE \
0100 (sizeof(reloc_target_flags) / sizeof(reloc_target_flags[0]))
0101
0102 #define RTLD_DEBUG_RELOC
0103 #ifdef RTLD_DEBUG_RELOC
0104 static const char *reloc_names[] = {
0105 "NONE", "RELOC_8", "RELOC_16", "RELOC_32", "DISP_8",
0106 "DISP_16", "DISP_32", "WDISP_30", "WDISP_22", "HI22",
0107 "22", "13", "LO10", "GOT10", "GOT13",
0108 "GOT22", "PC10", "PC22", "WPLT30", "COPY",
0109 "GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32",
0110
0111
0112 "PLT32",
0113 "HIPLT22", "LOPLT10", "LOPLT10", "PCPLT22", "PCPLT32",
0114 "10", "11", "64", "OLO10", "HH22",
0115 "HM10", "LM22", "PC_HH22", "PC_HM10", "PC_LM22",
0116 "WDISP16", "WDISP19", "GLOB_JMP", "7", "5", "6",
0117 "DISP64", "PLT64", "HIX22", "LOX10", "H44", "M44",
0118 "L44", "REGISTER", "UA64", "UA16",
0119 "TLS_GD_HI22", "TLS_GD_LO10", "TLS_GD_ADD", "TLS_GD_CALL",
0120 "TLS_LDM_HI22", "TLS_LDM_LO10", "TLS_LDM_ADD", "TLS_LDM_CALL",
0121 "TLS_LDO_HIX22", "TLS_LDO_LOX10", "TLS_LDO_ADD", "TLS_IE_HI22",
0122 "TLS_IE_LO10", "TLS_IE_LD", "TLS_IE_LDX", "TLS_IE_ADD", "TLS_LE_HIX22",
0123 "TLS_LE_LOX10", "TLS_DTPMOD32", "TLS_DTPMOD64", "TLS_DTPOFF32",
0124 "TLS_DTPOFF64", "TLS_TPOFF32", "TLS_TPOFF64",
0125 };
0126 #endif
0127
0128 #define RELOC_RESOLVE_SYMBOL(t) ((reloc_target_flags[t] & _RF_S) != 0)
0129 #define RELOC_PC_RELATIVE(t) ((reloc_target_flags[t] & _RF_P) != 0)
0130 #define RELOC_BASE_RELATIVE(t) ((reloc_target_flags[t] & _RF_B) != 0)
0131 #define RELOC_UNALIGNED(t) ((reloc_target_flags[t] & _RF_U) != 0)
0132 #define RELOC_USE_ADDEND(t) ((reloc_target_flags[t] & _RF_A) != 0)
0133 #define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff)
0134 #define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff)
0135 #define RELOC_TLS(t) (t >= R_TYPE(TLS_GD_HI22))
0136
0137 static const int reloc_target_bitmask[] = {
0138 #define _BM(x) (~(-(1ULL << (x))))
0139 0,
0140 _BM(8), _BM(16), _BM(32),
0141 _BM(8), _BM(16), _BM(32),
0142 _BM(30), _BM(22),
0143 _BM(22), _BM(22),
0144 _BM(13), _BM(10),
0145 _BM(10), _BM(13), _BM(22),
0146 _BM(10), _BM(22),
0147 _BM(30), 0,
0148 -1, -1, -1,
0149 _BM(32)
0150 #undef _BM
0151 };
0152 #define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t])
0153
0154 uint32_t
0155 rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
0156 const Elf_Shdr* shdr)
0157 {
0158 return 0;
0159 }
0160
0161 uint32_t
0162 rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
0163 int section,
0164 const char* name,
0165 const Elf_Shdr* shdr,
0166 const uint32_t flags)
0167 {
0168 (void) obj;
0169 (void) section;
0170 (void) name;
0171 (void) shdr;
0172 return flags;
0173 }
0174
0175 bool
0176 rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
0177 rtems_rtl_obj_sect* sect)
0178 {
0179 (void) obj;
0180 (void) sect;
0181 return false;
0182 }
0183
0184 bool
0185 rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
0186 rtems_rtl_obj_sect* sect)
0187 {
0188 (void) obj;
0189 (void) sect;
0190 return false;
0191 }
0192
0193 bool
0194 rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
0195 {
0196 bool r = false;
0197 if (type < RELOC_TARGET_FLAGS_SIZE) {
0198 r = RELOC_RESOLVE_SYMBOL (type) ? true : false;
0199 }
0200 switch (type) {
0201 case R_TYPE(TLS_DTPOFF32):
0202 case R_TYPE(TLS_LE_HIX22):
0203 case R_TYPE(TLS_LE_LOX10):
0204 r = true;
0205 break;
0206 default:
0207 break;
0208 }
0209 return r;
0210 }
0211
0212 uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
0213 {
0214 (void) obj;
0215 return sizeof(uint32_t);
0216 }
0217
0218 size_t
0219 rtems_rtl_elf_relocate_tramp_max_size (void)
0220 {
0221
0222
0223
0224 return 0;
0225 }
0226
0227 rtems_rtl_elf_rel_status
0228 rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
0229 const Elf_Rela* rela,
0230 const rtems_rtl_obj_sect* sect,
0231 const char* symname,
0232 const Elf_Byte syminfo,
0233 const Elf_Word symvalue)
0234 {
0235 (void) obj;
0236 (void) rela;
0237 (void) sect;
0238 (void) symname;
0239 (void) syminfo;
0240 (void) symvalue;
0241 return rtems_rtl_elf_rel_no_error;
0242 }
0243
0244 rtems_rtl_elf_rel_status
0245 rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
0246 const Elf_Rela* rela,
0247 const rtems_rtl_obj_sect* sect,
0248 const char* symname,
0249 const Elf_Byte syminfo,
0250 const Elf_Word symvalue)
0251 {
0252 Elf_Addr *where;
0253 Elf_Word type, value, mask;
0254 Elf_Addr tmp = 0;
0255
0256 where = (Elf_Addr *) (sect->base + rela->r_offset);
0257
0258 type = ELF_R_TYPE(rela->r_info);
0259 if (type == R_TYPE(NONE))
0260 return rtems_rtl_elf_rel_no_error;
0261
0262
0263 if (type == R_TYPE(JMP_SLOT))
0264 return rtems_rtl_elf_rel_no_error;
0265
0266
0267 if (type == R_TYPE(COPY))
0268 return rtems_rtl_elf_rel_no_error;
0269
0270
0271
0272
0273
0274 if (type > R_TYPE(TLS_TPOFF64)) {
0275 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0276 printf("rtl: invalid reloc type: %d\n", (int) type);
0277 return rtems_rtl_elf_rel_failure;
0278 }
0279
0280 value = rela->r_addend;
0281
0282
0283
0284
0285 if (RELOC_TLS(type)) {
0286 switch (type) {
0287 case R_TYPE(TLS_DTPMOD32):
0288 #if NETBSD_CODE__NOT_USED
0289 *where = (Elf_Addr)defobj->tlsindex;
0290 #endif
0291
0292 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0293 printf("rtl: reloc: TLS_DTPMOD32 %s in %s --> %p\n",
0294 symname, rtems_rtl_obj_oname (obj), (void *)*where);
0295 break;
0296
0297 case R_TYPE(TLS_DTPOFF32):
0298 *where = (Elf_Addr)(symvalue + rela->r_addend);
0299
0300 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0301 printf("rtl: reloc: TLS_DTPOFF32 %s in %s --> %p\n",
0302 symname, rtems_rtl_obj_oname (obj), (void *)*where);
0303 break;
0304
0305 case R_TYPE(TLS_TPOFF32):
0306 #if NETBSD_CODE__NOT_USED
0307 if (!defobj->tls_static &&
0308 _rtld_tls_offset_allocate(__UNCONST(defobj)))
0309 return ;
0310
0311 *where = (Elf_Addr)(def->st_value -
0312 defobj->tlsoffset + rela->r_addend);
0313 #endif
0314 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0315 printf("rtl: reloc: TLS_TPOFF32 %s in %s --> %p\n",
0316 symname, rtems_rtl_obj_oname (obj), (void *)*where);
0317 return rtems_rtl_elf_rel_failure;
0318
0319 case R_TYPE(TLS_LE_HIX22):
0320 *where |= ((symvalue + rela->r_addend) ^ 0xffffffff) >> 10;
0321 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0322 printf("rtl: reloc: R_SPARC_TLS_LE_HIX22 %s in %s --> %p\n",
0323 symname, rtems_rtl_obj_oname (obj), (void *)*where);
0324 break;
0325
0326 case R_TYPE(TLS_LE_LOX10):
0327 *where |= ((symvalue + rela->r_addend) & 0x3ff) | 0x1c00;
0328 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0329 printf("rtl: reloc: R_SPARC_TLS_LE_LOX10 %s in %s --> %p\n",
0330 symname, rtems_rtl_obj_oname (obj), (void *)*where);
0331 break;
0332
0333 default:
0334 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0335 printf("rtl: reloc: unknown TLS relo: %d for %s in %s --> %p\n",
0336 type, symname, rtems_rtl_obj_oname (obj), (void *)*where);
0337 return rtems_rtl_elf_rel_failure;
0338 }
0339 return rtems_rtl_elf_rel_no_error;
0340 }
0341
0342
0343
0344
0345
0346 if (type > R_TYPE(6))
0347 return rtems_rtl_elf_rel_failure;
0348
0349
0350
0351
0352 if (type == R_TYPE (RELATIVE)) {
0353 *where += (Elf_Addr)(sect->base + value);
0354 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0355 printf ("rtl: reloc relative in %s --> %p",
0356 rtems_rtl_obj_oname (obj), (void *)*where);
0357 return rtems_rtl_elf_rel_no_error;
0358 }
0359
0360 if (RELOC_RESOLVE_SYMBOL (type)) {
0361
0362 value += symvalue;
0363 }
0364
0365 if (RELOC_PC_RELATIVE (type)) {
0366 value -= (Elf_Word)where;
0367 }
0368
0369 if (RELOC_BASE_RELATIVE (type)) {
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382 #define DIAGNOSTIC
0383 #ifdef DIAGNOSTIC
0384 if (value != 0 && *where != 0) {
0385 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0386 printf("rtl: reloc base_rel(%s): where=%p, *where 0x%" PRIu32 ", "
0387 "addend=0x%" PRIu32 ", base %p\n",
0388 rtems_rtl_obj_oname (obj),
0389 where, *where, rela->r_addend, sect->base);
0390 }
0391 #endif
0392 value += (Elf_Word)(sect->base + *where);
0393 }
0394
0395 mask = RELOC_VALUE_BITMASK (type);
0396 value >>= RELOC_VALUE_RIGHTSHIFT (type);
0397 value &= mask;
0398
0399 if (RELOC_UNALIGNED(type)) {
0400
0401
0402
0403 char *ptr = (char*) where;
0404 int i, size = RELOC_TARGET_SIZE (type) / 8;
0405
0406
0407 for (i = size - 1; i >= 0; i--)
0408 tmp = (tmp << 8) | ptr[i];
0409
0410 tmp &= ~mask;
0411 tmp |= value;
0412
0413
0414 for (i = size - 1; i >= 0; i--, tmp >>= 8)
0415 ptr[i] = tmp & 0xff;
0416 } else {
0417 *where &= ~mask;
0418 *where |= value;
0419 tmp = *where;
0420 }
0421
0422 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0423 printf ("rtl: %s %p @ %p in %s\n",
0424 reloc_names[ELF_R_TYPE(rela->r_info)],
0425 (void *)tmp, where, rtems_rtl_obj_oname (obj));
0426
0427 return rtems_rtl_elf_rel_no_error;
0428 }
0429
0430 rtems_rtl_elf_rel_status
0431 rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
0432 const Elf_Rel* rel,
0433 const rtems_rtl_obj_sect* sect,
0434 const char* symname,
0435 const Elf_Byte syminfo,
0436 const Elf_Word symvalue)
0437 {
0438 (void) obj;
0439 (void) rel;
0440 (void) sect;
0441 (void) symname;
0442 (void) syminfo;
0443 (void) symvalue;
0444 rtems_rtl_set_error (EINVAL, "rel type record not supported");
0445 return rtems_rtl_elf_rel_failure;
0446 }
0447
0448 rtems_rtl_elf_rel_status
0449 rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
0450 const Elf_Rel* rel,
0451 const rtems_rtl_obj_sect* sect,
0452 const char* symname,
0453 const Elf_Byte syminfo,
0454 const Elf_Word symvalue)
0455 {
0456 (void) obj;
0457 (void) rel;
0458 (void) sect;
0459 (void) symname;
0460 (void) syminfo;
0461 (void) symvalue;
0462 printf ("rtl: rel type record not supported; please report\n");
0463 return rtems_rtl_elf_rel_failure;
0464 }
0465
0466 bool
0467 rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
0468 const char* name,
0469 uint32_t flags)
0470 {
0471 return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
0472 }
0473
0474 bool
0475 rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
0476 {
0477 return rtems_rtl_elf_unwind_dw2_register (obj);
0478 }
0479
0480 bool
0481 rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
0482 {
0483 return rtems_rtl_elf_unwind_dw2_deregister (obj);
0484 }