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.14 2020/06/16 21:01:30 joerg Exp $ */
0006 
0007 /*-
0008  * Copyright (c) 2014 The NetBSD Foundation, Inc.
0009  * All rights reserved.
0010  *
0011  * This code is derived from software contributed to The NetBSD Foundation
0012  * by Matt Thomas of 3am Software Foundry.
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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
0024  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
0025  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0026  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
0027  * BE 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 /*-
0037  * Copyright (c) 2014-2015 The FreeBSD Foundation
0038  * All rights reserved.
0039  *
0040  * Portions of this software were developed by Andrew Turner
0041  * under sponsorship from the FreeBSD Foundation.
0042  *
0043  * Redistribution and use in source and binary forms, with or without
0044  * modification, are permitted provided that the following conditions
0045  * are met:
0046  * 1. Redistributions of source code must retain the above copyright
0047  *    notice, this list of conditions and the following disclaimer.
0048  * 2. Redistributions in binary form must reproduce the above copyright
0049  *    notice, this list of conditions and the following disclaimer in the
0050  *    documentation and/or other materials provided with the distribution.
0051  *
0052  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0053  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0054  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0055  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
0056  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0057  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0058  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0059  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0060  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0061  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0062  * SUCH DAMAGE.
0063  */
0064 
0065 #include <sys/cdefs.h>
0066 #ifndef lint
0067 __RCSID("$NetBSD: mdreloc.c,v 1.14 2020/06/16 21:01:30 joerg Exp $");
0068 #endif /* not lint */
0069 
0070 #include <sys/types.h>
0071 #include <string.h>
0072 #include <errno.h>
0073 #include <inttypes.h>
0074 #include <sys/stat.h>
0075 #include <sys/endian.h>
0076 
0077 #include <rtems/rtl/rtl.h>
0078 #include "rtl-elf.h"
0079 #include "rtl-error.h"
0080 #include <rtems/rtl/rtl-trace.h>
0081 #include <rtems/score/tls.h>
0082 
0083 #include "rtl-unwind.h"
0084 #include "rtl-unwind-dw2.h"
0085 
0086 struct tls_data {
0087   size_t    td_tlsindex;
0088   Elf_Addr  td_tlsoffs;
0089 };
0090 
0091 rtems_rtl_elf_rel_status
0092 rtems_rtl_elf_reloc_rela (
0093   rtems_rtl_obj*            obj,
0094   const Elf_Rela*           rela,
0095   const rtems_rtl_obj_sect* sect,
0096   const char*               symname,
0097   const Elf_Byte            syminfo,
0098   const Elf_Word            symvalue,
0099   const bool                parsing
0100 );
0101 
0102 #define __BITS(hi,lo) ((~((~(Elf_Addr)0)<<((hi)+1)))&((~(Elf_Addr)0)<<(lo)))
0103 #define WIDTHMASK(w) (0xffffffffffffffffUL >> (64 - (w)))
0104 
0105 static inline bool
0106 checkoverflow(Elf_Addr addr, int bitwidth, Elf_Addr targetaddr,
0107     const char *bitscale, void *where, Elf64_Addr off)
0108 {
0109   const Elf_Addr mask = ~__BITS(bitwidth - 1, 0);
0110 
0111   if (((addr & mask) != 0) && ((addr & mask) != mask)) {
0112     printf("kobj_reloc: Relocation 0x%" PRIxPTR " too far from %p"
0113         " (base+0x%jx) for %dbit%s\n",
0114         (uintptr_t)targetaddr, where, off, bitwidth, bitscale);
0115     return true;
0116   }
0117 
0118   return false;
0119 }
0120 
0121 static inline bool
0122 checkalign(Elf_Addr addr, int alignbyte, void *where, Elf64_Addr off)
0123 {
0124   if ((addr & (alignbyte - 1)) != 0) {
0125     printf("kobj_reloc: Relocation 0x%" PRIxPTR " unaligned at %p"
0126         " (base+0x%jx). must be aligned %d\n",
0127         (uintptr_t)addr, where, off, alignbyte);
0128     return true;
0129   }
0130   return false;
0131 }
0132 
0133 /*
0134  * Set to 1 to allow untested relocations. If you tested one and it
0135  * works or you fixed the relocation please remove the guard.
0136  */
0137 #define ALLOW_UNTESTED_RELOCS 1
0138 
0139 static void*
0140 set_veneer(void* trampoline, Elf_Addr target)
0141 {
0142   /*
0143    * http://shell-storm.org/online/Online-Assembler-and-Disassembler/
0144    *
0145    * ldr x9, #8
0146    * br x9
0147    *
0148    */
0149   uint64_t* tramp = (uint64_t*) trampoline;
0150 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
0151   *tramp++ = 0xd61f012058000049;
0152 #else
0153   *tramp++ = 0xd61f012058000049; /* not tested */
0154 #endif
0155   *tramp++ = (uint64_t) target;
0156   return tramp;
0157 }
0158 
0159 static size_t
0160 get_veneer_size(int type)
0161 {
0162   (void) type;
0163   return 16;
0164 }
0165 
0166 uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
0167 {
0168   (void) obj;
0169   return sizeof(uint64_t);
0170 }
0171 
0172 size_t
0173 rtems_rtl_elf_relocate_tramp_max_size (void)
0174 {
0175   return 16;
0176 }
0177 
0178 uint32_t
0179 rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
0180                              const Elf_Shdr*      shdr)
0181 {
0182   return 0;
0183 }
0184 
0185 uint32_t
0186 rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
0187                                   int                  section,
0188                                   const char*          name,
0189                                   const Elf_Shdr*      shdr,
0190                                   const uint32_t       flags)
0191 {
0192   (void) obj;
0193   (void) section;
0194   (void) name;
0195   (void) shdr;
0196   return flags;
0197 }
0198 
0199 bool
0200 rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
0201                                   rtems_rtl_obj_sect*  sect)
0202 {
0203   (void) obj;
0204   (void) sect;
0205   return false;
0206 }
0207 
0208 bool
0209 rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
0210                                  rtems_rtl_obj_sect*  sect)
0211 {
0212   (void) obj;
0213   (void) sect;
0214   return false;
0215 }
0216 
0217 bool
0218 rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
0219 {
0220   return true;
0221 }
0222 
0223 rtems_rtl_elf_rel_status
0224 rtems_rtl_elf_reloc_rela (rtems_rtl_obj*            obj,
0225                           const Elf_Rela*           rela,
0226                           const rtems_rtl_obj_sect* sect,
0227                           const char*               symname,
0228                           const Elf_Byte            syminfo,
0229                           const Elf_Word            symvalue,
0230                           const bool                parsing)
0231 {
0232   Elf64_Addr *where;
0233   Elf32_Addr *where32;
0234   Elf_Addr    off = rela->r_offset;
0235   Elf_Addr    target;
0236   Elf_Addr    raddr;
0237   uint32_t   *insn, immhi, immlo, shift;
0238 
0239   where = (Elf_Addr *)(sect->base + rela->r_offset);
0240   where32 = (void *)where;
0241 
0242   insn = (uint32_t *)where;
0243 
0244   /*
0245    * S - the address of the symbol
0246    * A - the addend of the reolcation
0247    * P - the address of the place being relocated (derived from r_offset)
0248    * Page(expr) - the page address of the expression expr, defined as (expr & ~0xFFF).
0249    * TPREL(expr) - the thread pointer offset of the expression expr
0250    */
0251   switch (ELF_R_TYPE(rela->r_info)) {
0252     case R_TYPE(NONE):
0253       if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
0254         printf ("rtl: NONE %p in %s\n", where, rtems_rtl_obj_oname (obj));
0255       }
0256       break;
0257 
0258     case R_TYPE(ABS64): /* word S + A */
0259     case R_TYPE(GLOB_DAT): /* word S + A */
0260       if (!parsing) {
0261         target = (Elf_Addr)symvalue + rela->r_addend;
0262 
0263         if (*where != target)
0264           *where = target;
0265 
0266         if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0267           printf ("rtl: reloc 64/GLOB_DAT in %s --> %p in %s\n",
0268                   sect->name, (void *)(uintptr_t)*where,
0269                   rtems_rtl_obj_oname (obj));
0270       }
0271       break;
0272 
0273     /*
0274      * If S is a normal symbol, resolves to the difference between the static
0275      * link address of S and the execution address of S. If S is the null symbol
0276      * (ELF symbol index 0), resolves to the difference between the static link
0277      * address of P and the execution address of P.
0278      */
0279     case R_TYPE(RELATIVE):  /* Delta(S) + A */
0280       if (!parsing) {
0281         *where = (Elf_Addr)(uintptr_t)(sect->base + rela->r_addend);
0282         if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0283           printf ("rtl: reloc RELATIVE in %s --> %p in %s\n",
0284                   sect->name, (void *)(uintptr_t)*where,
0285                   rtems_rtl_obj_oname (obj));
0286       }
0287       break;
0288 
0289     case R_TYPE(COPY):
0290       /*
0291        * These are deferred until all other relocations have
0292        * been done.  All we do here is make sure that the
0293        * COPY relocation is not in a shared library.  They
0294        * are allowed only in executable files.
0295        */
0296       printf("rtl: reloc COPY (please report)\n");
0297       break;
0298 
0299     case R_AARCH64_ADD_TPREL_HI12: /* TPREL(S + A) */
0300     case R_AARCH64_ADD_TPREL_LO12:
0301     case R_AARCH64_ADD_TPREL_LO12_NC:
0302       uint32_t of_check = 0;
0303       switch (ELF_R_TYPE(rela->r_info)) {
0304         case R_AARCH64_ADD_TPREL_LO12:
0305       of_check = 212;
0306     /* fallthrough */
0307         case R_AARCH64_ADD_TPREL_LO12_NC:
0308           shift = 0;
0309           break;
0310         case R_AARCH64_ADD_TPREL_HI12:
0311       of_check = 224;
0312           shift = 12;
0313           break;
0314         default:
0315           printf("illegal rtype: %" PRIu64 "\n", ELF_R_TYPE(rela->r_info));
0316           break;
0317       }
0318 
0319       if (!parsing) {
0320         target = (Elf_Addr)symvalue;
0321         target >>= shift;
0322     target &= WIDTHMASK(12);
0323         if (of_check && target >= of_check) {
0324           return rtems_rtl_elf_rel_failure;
0325         }
0326         *insn = htole32(
0327             (le32toh(*insn) & ~__BITS(21,10)) | (target << 10));
0328       }
0329       break;
0330 
0331     case R_AARCH64_ADD_ABS_LO12_NC: /* S + A */
0332     case R_AARCH64_LDST8_ABS_LO12_NC:
0333     case R_AARCH_LDST16_ABS_LO12_NC:
0334     case R_AARCH_LDST32_ABS_LO12_NC:
0335     case R_AARCH_LDST64_ABS_LO12_NC:
0336     case R_AARCH64_LDST128_ABS_LO12_NC:
0337       switch (ELF_R_TYPE(rela->r_info)) {
0338         case R_AARCH64_ADD_ABS_LO12_NC:
0339         case R_AARCH64_LDST8_ABS_LO12_NC:
0340           shift = 0;
0341           break;
0342         case R_AARCH_LDST16_ABS_LO12_NC:
0343           shift = 1;
0344           break;
0345         case R_AARCH_LDST32_ABS_LO12_NC:
0346           shift = 2;
0347           break;
0348         case R_AARCH_LDST64_ABS_LO12_NC:
0349           shift = 3;
0350           break;
0351         case R_AARCH64_LDST128_ABS_LO12_NC:
0352           shift = 4;
0353           break;
0354         default:
0355           printf("illegal rtype: %" PRIu64 "\n", ELF_R_TYPE(rela->r_info));
0356           break;
0357       }
0358 
0359       /*
0360        * S + A
0361        *  e.g.) add  x0,x0,#:lo12:<sym>+<addend>
0362        *        ldrb w0,[x0,#:lo12:<sym>+<addend>]
0363        *        ldrh w0,[x0,#:lo12:<sym>+<addend>]
0364        *        ldr  w0,[x0,#:lo12:<sym>+<addend>]
0365        *        ldr  x0,[x0,#:lo12:<sym>+<addend>]
0366        */
0367       if (!parsing) {
0368         target = (Elf_Addr)symvalue + rela->r_addend;
0369         if (checkalign(target, 1 << shift, where, off)) {
0370           printf ("rtl: reloc checkalign failed in %s --> %p in %s\n",
0371                   sect->name, (void *)(uintptr_t)*where,
0372                   rtems_rtl_obj_oname (obj));
0373           printf("ELF_R_TYPE is : %" PRIu64 "\n", ELF_R_TYPE(rela->r_info));
0374           break;
0375         }
0376         target &= WIDTHMASK(12);
0377         target >>= shift;
0378         *insn = htole32(
0379             (le32toh(*insn) & ~__BITS(21,10)) | (target << 10));
0380       }
0381       break;
0382 
0383     case R_AARCH64_ADR_PREL_PG_HI21:
0384       /*
0385        * Page(S + A) - Page(P)
0386        *  e.g.) adrp x0,<sym>+<addend>
0387        */
0388       if (!parsing) {
0389         target = (Elf_Addr)symvalue + rela->r_addend;
0390         target = target >> 12;
0391         raddr = target << 12;
0392         target -= (uintptr_t)where >> 12;
0393 
0394         if (checkoverflow(target, 21, raddr, " x 4k", where, off)) {
0395           printf("]] %d\n", __LINE__);
0396           return rtems_rtl_elf_rel_failure;
0397         }
0398 
0399         immlo = target & WIDTHMASK(2);
0400         immhi = (target >> 2) & WIDTHMASK(19);
0401         *insn = htole32((le32toh(*insn) &
0402             ~(__BITS(30,29) | __BITS(23,5))) |
0403             (immlo << 29) | (immhi << 5));
0404       }
0405       break;
0406 
0407     case R_AARCH_JUMP26:
0408     case R_AARCH_CALL26:
0409       /*
0410        * S + A - P
0411        *  e.g.) b <sym>+<addend>
0412        *        bl <sym>+<addend>
0413        */
0414       if (parsing && sect->base == 0) {
0415         if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0416           printf ("rtl: JUMP26/PC26/CALL tramp cache\n");
0417         return rtems_rtl_elf_rel_tramp_cache;
0418       }
0419 
0420       raddr = (Elf_Addr)symvalue + rela->r_addend;
0421       target = raddr - (uintptr_t)where;
0422 
0423       if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0424         printf (
0425           "rtl: JUMP26/PC26/CALL: insn=%p where=%p target=%p raddr=%p parsing=%d\n",
0426           insn, (void*) where, (void*)(uintptr_t) target, (void*)(uintptr_t) raddr,
0427           parsing
0428         );
0429 
0430       if (checkalign(target, 4, where, off)) {
0431         return rtems_rtl_elf_rel_failure;
0432       }
0433 
0434       target = (intptr_t)target >> 2;
0435 
0436       if (((Elf_Sword)target > 0x1FFFFFF) || ((Elf_Sword)target < -0x2000000)) {
0437         Elf_Word tramp_addr;
0438         size_t   tramp_size = get_veneer_size(ELF_R_TYPE(rela->r_info));
0439 
0440         if (parsing) {
0441           if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
0442             printf ("rtl: JUMP26/PC26/CALL tramp add\n");
0443           return rtems_rtl_elf_rel_tramp_add;
0444         }
0445 
0446         if (!rtems_rtl_obj_has_tramp_space (obj, tramp_size)) {
0447           rtems_rtl_set_error (EINVAL,
0448                                "%s: CALL/JUMP26: overflow: no tramp memory",
0449                                sect->name);
0450           return rtems_rtl_elf_rel_failure;
0451         }
0452 
0453         tramp_addr = ((Elf_Addr)(uintptr_t) obj->tramp_brk) | (symvalue & 1);
0454         obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue);
0455         target = tramp_addr + rela->r_addend - (uintptr_t)where;
0456         target = (uintptr_t)target >> 2;
0457       }
0458 
0459       if (checkoverflow(target, 26, raddr, " word", where, off)) {
0460         return rtems_rtl_elf_rel_failure;
0461       }
0462 
0463       if (!parsing) {
0464         target &= WIDTHMASK(26);
0465         *insn = htole32((le32toh(*insn) & ~__BITS(25,0)) | target);
0466       }
0467 
0468       break;
0469 
0470     case R_AARCH64_PREL32:
0471       /*
0472        * S + A - P
0473        *  e.g.) 1: .word <sym>+<addend>-1b
0474        */
0475       if (!parsing) {
0476         raddr = (Elf_Addr)symvalue + rela->r_addend;
0477         target = raddr - (uintptr_t)where;
0478         if (checkoverflow(target, 32, raddr, "", where, off)) {
0479           printf("]] %d\n", __LINE__);
0480           return rtems_rtl_elf_rel_failure;
0481         }
0482         *where32 = target;
0483       }
0484       break;
0485 
0486     case R_TYPE(TLSDESC):
0487       printf ("rtl: reloc TLSDESC in %s --> %p in %s\n",
0488               sect->name, (void *)(uintptr_t)*where,
0489               rtems_rtl_obj_oname (obj));
0490       break;
0491 
0492     case R_TLS_TYPE(TLS_DTPREL):
0493       printf ("rtl: reloc TLS_DTPREL in %s --> %p in %s\n",
0494               sect->name, (void *)(uintptr_t)*where,
0495               rtems_rtl_obj_oname (obj));
0496       break;
0497     case R_TLS_TYPE(TLS_DTPMOD):
0498       printf ("rtl: reloc TLS_DTPMOD in %s --> %p in %s\n",
0499               sect->name, (void *)(uintptr_t)*where,
0500               rtems_rtl_obj_oname (obj));
0501       break;
0502 
0503     case R_TLS_TYPE(TLS_TPREL):
0504       printf ("rtl: reloc TLS_TPREL in %s --> %p in %s\n",
0505               sect->name, (void *)(uintptr_t)*where,
0506               rtems_rtl_obj_oname (obj));
0507       break;
0508 
0509     default:
0510       printf ("rtl: Unsupported relocation type (%" PRIu64
0511               ") in %s --> %p in %s\n",
0512               ELF_R_TYPE(rela->r_info), sect->name, (void *)where,
0513               rtems_rtl_obj_oname (obj));
0514       return rtems_rtl_elf_rel_failure;
0515   }
0516 
0517   return rtems_rtl_elf_rel_no_error;
0518 }
0519 
0520 rtems_rtl_elf_rel_status
0521 rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
0522                                    const Elf_Rela*           rela,
0523                                    const rtems_rtl_obj_sect* sect,
0524                                    const char*               symname,
0525                                    const Elf_Byte            syminfo,
0526                                    const Elf_Word            symvalue)
0527 {
0528   return rtems_rtl_elf_reloc_rela (obj,
0529                                    rela,
0530                                    sect,
0531                                    symname,
0532                                    syminfo,
0533                                    symvalue,
0534                                    true);
0535 }
0536 
0537 rtems_rtl_elf_rel_status
0538 rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
0539                              const Elf_Rela*           rela,
0540                              const rtems_rtl_obj_sect* sect,
0541                              const char*               symname,
0542                              const Elf_Byte            syminfo,
0543                              const Elf_Word            symvalue)
0544 {
0545   return rtems_rtl_elf_reloc_rela (obj,
0546                                    rela,
0547                                    sect,
0548                                    symname,
0549                                    syminfo,
0550                                    symvalue,
0551                                    false);
0552 }
0553 
0554 rtems_rtl_elf_rel_status
0555 rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
0556                                   const Elf_Rel*            rel,
0557                                   const rtems_rtl_obj_sect* sect,
0558                                   const char*               symname,
0559                                   const Elf_Byte            syminfo,
0560                                   const Elf_Word            symvalue)
0561 {
0562   rtems_rtl_set_error (EINVAL, "rela type record not supported");
0563   return rtems_rtl_elf_rel_failure;
0564 }
0565 
0566 rtems_rtl_elf_rel_status
0567 rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
0568                             const Elf_Rel*            rel,
0569                             const rtems_rtl_obj_sect* sect,
0570                             const char*               symname,
0571                             const Elf_Byte            syminfo,
0572                             const Elf_Word            symvalue)
0573 {
0574   rtems_rtl_set_error (EINVAL, "rela type record not supported");
0575   return rtems_rtl_elf_rel_failure;
0576 }
0577 
0578 bool
0579 rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
0580                             const char*          name,
0581                             uint32_t             flags) {
0582   return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
0583 }
0584 
0585 bool
0586 rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj) {
0587   return rtems_rtl_elf_unwind_dw2_register (obj);
0588 }
0589 
0590 bool
0591 rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj) {
0592   return rtems_rtl_elf_unwind_dw2_deregister (obj);
0593 }