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 <stdio.h>
0011 #include <sys/types.h>
0012 #include <sys/stat.h>
0013
0014 #include <rtems/rtl/rtl.h>
0015 #include "rtl-elf.h"
0016 #include "rtl-error.h"
0017 #include <rtems/rtl/rtl-trace.h>
0018 #include "rtl-unwind.h"
0019 #include "rtl-unwind-dw2.h"
0020
0021 static inline int overflow_8_check(int value)
0022 {
0023 if ((value & 0xffffff00) && (~value & 0xffffff80))
0024 return true;
0025 return false;
0026 }
0027
0028 static inline int overflow_16_check(int value)
0029 {
0030 if ((value & 0xffff0000) && (~value & 0xffff8000))
0031 return true;
0032 return false;
0033 }
0034
0035 uint32_t
0036 rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
0037 const Elf_Shdr* shdr)
0038 {
0039 return 0;
0040 }
0041
0042 uint32_t
0043 rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
0044 int section,
0045 const char* name,
0046 const Elf_Shdr* shdr,
0047 const uint32_t flags)
0048 {
0049 (void) obj;
0050 (void) section;
0051 (void) name;
0052 (void) shdr;
0053 return flags;
0054 }
0055
0056 bool
0057 rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
0058 rtems_rtl_obj_sect* sect)
0059 {
0060 (void) obj;
0061 (void) sect;
0062 return false;
0063 }
0064
0065 bool
0066 rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
0067 rtems_rtl_obj_sect* sect)
0068 {
0069 (void) obj;
0070 (void) sect;
0071 return false;
0072 }
0073
0074 bool
0075 rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
0076 {
0077 return true;
0078 }
0079
0080 uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
0081 {
0082 (void) obj;
0083 return sizeof(uint32_t);
0084 }
0085
0086 size_t
0087 rtems_rtl_elf_relocate_tramp_max_size (void)
0088 {
0089
0090
0091
0092 return 0;
0093 }
0094
0095 rtems_rtl_elf_rel_status
0096 rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
0097 const Elf_Rela* rela,
0098 const rtems_rtl_obj_sect* sect,
0099 const char* symname,
0100 const Elf_Byte syminfo,
0101 const Elf_Word symvalue)
0102 {
0103 (void) obj;
0104 (void) rela;
0105 (void) sect;
0106 (void) symname;
0107 (void) syminfo;
0108 (void) symvalue;
0109 return rtems_rtl_elf_rel_no_error;
0110 }
0111
0112 rtems_rtl_elf_rel_status
0113 rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
0114 const Elf_Rela* rela,
0115 const rtems_rtl_obj_sect* sect,
0116 const char* symnane,
0117 const Elf_Byte syminfo,
0118 const Elf_Word symvalue)
0119 {
0120 Elf_Addr target = 0;
0121 Elf_Addr* where;
0122 Elf_Word tmp;
0123
0124 where = (Elf_Addr *)(sect->base + rela->r_offset);
0125
0126 switch (ELF_R_TYPE(rela->r_info)) {
0127 case R_TYPE(NONE):
0128 break;
0129
0130 case R_TYPE(PC8):
0131 tmp = symvalue + rela->r_addend - (Elf_Addr)where;
0132 if (overflow_8_check(tmp))
0133 return rtems_rtl_elf_rel_failure;
0134
0135 *(uint8_t *)where = tmp;
0136
0137 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0138 printf ("rtl: reloc R_TYPE_8/PC8 in %s --> %p (%p) in %s\n",
0139 sect->name, (void*) (symvalue + rela->r_addend),
0140 (void *)*where, rtems_rtl_obj_oname (obj));
0141 break;
0142
0143 case R_TYPE(PC16):
0144 tmp = symvalue + rela->r_addend - (Elf_Addr)where;
0145 if (overflow_16_check(tmp))
0146 return rtems_rtl_elf_rel_failure;
0147
0148 *(uint16_t*)where = tmp;
0149
0150 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0151 printf ("rtl: reloc R_TYPE_16/PC16 in %s --> %p (%p) in %s\n",
0152 sect->name, (void*) (symvalue + rela->r_addend),
0153 (void *)*where, rtems_rtl_obj_oname (obj));
0154 break;
0155 case R_TYPE(PC32):
0156 target = (Elf_Addr) symvalue + rela->r_addend;
0157 *where += target - (Elf_Addr)where;
0158
0159 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0160 printf ("rtl: reloc PC32 in %s --> %p (%p) in %s\n",
0161 sect->name, (void*) (symvalue + rela->r_addend),
0162 (void *)*where, rtems_rtl_obj_oname (obj));
0163 break;
0164
0165 case R_TYPE(GOT32):
0166 case R_TYPE(32):
0167 case R_TYPE(GLOB_DAT):
0168 target = (Elf_Addr) symvalue + rela->r_addend;
0169
0170 if (*where != target)
0171 *where = target;
0172
0173 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0174 printf ("rtl: reloc 32/GLOB_DAT in %s --> %p in %s\n",
0175 sect->name, (void *)*where,
0176 rtems_rtl_obj_oname (obj));
0177 break;
0178
0179 case R_TYPE(RELATIVE):
0180 *where += (Elf_Addr) sect->base + rela->r_addend;
0181 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0182 printf ("rtl: reloc RELATIVE in %s --> %p\n",
0183 rtems_rtl_obj_oname (obj), (void *)*where);
0184 break;
0185
0186 case R_TYPE(COPY):
0187
0188
0189
0190
0191
0192
0193 printf ("rtl: reloc COPY (please report)\n");
0194 break;
0195
0196 default:
0197 printf ("rtl: reloc unknown: sym = %u, type = %u, offset = %p, "
0198 "contents = %p\n",
0199 ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info),
0200 (void *)rela->r_offset, (void *)*where);
0201 rtems_rtl_set_error (EINVAL,
0202 "%s: Unsupported relocation type %d "
0203 "in non-PLT relocations",
0204 sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
0205 return rtems_rtl_elf_rel_failure;
0206 }
0207
0208 return rtems_rtl_elf_rel_no_error;
0209 }
0210
0211 rtems_rtl_elf_rel_status
0212 rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
0213 const Elf_Rel* rel,
0214 const rtems_rtl_obj_sect* sect,
0215 const char* symname,
0216 const Elf_Byte syminfo,
0217 const Elf_Word symvalue)
0218 {
0219 (void) obj;
0220 (void) rel;
0221 (void) sect;
0222 (void) symname;
0223 (void) syminfo;
0224 (void) symvalue;
0225 rtems_rtl_set_error (EINVAL, "rel type record not supported");
0226 return rtems_rtl_elf_rel_failure;
0227 }
0228
0229 rtems_rtl_elf_rel_status
0230 rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
0231 const Elf_Rel* rel,
0232 const rtems_rtl_obj_sect* sect,
0233 const char* symname,
0234 const Elf_Byte syminfo,
0235 const Elf_Word symvalue)
0236 {
0237 (void) obj;
0238 (void) rel;
0239 (void) sect;
0240 (void) symname;
0241 (void) syminfo;
0242 (void) symvalue;
0243 rtems_rtl_set_error (EINVAL, "rel type record not supported");
0244 return rtems_rtl_elf_rel_failure;
0245 }
0246
0247 bool
0248 rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
0249 const char* name,
0250 uint32_t flags)
0251 {
0252 return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
0253 }
0254
0255 bool
0256 rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
0257 {
0258 return rtems_rtl_elf_unwind_dw2_register (obj);
0259 }
0260
0261 bool
0262 rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
0263 {
0264 return rtems_rtl_elf_unwind_dw2_deregister (obj);
0265 }