Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  *  @file
0005  *
0006  *  @ingroup
0007  *
0008  *  @brief
0009  */
0010 
0011 /*
0012  * Copyright (C) 2014 Chris Johns <chrisj@rtems.org>.
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #include <sys/cdefs.h>
0037 
0038 #include <stdio.h>
0039 #include <rtems/rtl/rtl.h>
0040 #include <errno.h>
0041 #include "rtl-elf.h"
0042 #include "rtl-error.h"
0043 #include <rtems/rtl/rtl-trace.h>
0044 #include "rtl-unwind.h"
0045 #include "rtl-unwind-dw2.h"
0046 
0047 uint32_t
0048 rtems_rtl_elf_section_flags (const rtems_rtl_obj_t* obj,
0049                              const Elf_Shdr*        shdr)
0050 {
0051   return 0;
0052 }
0053 
0054 uint32_t
0055 rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
0056                                   int                  section,
0057                                   const char*          name,
0058                                   const Elf_Shdr*      shdr,
0059                                   const uint32_t       flags)
0060 {
0061   (void) obj;
0062   (void) section;
0063   (void) name;
0064   (void) shdr;
0065   return flags;
0066 }
0067 
0068 bool
0069 rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
0070                                   rtems_rtl_obj_sect*  sect)
0071 {
0072   (void) obj;
0073   (void) sect;
0074   return false;
0075 }
0076 
0077 bool
0078 rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
0079                                   rtems_rtl_obj_sect*  sect)
0080 {
0081   (void) obj;
0082   (void) sect;
0083   return false;
0084 }
0085 
0086 bool
0087 rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
0088 {
0089   return true;
0090 }
0091 
0092 static inline Elf_Addr
0093 load_ptr(void *where)
0094 {
0095     Elf_Addr res;
0096 
0097     memcpy(&res, where, sizeof(res));
0098 
0099     return (res);
0100 }
0101 
0102 uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
0103 {
0104   (void) obj;
0105   return sizeof(uint32_t);
0106 }
0107 
0108 size_t
0109 rtems_rtl_elf_relocate_tramp_max_size (void)
0110 {
0111   /*
0112    * Disable by returning 0.
0113    */
0114   return 0;
0115 }
0116 
0117 rtems_rtl_elf_rel_status
0118 rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
0119                                    const Elf_Rela*           rela,
0120                                    const rtems_rtl_obj_sect* sect,
0121                                    const char*               symname,
0122                                    const Elf_Byte            syminfo,
0123                                    const Elf_Word            symvalue)
0124 {
0125   (void) obj;
0126   (void) rela;
0127   (void) sect;
0128   (void) symname;
0129   (void) syminfo;
0130   (void) symvalue;
0131   return rtems_rtl_elf_rel_no_error;
0132 }
0133 
0134 rtems_rtl_elf_rel_status
0135 rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
0136                              const Elf_Rela*           rela,
0137                              const rtems_rtl_obj_sect* sect,
0138                              const char*               symname,
0139                              const Elf_Byte            syminfo,
0140                              const Elf_Word            symvalue)
0141 {
0142   Elf_Addr target = 0;
0143   Elf_Addr *where;
0144   Elf_Word tmp;
0145   Elf_Word size; //byte
0146 
0147   where = (Elf_Addr *)(sect->base + rela->r_offset);
0148 
0149   if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
0150       printf("rela relocation type is %d relocated address 0x%08x",
0151               ELF_R_TYPE(rela->r_info), where);
0152   }
0153 
0154   tmp = symvalue;
0155   switch (ELF_R_TYPE(rela->r_info)) {
0156     case R_TYPE(UNUSED0):
0157       break;
0158 
0159     case R_TYPE(HUIMM16):
0160       tmp = symvalue >> 16;
0161     case R_TYPE(LUIMM16):
0162     case R_TYPE(RIMM16):
0163       size = 2;
0164       break;
0165 
0166     case R_TYPE(BYTE4_DATA):
0167       size = 4;
0168       break;
0169 
0170     case R_TYPE(PCREL24):
0171     case R_TYPE(PCREL24_JU):
0172       where = (Elf_Addr*)((Elf_Addr)where - 2); /* Back 2 bytes */
0173       tmp = symvalue - (Elf_Addr)where;
0174       tmp >>= 1;
0175       if ((tmp & 0x20000000) == 0x20000000)
0176         tmp |= 0xc0000000;
0177 
0178       if ((tmp & 0xff000000) && (~tmp & 0xff800000)) {
0179         printf("PCREL24/PCREL24_JU Overflow\n");
0180         return rtems_rtl_elf_rel_failure;
0181       }
0182 
0183       tmp = (load_ptr(where) & 0x0000ff00) | ((tmp & 0x0000ffff) << 16) |
0184              ((tmp & 0x00ff0000) >> 16);
0185       size = 4;
0186       break;
0187 
0188     case R_TYPE(PCREL12_JUMP_S):
0189       tmp = symvalue - (Elf_Addr)where;
0190       tmp >>= 1;
0191       if ((tmp & 0x20000000) == 0x20000000)
0192         tmp |= 0xc0000000;
0193 
0194       if ((tmp & 0xfffff000) && (~tmp & 0xfffff800)) {
0195         printf("PCREL12_JUMP_S Overflow\n");
0196         return rtems_rtl_elf_rel_failure;
0197       }
0198 
0199       tmp = ((*(uint16_t *)where) & 0xf000) | (tmp & 0xfff);
0200       size = 2;
0201       break;
0202 
0203     default:
0204       printf("Unspported rela type\n");
0205       return rtems_rtl_elf_rel_failure;
0206   }
0207 
0208   memcpy((void*)where, &tmp, size);
0209 
0210   return rtems_rtl_elf_rel_no_error;
0211 }
0212 
0213 rtems_rtl_elf_rel_status
0214 rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
0215                                   const Elf_Rel*            rel,
0216                                   const rtems_rtl_obj_sect* sect,
0217                                   const char*               symname,
0218                                   const Elf_Byte            syminfo,
0219                                   const Elf_Word            symvalue)
0220 {
0221   (void) obj;
0222   (void) rel;
0223   (void) sect;
0224   (void) symname;
0225   (void) syminfo;
0226   (void) symvalue;
0227   rtems_rtl_set_error (EINVAL, "rel type record not supported");
0228   return rtems_rtl_elf_rel_failure;
0229 }
0230 
0231 rtems_rtl_elf_rel_status
0232 rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
0233                             const Elf_Rel*            rel,
0234                             const rtems_rtl_obj_sect* sect,
0235                             const char*               symname,
0236                             const Elf_Byte            syminfo,
0237                             const Elf_Word            symvalue)
0238 {
0239   (void) obj;
0240   (void) rel;
0241   (void) sect;
0242   (void) symname;
0243   (void) syminfo;
0244   (void) symvalue;
0245   rtems_rtl_set_error (EINVAL, "rel type record not supported");
0246   return rtems_rtl_elf_rel_failure;
0247 }
0248 
0249 bool
0250 rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
0251                             const char*          name,
0252                             uint32_t             flags)
0253 {
0254   return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
0255 }
0256 
0257 bool
0258 rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
0259 {
0260   return rtems_rtl_elf_unwind_dw2_register (obj);
0261 }
0262 
0263 bool
0264 rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
0265 {
0266   return rtems_rtl_elf_unwind_dw2_deregister (obj);
0267 }