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 #include <sys/cdefs.h>
0029
0030 #include <errno.h>
0031 #include <stdio.h>
0032 #include <sys/types.h>
0033 #include <sys/stat.h>
0034
0035 #include <rtems/rtl/rtl.h>
0036 #include "rtl-elf.h"
0037 #include "rtl-error.h"
0038 #include <rtems/rtl/rtl-trace.h>
0039 #include "rtl-unwind.h"
0040 #include "rtl-unwind-dw2.h"
0041
0042 uint32_t
0043 rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
0044 const Elf_Shdr* shdr) {
0045 (void) obj;
0046 (void) shdr;
0047 return 0;
0048 }
0049
0050 uint32_t
0051 rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
0052 int section,
0053 const char* name,
0054 const Elf_Shdr* shdr,
0055 const uint32_t flags) {
0056 (void) obj;
0057 (void) section;
0058 (void) name;
0059 (void) shdr;
0060 return flags;
0061 }
0062
0063 bool
0064 rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
0065 rtems_rtl_obj_sect* sect) {
0066 (void) obj;
0067 (void) sect;
0068 return false;
0069 }
0070
0071 bool
0072 rtems_rtl_elf_arch_section_free (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_rel_resolve_sym (Elf_Word type) {
0081 return type != 0;
0082 }
0083
0084 uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
0085 {
0086 (void) obj;
0087 return sizeof(uint32_t);
0088 }
0089
0090 size_t
0091 rtems_rtl_elf_relocate_tramp_max_size (void) {
0092
0093
0094
0095 return 0;
0096 }
0097
0098 rtems_rtl_elf_rel_status
0099 rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
0100 const Elf_Rel* rel,
0101 const rtems_rtl_obj_sect* sect,
0102 const char* symname,
0103 const Elf_Byte syminfo,
0104 const Elf_Word symvalue) {
0105 (void) obj;
0106 (void) rel;
0107 (void) sect;
0108 (void) symname;
0109 (void) syminfo;
0110 (void) symvalue;
0111 return rtems_rtl_elf_rel_no_error;
0112 }
0113
0114 static void write16le(void *loc, uint16_t val) {
0115 *((uint16_t *) loc) = val;
0116 }
0117
0118 static void write32le(void *loc, uint32_t val) {
0119 *((uint32_t *) loc) = val;
0120 }
0121
0122 static uint16_t read16le(void *loc) {
0123 return *((uint16_t *) loc);
0124 }
0125
0126 static uint32_t read32le(void *loc) {
0127 return *((uint32_t *) loc);
0128 }
0129
0130 static rtems_rtl_elf_rel_status
0131 rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
0132 const Elf_Rela* rela,
0133 const rtems_rtl_obj_sect* sect,
0134 const char* symname,
0135 const Elf_Byte syminfo,
0136 const Elf_Word symvalue,
0137 const bool parsing) {
0138 Elf_Word *where;
0139 Elf_Word addend = (Elf_Word)rela->r_addend;
0140 Elf_Addr target;
0141
0142 where = (Elf_Addr *)(sect->base + rela->r_offset);
0143
0144
0145 target = (Elf_Addr)symvalue + addend;
0146
0147 Elf_Word pcrel_val = target - ((Elf_Word)where);
0148
0149 if (parsing) {
0150 return rtems_rtl_elf_rel_no_error;
0151 }
0152
0153 switch (ELF_R_TYPE(rela->r_info)) {
0154 case R_TYPE(NONE):
0155 break;
0156
0157 case R_TYPE(64):
0158
0159 write16le(where,
0160 (read16le(where) & 0xFFFF0000) | (target >> 16));
0161
0162 write16le(where + 1,
0163 (read16le(where + 1) & 0xFFFF0000) | (target & 0xFFFF));
0164 break;
0165
0166 case R_TYPE(32):
0167 {
0168 uintptr_t addr = (uintptr_t)where;
0169 if ((uintptr_t)where & 3) {
0170
0171 uintptr_t addr_down = addr & ~3;
0172 uintptr_t addr_up = (addr + 3) & ~3;
0173
0174 uint32_t value_down = read32le((void*)addr_down);
0175 uint32_t value_up = read32le((void*)addr_up);
0176
0177
0178
0179
0180
0181 unsigned offset = addr & 3;
0182
0183
0184
0185
0186
0187 uint32_t new_value_down = (value_down & ((1 << (offset * 8)) - 1)) |
0188 (target << (offset * 8));
0189 uint32_t new_value_up = (value_up & ~((1 << (offset * 8)) - 1)) |
0190 (target >> ((4 - offset) * 8));
0191
0192 write32le((void*)addr_down, new_value_down);
0193 write32le((void*)addr_up, new_value_up);
0194 } else {
0195 write32le(where, target);
0196 }
0197 }
0198 break;
0199
0200 case R_TYPE(32_PCREL):
0201 write32le(where, pcrel_val);
0202
0203 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0204 printf ("rtl: R_MICROBLAZE_32_PCREL %p @ %p in %s\n",
0205 (void *) * (where), where, rtems_rtl_obj_oname (obj));
0206 break;
0207
0208 case R_TYPE(64_PCREL):
0209
0210
0211
0212 pcrel_val -= 4;
0213
0214 write16le(where,
0215 (read16le(where) & 0xFFFF0000) | (pcrel_val >> 16));
0216
0217 write16le(where + 1,
0218 (read16le(where + 1) & 0xFFFF0000) | (pcrel_val & 0xFFFF));
0219
0220 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0221 printf ("rtl: R_MICROBLAZE_64_PCREL %p @ %p in %s\n",
0222 (void *) * (where), where, rtems_rtl_obj_oname (obj));
0223 break;
0224
0225 case R_TYPE(32_PCREL_LO):
0226 write16le(where, (read16le(where) & 0xFFFF0000) | (pcrel_val & 0xFFFF));
0227 break;
0228
0229 default:
0230 rtems_rtl_set_error (EINVAL,
0231 "%s: Unsupported relocation type %d "
0232 "in non-PLT relocations",
0233 sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
0234 return rtems_rtl_elf_rel_failure;
0235 }
0236
0237 return rtems_rtl_elf_rel_no_error;
0238 }
0239
0240 rtems_rtl_elf_rel_status
0241 rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
0242 const Elf_Rela* rela,
0243 const rtems_rtl_obj_sect* sect,
0244 const char* symname,
0245 const Elf_Byte syminfo,
0246 const Elf_Word symvalue) {
0247 return rtems_rtl_elf_reloc_rela (obj,
0248 rela,
0249 sect,
0250 symname,
0251 syminfo,
0252 symvalue,
0253 false);
0254 }
0255
0256 rtems_rtl_elf_rel_status
0257 rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
0258 const Elf_Rela* rela,
0259 const rtems_rtl_obj_sect* sect,
0260 const char* symname,
0261 const Elf_Byte syminfo,
0262 const Elf_Word symvalue) {
0263 return rtems_rtl_elf_reloc_rela (obj,
0264 rela,
0265 sect,
0266 symname,
0267 syminfo,
0268 symvalue,
0269 true);
0270 }
0271
0272 rtems_rtl_elf_rel_status
0273 rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
0274 const Elf_Rel* rel,
0275 const rtems_rtl_obj_sect* sect,
0276 const char* symname,
0277 const Elf_Byte syminfo,
0278 const Elf_Word symvalue) {
0279 rtems_rtl_set_error (EINVAL, "rel type record not supported");
0280 return rtems_rtl_elf_rel_failure;
0281 }
0282
0283 bool
0284 rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
0285 const char* name,
0286 uint32_t flags) {
0287 return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
0288 }
0289
0290 bool
0291 rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj) {
0292 return rtems_rtl_elf_unwind_dw2_register (obj);
0293 }
0294
0295 bool
0296 rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj) {
0297 return rtems_rtl_elf_unwind_dw2_deregister (obj);
0298 }