Changeset 0b416759 in rtems


Ignore:
Timestamp:
Apr 28, 2020, 3:58:20 AM (6 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
5, master
Children:
cfe8f7a
Parents:
396e9830
Message:

libdl/mips: Fix MIPS16hi/lo relocation support.

This patch is an updated version from:

https://lists.rtems.org/pipermail/users/2016-January/029740.html

Closes #3693

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libdl/rtl-mdreloc-mips.c

    r396e9830 r0b416759  
    22
    33#include <errno.h>
     4#include <inttypes.h>
    45#include <stdio.h>
    56#include <sys/types.h>
     
    119120  return rtems_rtl_elf_rel_no_error;
    120121}
     122
     123#define RTEMS_RTL_MIPS_HI16_MAX (128)
     124
     125static struct {
     126  Elf_Addr* where_hi16;
     127  Elf_Addr  ahl;
     128} mips_hi16_list[RTEMS_RTL_MIPS_HI16_MAX];
     129static size_t mips_hi16_list_cnt;
    121130
    122131/*
     
    137146{
    138147  Elf_Addr *where;
    139   Elf_Word  tmp;
     148  Elf_Word tmp;
    140149  Elf_Word addend = (Elf_Word)0;
    141150  Elf_Word local = 0;
     151  Elf_Addr *where_hi16;
     152  Elf_Addr ahl;
    142153  uint32_t t;
    143 
    144 
    145   static Elf_Addr *where_hi16;
    146   static Elf_Addr ahl;
    147154
    148155  where = (Elf_Addr *)(sect->base + rel->r_offset);
     
    206213
    207214      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
    208         printf ("rtl: R_MIPS_26 local=%lu @ %p in %s\n",
     215        printf ("rtl: R_MIPS_26 local=%" PRIu32 " @ %p in %s\n",
    209216                local, (void *)*(where), rtems_rtl_obj_oname (obj));
    210217      break;
    211218
    212219    case R_TYPE(HI16):
    213       ahl = addend << 16;
    214       where_hi16 = where;
    215 
     220      if (mips_hi16_list_cnt >= RTEMS_RTL_MIPS_HI16_MAX) {
     221        rtems_rtl_set_error (ENOMEM,
     222                             "%s: too many MIPS_HI16 relocs", sect->name);
     223        return false;
     224      }
     225      mips_hi16_list[mips_hi16_list_cnt].where_hi16 = where;
     226      mips_hi16_list[mips_hi16_list_cnt].ahl = addend << 16;
     227      ++mips_hi16_list_cnt;
    216228
    217229      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
     
    221233
    222234    case R_TYPE(LO16):
    223       //ahl += (int16_t)addend;
    224       t = ahl + (int16_t)addend;
     235      t = (int16_t) addend;
    225236      tmp = symvalue;
    226       if (tmp == 0)
     237      if (tmp == 0) {
     238        rtems_rtl_set_error (EINVAL,
     239                             "%s: symvalue is 0 in MIPS_LO16", sect->name);
    227240        return rtems_rtl_elf_rel_failure;
    228 
     241      }
     242
     243      /* reloc low part */
    229244      addend &= 0xffff0000;
    230245      addend |= (uint16_t)(t + tmp);
    231246      *where = addend;
    232247
    233       if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
    234         printf("*where %lx where %p\n", *where, where);
    235 
    236       addend = *where_hi16;
    237       addend &= 0xffff0000;
    238       addend |= ((t + tmp) - (int16_t)(t + tmp)) >> 16;
    239       *where_hi16 = addend;
    240 
    241       if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
    242         printf("*where_hi %lx where_hi %p\n", *where_hi16, where_hi16);
     248      if (rtems_rtl_trace(RTEMS_RTL_TRACE_RELOC))
     249        printf("*where %x where %p\n", *where, where);
     250
     251      /* reloc hi parts */
     252      while (mips_hi16_list_cnt != 0) {
     253        --mips_hi16_list_cnt;
     254        ahl = mips_hi16_list[mips_hi16_list_cnt].ahl;
     255        where_hi16 = mips_hi16_list[mips_hi16_list_cnt].where_hi16;
     256        addend = *(where_hi16);
     257        addend &= 0xffff0000;
     258        addend |= ((ahl + t + tmp) - (int16_t) (ahl + t + tmp)) >> 16;
     259        *(where_hi16) = addend;
     260        if (rtems_rtl_trace(RTEMS_RTL_TRACE_RELOC))
     261          printf("*where_hi %x where_hi %p ahl=%08x\n",
     262                 *(where_hi16), where_hi16, ahl);
     263      }
    243264
    244265      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
     
    267288
    268289    default:
    269       printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
     290      printf ("rtl: reloc unknown: sym = %" PRIu32 ", type = %" PRIu32 ", offset = %p, "
    270291              "contents = %p\n",
    271292              ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
    272293              (void *)rel->r_offset, (void *)*where);
    273294      rtems_rtl_set_error (EINVAL,
    274                            "%s: Unsupported relocation type %ld "
     295                           "%s: Unsupported relocation type %" PRIu32
    275296                           "in non-PLT relocations",
    276297                           sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
Note: See TracChangeset for help on using the changeset viewer.