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 <errno.h>
0039 #include <stdio.h>
0040 #include <sys/types.h>
0041 #include <sys/stat.h>
0042 
0043 #include <rtems/rtl/rtl.h>
0044 #include "rtl-elf.h"
0045 #include "rtl-error.h"
0046 #include <rtems/rtl/rtl-trace.h>
0047 #include "rtl-unwind.h"
0048 #include "rtl-unwind-dw2.h"
0049 
0050 uint32_t
0051 rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
0052                              const Elf_Shdr*      shdr)
0053 {
0054   return 0;
0055 }
0056 
0057 uint32_t
0058 rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
0059                                   int                  section,
0060                                   const char*          name,
0061                                   const Elf_Shdr*      shdr,
0062                                   const uint32_t       flags)
0063 {
0064   (void) obj;
0065   (void) section;
0066   (void) name;
0067   (void) shdr;
0068   return flags;
0069 }
0070 
0071 bool
0072 rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
0073                                   rtems_rtl_obj_sect*  sect)
0074 {
0075   (void) obj;
0076   (void) sect;
0077   return false;
0078 }
0079 
0080 bool
0081 rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
0082                                   rtems_rtl_obj_sect*  sect)
0083 {
0084   (void) obj;
0085   (void) sect;
0086   return false;
0087 }
0088 
0089 bool
0090 rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
0091 {
0092   return true;
0093 }
0094 
0095 uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
0096 {
0097   (void) obj;
0098   return sizeof(uint32_t);
0099 }
0100 
0101 size_t
0102 rtems_rtl_elf_relocate_tramp_max_size (void)
0103 {
0104   /*
0105    * Disable by returning 0.
0106    */
0107   return 0;
0108 }
0109 
0110 rtems_rtl_elf_rel_status
0111 rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
0112                                    const Elf_Rela*           rela,
0113                                    const rtems_rtl_obj_sect* sect,
0114                                    const char*               symname,
0115                                    const Elf_Byte            syminfo,
0116                                    const Elf_Word            symvalue)
0117 {
0118   (void) obj;
0119   (void) rela;
0120   (void) sect;
0121   (void) symname;
0122   (void) syminfo;
0123   (void) symvalue;
0124   return rtems_rtl_elf_rel_no_error;
0125 }
0126 
0127 rtems_rtl_elf_rel_status
0128 rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
0129                              const Elf_Rela*           rela,
0130                              const rtems_rtl_obj_sect* sect,
0131                              const char*               symname,
0132                              const Elf_Byte            syminfo,
0133                              const Elf_Word            symvalue)
0134 {
0135   Elf_Addr *where;
0136   Elf32_Word tmp;
0137   Elf32_Word insn;
0138 
0139 
0140   where = (Elf_Addr *)(sect->base + rela->r_offset);
0141 
0142   switch (ELF_R_TYPE(rela->r_info)) {
0143     case R_TYPE(NONE):
0144       break;
0145 
0146     case R_TYPE(HI16):
0147       insn = *where;
0148       /* orhi/mvhi instruction
0149        *  31--------26|25-21|20-16|15----0|
0150        * |0 1 1 1 1 0 |rY   |rX   |imm16  |
0151        */
0152       if (0x1e == (insn >> 26)) {
0153         insn &= 0xffff0000;
0154         insn |= ((symvalue + rela->r_addend) >> 16);
0155         *where = insn;
0156       }
0157       break;
0158 
0159     case R_TYPE(LO16):
0160       insn = *where;
0161       /* ori instruction
0162        *  31--------26|25-21|20-16|15----0|
0163        * |0 0 1 1 1 0 |rY   |rX   |imm16  |
0164        */
0165       if (0xe == (insn >> 26)) {
0166         insn &= 0xffff0000;
0167         insn |= ((symvalue + rela->r_addend) & 0xffff);
0168         *where = insn;
0169       }
0170       break;
0171 
0172     case R_TYPE(CALL):
0173       insn = *where;
0174       /*
0175        * calli instruction
0176        *  31-------26|25---0|
0177        * |1 1 1 1 1 0|imm26 |
0178        * Syntax: call imm26
0179        * Operation: ra = pc + 4; pc = pc + sign_extend(imm26<<2)
0180        */
0181       if (0x3e == (insn >> 26)) {
0182         Elf_Sword imm26 = symvalue +rela->r_addend - (Elf_Addr)where;
0183         imm26 = (imm26 >> 2) & 0x3ffffff;
0184         insn = 0xf8000000 + imm26;
0185         *where = insn;
0186       }
0187       break;
0188 
0189     case R_TYPE(BRANCH):
0190       insn = *where;
0191       tmp = symvalue + rela->r_addend - (Elf_Addr)where;
0192       tmp = (Elf32_Sword)tmp >> 2;
0193       if (((Elf32_Sword)tmp > 0x7fff) || ((Elf32_Sword)tmp < -0x8000)){
0194         printf("BRANCH Overflow\n");
0195         return rtems_rtl_elf_rel_failure;
0196       }
0197 
0198       *where = (*where & 0xffff0000) | (tmp & 0xffff);
0199       break;
0200 
0201     case R_TYPE(32):
0202       *where = symvalue + rela->r_addend;
0203       break;
0204 
0205     default:
0206       rtems_rtl_set_error (EINVAL, "rela type record not supported");
0207       printf("Unsupported reloc types\n");
0208       return rtems_rtl_elf_rel_failure;
0209   }
0210 
0211   if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
0212       printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info));
0213       printf("relocated address 0x%08lx\n", (Elf_Addr)where);
0214   }
0215 
0216   return rtems_rtl_elf_rel_no_error;
0217 }
0218 
0219 rtems_rtl_elf_rel_status
0220 rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
0221                                   const Elf_Rel*            rel,
0222                                   const rtems_rtl_obj_sect* sect,
0223                                   const char*               symname,
0224                                   const Elf_Byte            syminfo,
0225                                   const Elf_Word            symvalue)
0226 {
0227   (void) obj;
0228   (void) rela;
0229   (void) sect;
0230   (void) symname;
0231   (void) syminfo;
0232   (void) symvalue;
0233   rtems_rtl_set_error (EINVAL, "rel type record not supported");
0234   return rtems_rtl_elf_rel_failure;
0235 }
0236 
0237 rtems_rtl_elf_rel_status
0238 rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
0239                             const Elf_Rel*            rel,
0240                             const rtems_rtl_obj_sect* sect,
0241                             const char*               symname,
0242                             const Elf_Byte            syminfo,
0243                             const Elf_Word            symvalue)
0244 {
0245   (void) obj;
0246   (void) rela;
0247   (void) sect;
0248   (void) symname;
0249   (void) syminfo;
0250   (void) symvalue;
0251   rtems_rtl_set_error (EINVAL, "rela type record not supported");
0252   return rtems_rtl_elf_rel_failure;
0253 }
0254 
0255 bool
0256 rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
0257                             const char*          name,
0258                             uint32_t             flags)
0259 {
0260   return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
0261 }
0262 
0263 bool
0264 rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
0265 {
0266   return rtems_rtl_elf_unwind_dw2_register (obj);
0267 }
0268 
0269 bool
0270 rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
0271 {
0272   return rtems_rtl_elf_unwind_dw2_deregister (obj);
0273 }