Ticket #4069: v2-0001-libdl-riscv-Fix-RISCV-issues-with-libdl-tests.patch

File v2-0001-libdl-riscv-Fix-RISCV-issues-with-libdl-tests.patch, 12.9 KB (added by Chris Johns, on 09/11/20 at 08:24:12)

Tests dl01-dl04,dl06-dl09 pass with this patch on the SIS. Hesham, please test, review and push if you think it is OK.

  • cpukit/include/rtems/rtl/rtl-sym.h

    From 7549d1f31a4d7476c795c92e5e6478c98bb2539c Mon Sep 17 00:00:00 2001
    From: Chris Johns <chrisj@rtems.org>
    Date: Thu, 10 Sep 2020 15:04:24 +1000
    Subject: [PATCH v2] libdl/riscv: Fix RISCV issues with libdl tests
    
    - Support misaligned read and write accesses
    
    - Add a RISCV reloc trace
    
    - Add a better check for a valid symbol name. An empty name is
      considered invalid and should not be added to an object files
      list of unresolved symbols.
    
    Updates #4069
    ---
     cpukit/include/rtems/rtl/rtl-sym.h |   9 ++
     cpukit/libdl/rtl-elf.c             |  27 +++--
     cpukit/libdl/rtl-mdreloc-riscv.c   | 163 +++++++++++++++++++++++++----
     cpukit/libdl/rtl-sym.c             |  13 +++
     cpukit/libdl/rtl-unresolved.c      |   9 +-
     5 files changed, 187 insertions(+), 34 deletions(-)
    
    diff --git a/cpukit/include/rtems/rtl/rtl-sym.h b/cpukit/include/rtems/rtl/rtl-sym.h
    index 07cad4cab6..838c1d2b3a 100644
    a b void rtems_rtl_symbol_obj_erase_local (rtems_rtl_obj* obj); 
    137137 */
    138138void rtems_rtl_symbol_obj_erase (rtems_rtl_obj* obj);
    139139
     140/**
     141 * Is the symbol name valid? A valid symbol name must exist, i.e. not
     142 * NULL and the string has a length greater than 0.
     143 *
     144 * @param name Symbol name string.
     145 * @retval bool Return true if there is a valid symbol name.
     146 */
     147bool rtems_rtl_symbol_name_valid (const char* name);
     148
    140149#ifdef __cplusplus
    141150}
    142151#endif /* __cplusplus */
  • cpukit/libdl/rtl-elf.c

    diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c
    index 75b3d9c953..2f2c4c7792 100644
    a b  
    2828#include <unistd.h>
    2929
    3030#include <rtems/rtl/rtl.h>
     31#include <rtems/rtl/rtl-trace.h>
     32#include <rtems/rtl/rtl-unresolved.h>
     33
    3134#include "rtl-elf.h"
    3235#include "rtl-error.h"
    33 #include <rtems/rtl/rtl-trace.h>
    3436#include "rtl-trampoline.h"
    3537#include "rtl-unwind.h"
    36 #include <rtems/rtl/rtl-unresolved.h>
    3738
    3839/**
    3940 * The offsets in the reloc words.
    rtems_rtl_elf_reloc_parser (rtems_rtl_obj* obj, 
    276277  /*
    277278   * Handle any dependencies if there is a valid symbol.
    278279   */
    279   if (symname != NULL)
     280  if (rtems_rtl_symbol_name_valid (symname))
    280281  {
    281282    /*
    282283     * Find the symbol's object file. It cannot be NULL so ignore that result
    rtems_rtl_elf_reloc_relocator (rtems_rtl_obj* obj, 
    335336      rel_words[REL_R_ADDEND] = 0;
    336337    }
    337338
    338     if (!rtems_rtl_unresolved_add (obj,
    339                                    flags,
    340                                    symname,
    341                                    targetsect->section,
    342                                    rel_words))
    343       return false;
     339    if (rtems_rtl_symbol_name_valid (symname))
     340    {
     341      if (!rtems_rtl_unresolved_add (obj,
     342                                     flags,
     343                                     symname,
     344                                     targetsect->section,
     345                                     rel_words))
     346        return false;
    344347
    345     ++obj->unresolved;
     348      ++obj->unresolved;
     349    }
    346350  }
    347351  else
    348352  {
    rtems_rtl_elf_parse_sections (rtems_rtl_obj* obj, int fd, Elf_Ehdr* ehdr) 
    14341438      if (rtems_rtl_obj_aname_valid (obj))
    14351439      {
    14361440        const char* symname = rtems_rtl_elf_separated_section (name);
    1437         if (symname != NULL && rtems_rtl_symbol_global_find (symname))
     1441        if (rtems_rtl_symbol_name_valid (symname) &&
     1442            rtems_rtl_symbol_global_find (symname))
    14381443          flags &= ~RTEMS_RTL_OBJ_SECT_LOAD;
    14391444      }
    14401445
  • cpukit/libdl/rtl-mdreloc-riscv.c

    diff --git a/cpukit/libdl/rtl-mdreloc-riscv.c b/cpukit/libdl/rtl-mdreloc-riscv.c
    index e6778dcc90..688876b013 100644
    a b  
    3838#include <sys/cdefs.h>
    3939
    4040#include <errno.h>
     41#include <inttypes.h>
    4142#include <stdio.h>
    4243#include <sys/types.h>
    4344#include <sys/stat.h>
    rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj, 
    113114  return rtems_rtl_elf_rel_no_error;
    114115}
    115116
     117static const char* reloc_label(unsigned int r_type)
     118{
     119  const char* what = NULL;
     120  switch (r_type) {
     121  case R_TYPE(NONE):
     122    what = "NONE";
     123    break;
     124  case R_TYPE(RVC_BRANCH):
     125    what = "RVC_BRANCH";
     126    break;
     127  case R_TYPE(RVC_JUMP):
     128    what = "RVC_JUMP";
     129    break;
     130  case R_TYPE(RVC_LUI):
     131    what = "RVC_LUI";
     132    break;
     133  case R_TYPE(JAL):
     134    what = "JAL";
     135    break;
     136  case R_TYPE(BRANCH):
     137    what = "BRANCH";
     138    break;
     139  case R_TYPE(64):
     140    what = "64";
     141    break;
     142  case R_TYPE(32):
     143    what = "32";
     144    break;
     145  case R_TYPE(SET6):
     146    what = "SET6";
     147    break;
     148  case R_TYPE(SET8):
     149    what = "SET8";
     150    break;
     151  case R_TYPE(SET16):
     152    what = "SET16";
     153    break;
     154  case R_TYPE(SET32):
     155    what = "SET32";
     156    break;
     157  case R_TYPE(ADD8):
     158    what = "ADD8";
     159    break;
     160  case R_TYPE(ADD16):
     161    what = "ADD16";
     162    break;
     163  case R_TYPE(ADD32):
     164    what = "ADD32";
     165    break;
     166  case R_TYPE(ADD64):
     167    what = "ADD64";
     168    break;
     169  case R_TYPE(SUB6):
     170    what = "SUB6";
     171    break;
     172  case R_TYPE(SUB8):
     173    what = "SUB8";
     174    break;
     175  case R_TYPE(SUB16):
     176    what = "SUB16";
     177    break;
     178  case R_TYPE(SUB32):
     179    what = "SUB32";
     180    break;
     181  case R_TYPE(SUB64):
     182    what = "SUB64";
     183    break;
     184  case R_TYPE(32_PCREL):
     185    what = "32_PCREL";
     186    break;
     187  case R_TYPE(PCREL_HI20):
     188    what = "PCREL_HI20";
     189    break;
     190  case R_TYPE(GOT_HI20):
     191  case R_TYPE(HI20):
     192    what = "HI20";
     193    break;
     194  case R_TYPE(PCREL_LO12_I):
     195    what = "PCREL_LO12_I";
     196    break;
     197  case R_TYPE(LO12_I):
     198    what = "LO12_I";
     199    break;
     200  case R_TYPE(PCREL_LO12_S):
     201    what = "PCREL_LO12_S";
     202    break;
     203  case R_TYPE(LO12_S):
     204    what = "LO12_S";
     205    break;
     206  case R_TYPE(CALL_PLT):
     207  case R_TYPE(CALL):
     208    what = "CALL";
     209    break;
     210  default:
     211    break;
     212  }
     213  return what;
     214}
     215
    116216// Extract bits V[Begin:End], where range is inclusive, and Begin must be < 63.
    117217static uint32_t extractBits(uint64_t v, uint32_t begin, uint32_t end) {
    118218  return (v & ((1ULL << (begin + 1)) - 1)) >> end;
    static int64_t SignExtend64(uint64_t val, unsigned bits) { 
    122222  return (int64_t )(((int64_t) (val << (64 - bits))) >> (64 - bits));
    123223}
    124224
     225static void write8le(void *loc, uint8_t val) {
     226  *((uint8_t *) loc) = val;
     227}
     228
    125229static void write16le(void *loc, uint16_t val) {
    126230  *((uint16_t *) loc) = val;
    127231}
    128232
    129233static void write32le(void *loc, uint32_t val) {
    130   *((uint32_t *) loc) = val;
     234  if ((((intptr_t) loc) & 3) == 0)
     235    *((uint32_t *) loc) = val;
     236  else {
     237    write8le(loc, val >> 24);
     238    write8le(loc + 1, val >> 16);
     239    write8le(loc + 2, val >> 8);
     240    write8le(loc + 3, val);
     241  }
    131242}
    132243
    133244static void write64le(void *loc, uint64_t val) {
    134245  *((uint64_t *) loc) = val;
    135246}
    136247
     248static uint8_t read8le(void *loc) {
     249  return *((uint8_t *) loc);
     250}
     251
    137252static uint16_t read16le(void *loc) {
    138253  return *((uint16_t *) loc);
    139254}
    140255
    141256static uint32_t read32le(void *loc) {
    142   return *((uint32_t *) loc);
     257  if ((((intptr_t) loc) & 3) == 0)
     258    return *((uint32_t *) loc);
     259  return (read8le(loc) << 24) | (read8le(loc + 1) << 16) | (read8le(loc + 2) << 8) | read8le(loc + 3);
    143260}
    144261
    145262static uint64_t read64le(void *loc) {
    146   return *((uint64_t *) loc);
     263  if ((((intptr_t) loc) & 3) == 0)
     264    return *((uint64_t *) loc);
     265  return (((uint64_t) read32le(loc)) << 32) | (uint64_t) read32le(loc + 4);
    147266}
    148267
    149268static rtems_rtl_elf_rel_status
    150 rtems_rtl_elf_reloc_rela (rtems_rtl_obj*      obj,
     269rtems_rtl_elf_reloc_rela (rtems_rtl_obj*            obj,
    151270                          const Elf_Rela*           rela,
    152271                          const rtems_rtl_obj_sect* sect,
    153272                          const char*               symname,
    154273                          const Elf_Byte            syminfo,
    155274                          const Elf_Word            symvalue,
    156275                          const bool parsing) {
    157   Elf_Word *where;
    158   Elf_Word  tmp;
    159   Elf_Word addend = (Elf_Word) rela->r_addend;
    160   Elf_Word local = 0;
    161 
     276  Elf_Word *where = (Elf_Addr *)(sect->base + rela->r_offset);
    162277  char bits = (sizeof(Elf_Word) * 8);
    163   where = (Elf_Addr *)(sect->base + rela->r_offset);
    164278
    165279  // Final PCREL value
    166280  Elf_Word pcrel_val = symvalue - ((Elf_Word) where);
    167281
    168282  if (syminfo == STT_SECTION) {
    169     local = 1;
    170283    return rtems_rtl_elf_rel_no_error;
    171284  }
    172285
    rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, 
    174287    return rtems_rtl_elf_rel_no_error;
    175288  }
    176289
     290  if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
     291    const char* what = reloc_label(ELF_R_TYPE(rela->r_info));
     292    Elf_Word at_where = read32le(where);
     293    printf("rtl: reloc base_rel(%s): %s: where=%p, *where=0x%" PRIx32 ", "
     294           "addend=0x%" PRIu32 ", base %p\n",
     295           rtems_rtl_obj_oname (obj),
     296           what, where, at_where, rela->r_addend, sect->base);
     297  }
     298
    177299  switch (ELF_R_TYPE(rela->r_info)) {
    178300  case R_TYPE(NONE):
    179301    break;
    180302
    181303  case R_TYPE(RVC_BRANCH): {
    182     uint16_t insn = ((*where) & 0xFFFF) & 0xE383;
     304    uint16_t insn = (read32le(where) & 0xFFFF) & 0xE383;
    183305    uint16_t imm8 = extractBits(pcrel_val, 8, 8) << 12;
    184306    uint16_t imm4_3 = extractBits(pcrel_val, 4, 3) << 10;
    185307    uint16_t imm7_6 = extractBits(pcrel_val, 7, 6) << 5;
    rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, 
    192314  break;
    193315
    194316  case R_TYPE(RVC_JUMP): {
    195     uint16_t insn = ((*where) & 0xFFFF) & 0xE003;
     317    uint16_t insn = (read32le(where) & 0xFFFF) & 0xE003;
    196318    uint16_t imm11 = extractBits(pcrel_val, 11, 11) << 12;
    197319    uint16_t imm4 = extractBits(pcrel_val, 4, 4) << 11;
    198320    uint16_t imm9_8 = extractBits(pcrel_val, 9, 8) << 9;
    rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, 
    232354  break;
    233355
    234356  case R_TYPE(BRANCH): {
    235 
    236357    uint32_t insn = read32le(where) & 0x1FFF07F;
    237358    uint32_t imm12 = extractBits(pcrel_val, 12, 12) << 31;
    238359    uint32_t imm10_5 = extractBits(pcrel_val, 10, 5) << 25;
    rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, 
    252373    break;
    253374
    254375  case R_TYPE(SET6):
    255     *((uint8_t *) where) = (*where & 0xc0) | (symvalue & 0x3f);
     376    write8le(where, (read8le(where) & 0xc0) | (symvalue & 0x3f));
    256377    break;
    257378  case R_TYPE(SET8):
    258     *((uint8_t *) where) = symvalue;
     379    write8le(where, symvalue);
    259380    break;
    260381  case R_TYPE(SET16):
    261382    write16le(where, symvalue);
    rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, 
    265386    break;
    266387
    267388  case R_TYPE(ADD8):
    268     *((uint8_t *) where) = *((uint8_t *) where) + symvalue;
     389    write8le(where, read8le(where) + symvalue);
    269390    break;
    270391  case R_TYPE(ADD16):
    271392    write16le(where, read16le(where) + symvalue);
    rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, 
    278399    break;
    279400
    280401  case R_TYPE(SUB6):
    281     *((uint8_t *) where) = (*where & 0xc0) | (((*where & 0x3f) - symvalue) & 0x3f);
     402    write8le(where, (read8le(where) & 0xc0) | (((read8le(where) & 0x3f) - symvalue) & 0x3f));
    282403    break;
    283404  case R_TYPE(SUB8):
    284     *((uint8_t *) where) = *((uint8_t *) where) - symvalue;
     405    write8le(where, read8le(where) - symvalue);
    285406    break;
    286407  case R_TYPE(SUB16):
    287408    write16le(where, read16le(where) - symvalue);
    rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, 
    298419
    299420    if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
    300421      printf ("rtl: R_RISCV_32_PCREL %p @ %p in %s\n",
    301               (void *) * (where), where, rtems_rtl_obj_oname (obj));
     422              (void*) read32le(where), where, rtems_rtl_obj_oname (obj));
    302423
    303424  }
    304425  break;
    rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, 
    365486
    366487  default:
    367488    rtems_rtl_set_error (EINVAL,
    368                          "%s: Unsupported relocation type %ld "
     489                         "%s: Unsupported relocation type %" PRIu32 " "
    369490                         "in non-PLT relocations",
    370491                         sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
    371492    return rtems_rtl_elf_rel_failure;
  • cpukit/libdl/rtl-sym.c

    diff --git a/cpukit/libdl/rtl-sym.c b/cpukit/libdl/rtl-sym.c
    index 593069fba0..4fe08dcfaf 100644
    a b rtems_rtl_symbol_obj_erase (rtems_rtl_obj* obj) 
    299299    obj->global_syms = 0;
    300300  }
    301301}
     302
     303bool
     304rtems_rtl_symbol_name_valid(const char* name)
     305{
     306  if (name != NULL)
     307  {
     308    if (*name != '\0')
     309    {
     310      return true;
     311    }
     312  }
     313  return false;
     314}
  • cpukit/libdl/rtl-unresolved.c

    diff --git a/cpukit/libdl/rtl-unresolved.c b/cpukit/libdl/rtl-unresolved.c
    index 8e1c2abc90..c4c94e3f19 100644
    a b  
    2424#include <string.h>
    2525
    2626#include <rtems/rtl/rtl.h>
    27 #include "rtl-error.h"
    28 #include <rtems/rtl/rtl-unresolved.h>
     27#include <rtems/rtl/rtl-sym.h>
    2928#include <rtems/rtl/rtl-trace.h>
     29#include <rtems/rtl/rtl-unresolved.h>
     30
     31#include "rtl-error.h"
    3032#include "rtl-trampoline.h"
    3133
    3234static rtems_rtl_unresolv_block*
    rtems_rtl_unresolved_add (rtems_rtl_obj* obj, 
    547549    printf ("rtl: unresolv: add: %s(s:%d) -> %s\n",
    548550            rtems_rtl_obj_oname (obj), sect, name);
    549551
     552  if (!rtems_rtl_symbol_name_valid (name))
     553    return false;
     554
    550555  unresolved = rtems_rtl_unresolved_unprotected ();
    551556  if (!unresolved)
    552557    return false;