Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:16

0001 /*
0002  * Taken from NetBSD and stripped of the relocations not needed on RTEMS.
0003  */
0004 
0005 /*  $NetBSD: mdreloc.c,v 1.26 2010/01/14 11:58:32 skrll Exp $   */
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    * Disable by returning 0.
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      * These are deferred until all other relocations have
0189      * been done.  All we do here is make sure that the
0190      * COPY relocation is not in a shared library.  They
0191      * are allowed only in executable files.
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 }