[PATCH 1/5] microblaze: Add libdl support

Alex White alex.white at oarcorp.com
Mon Aug 28 01:30:09 UTC 2023


---
 cpukit/libdl/rtl-mdreloc-microblaze.c         | 291 ++++++++++++++++++
 cpukit/libdl/rtl-tls.c                        |   2 +-
 .../microblaze/include/machine/elf_machdep.h  |  83 +++++
 spec/build/cpukit/cpumicroblaze.yml           |   3 +
 spec/build/cpukit/objdl.yml                   |   2 +
 spec/build/cpukit/objdlmicroblaze.yml         |  15 +
 spec/build/cpukit/optlibdl.yml                |   1 +
 7 files changed, 396 insertions(+), 1 deletion(-)
 create mode 100644 cpukit/libdl/rtl-mdreloc-microblaze.c
 create mode 100644 cpukit/score/cpu/microblaze/include/machine/elf_machdep.h
 create mode 100644 spec/build/cpukit/objdlmicroblaze.yml

diff --git a/cpukit/libdl/rtl-mdreloc-microblaze.c b/cpukit/libdl/rtl-mdreloc-microblaze.c
new file mode 100644
index 0000000000..b8834b203b
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-microblaze.c
@@ -0,0 +1,291 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2023 On-Line Applications Research Corporation (OAR)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include <rtems/rtl/rtl-trace.h>
+#include "rtl-unwind.h"
+#include "rtl-unwind-dw2.h"
+
+uint32_t
+rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
+                             const Elf_Shdr*      shdr) {
+  (void) obj;
+  (void) shdr;
+  return 0;
+}
+
+uint32_t
+rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
+                                  int                  section,
+                                  const char*          name,
+                                  const Elf_Shdr*      shdr,
+                                  const uint32_t       flags) {
+  (void) obj;
+  (void) section;
+  (void) name;
+  (void) shdr;
+  return flags;
+}
+
+bool
+rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
+                                  rtems_rtl_obj_sect*  sect) {
+  (void) obj;
+  (void) sect;
+  return false;
+}
+
+bool
+rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
+                                 rtems_rtl_obj_sect*  sect) {
+  (void) obj;
+  (void) sect;
+  return false;
+}
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type) {
+  return type != 0;
+}
+
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void) {
+  /*
+   * Disable by returning 0.
+   */
+  return 0;
+}
+
+rtems_rtl_elf_rel_status
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj*            obj,
+                                  const Elf_Rel*            rel,
+                                  const rtems_rtl_obj_sect* sect,
+                                  const char*               symname,
+                                  const Elf_Byte            syminfo,
+                                  const Elf_Word            symvalue) {
+  (void) obj;
+  (void) rel;
+  (void) sect;
+  (void) symname;
+  (void) syminfo;
+  (void) symvalue;
+  return rtems_rtl_elf_rel_no_error;
+}
+
+static void write16le(void *loc, uint16_t val) {
+  *((uint16_t *) loc) = val;
+}
+
+static void write32le(void *loc, uint32_t val) {
+  *((uint32_t *) loc) = val;
+}
+
+static uint16_t read16le(void *loc) {
+  return *((uint16_t *) loc);
+}
+
+static uint32_t read32le(void *loc) {
+  return *((uint32_t *) loc);
+}
+
+static rtems_rtl_elf_rel_status
+rtems_rtl_elf_reloc_rela (rtems_rtl_obj*            obj,
+                          const Elf_Rela*           rela,
+                          const rtems_rtl_obj_sect* sect,
+                          const char*               symname,
+                          const Elf_Byte            syminfo,
+                          const Elf_Word            symvalue,
+                          const bool                parsing) {
+  Elf_Word *where;
+  Elf_Word addend = (Elf_Word)rela->r_addend;
+  Elf_Addr target;
+
+  where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+  /* Final PCREL value */
+  Elf_Word pcrel_val = symvalue - ((Elf_Word)where);
+
+  if (parsing) {
+    return rtems_rtl_elf_rel_no_error;
+  }
+
+  switch (ELF_R_TYPE(rela->r_info)) {
+  case R_TYPE(NONE):
+    break;
+
+  case R_TYPE(64):
+    target = (Elf_Addr)symvalue + addend;
+    /* Set the lower 16 bits of where to the upper 16 bits of target */
+    write16le(where,
+              (read16le(where) & 0xFFFF0000) | (target >> 16));
+    /* Set the lower 16 bits of where + 4 to the lower 16 bits of target */
+    write16le(where + 1,
+              (read16le(where + 1) & 0xFFFF0000) | (target & 0xFFFF));
+    break;
+
+  case R_TYPE(32):
+    {
+      uintptr_t addr = (uintptr_t)where;
+      if ((uintptr_t)where & 3) {
+        /* `where` is not aligned to a 4-byte boundary. */
+        uintptr_t addr_down = addr & ~3;
+        uintptr_t addr_up = (addr + 3) & ~3;
+
+        uint32_t value_down = read32le((void*)addr_down);
+        uint32_t value_up = read32le((void*)addr_up);
+
+        /*
+         * Calculate how many bytes `where` is offset from the previous 4-byte
+         * boundary.
+         */
+        unsigned offset = addr & 3;
+
+        /*
+         * Combine `symvalue` with `value_down` and `value_up` to form the new
+         * values to write.
+         */
+        uint32_t new_value_down = (value_down & ((1 << (offset * 8)) - 1)) |
+          (symvalue << (offset * 8));
+        uint32_t new_value_up = (value_up & ~((1 << (offset * 8)) - 1)) |
+          (symvalue >> ((4 - offset) * 8));
+
+        write32le((void*)addr_down, new_value_down);
+        write32le((void*)addr_up, new_value_up);
+      } else {
+        write32le(where, symvalue);
+      }
+    }
+    break;
+
+  case R_TYPE(32_PCREL):
+    write32le(where, pcrel_val);
+
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+      printf ("rtl: R_MICROBLAZE_32_PCREL %p @ %p in %s\n",
+              (void *) * (where), where, rtems_rtl_obj_oname (obj));
+    break;
+
+  case R_TYPE(64_PCREL):
+    /*
+     * Compensate for the fact that the PC is 4 bytes ahead of the instruction
+     */
+    target = pcrel_val - 4;
+    /* Set the lower 16 bits of where to the upper 16 bits of target */
+    write16le(where,
+              (read16le(where) & 0xFFFF0000) | (target >> 16));
+    /* Set the lower 16 bits of where + 4 to the lower 16 bits of target */
+    write16le(where + 1,
+              (read16le(where + 1) & 0xFFFF0000) | (target & 0xFFFF));
+
+    if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+      printf ("rtl: R_MICROBLAZE_64_PCREL %p @ %p in %s\n",
+              (void *) * (where), where, rtems_rtl_obj_oname (obj));
+    break;
+
+  case R_TYPE(32_PCREL_LO):
+    write16le(where, (read16le(where) & 0xFFFF0000) | (pcrel_val & 0xFFFF));
+    break;
+
+  default:
+    rtems_rtl_set_error (EINVAL,
+                         "%s: Unsupported relocation type %d "
+                         "in non-PLT relocations",
+                         sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
+    return rtems_rtl_elf_rel_failure;
+  }
+
+  return rtems_rtl_elf_rel_no_error;
+}
+
+rtems_rtl_elf_rel_status
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj*            obj,
+                             const Elf_Rela*           rela,
+                             const rtems_rtl_obj_sect* sect,
+                             const char*               symname,
+                             const Elf_Byte            syminfo,
+                             const Elf_Word            symvalue) {
+  return rtems_rtl_elf_reloc_rela (obj,
+                                   rela,
+                                   sect,
+                                   symname,
+                                   syminfo,
+                                   symvalue,
+                                   false);
+}
+
+rtems_rtl_elf_rel_status
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj*            obj,
+                                   const Elf_Rela*           rela,
+                                   const rtems_rtl_obj_sect* sect,
+                                   const char*               symname,
+                                   const Elf_Byte            syminfo,
+                                   const Elf_Word            symvalue) {
+  return rtems_rtl_elf_reloc_rela (obj,
+                                   rela,
+                                   sect,
+                                   symname,
+                                   syminfo,
+                                   symvalue,
+                                   true);
+}
+
+rtems_rtl_elf_rel_status
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj*            obj,
+                            const Elf_Rel*            rel,
+                            const rtems_rtl_obj_sect* sect,
+                            const char*               symname,
+                            const Elf_Byte            syminfo,
+                            const Elf_Word            symvalue) {
+  rtems_rtl_set_error (EINVAL, "rel type record not supported");
+  return rtems_rtl_elf_rel_failure;
+}
+
+bool
+rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
+                            const char*          name,
+                            uint32_t             flags) {
+  return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
+}
+
+bool
+rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj) {
+  return rtems_rtl_elf_unwind_dw2_register (obj);
+}
+
+bool
+rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj) {
+  return rtems_rtl_elf_unwind_dw2_deregister (obj);
+}
diff --git a/cpukit/libdl/rtl-tls.c b/cpukit/libdl/rtl-tls.c
index 0b940c270b..95ca47fe6a 100644
--- a/cpukit/libdl/rtl-tls.c
+++ b/cpukit/libdl/rtl-tls.c
@@ -97,7 +97,7 @@
 #elif defined(__powerpc__)
 #include <stdint.h>
 # define __get_tls() ({ void** __val; register uintptr_t tp __asm__( "2" ); __val = (void**) tp; __val; })
-#elif defined(__m68k__) || defined(__v850__)
+#elif defined(__m68k__) || defined(__v850__) || defined(__microblaze__)
 /* No TLS support */
 # define __get_tls() (void*) 0UL
 #else
diff --git a/cpukit/score/cpu/microblaze/include/machine/elf_machdep.h b/cpukit/score/cpu/microblaze/include/machine/elf_machdep.h
new file mode 100644
index 0000000000..e6d661c596
--- /dev/null
+++ b/cpukit/score/cpu/microblaze/include/machine/elf_machdep.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2023 On-Line Applications Research Corporation (OAR)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MICROBLAZE_ELF_MACHDEP_H_
+#define _MICROBLAZE_ELF_MACHDEP_H_
+
+#define ELF64_MACHDEP_ID EM_MICROBLAZE
+#define ELF32_MACHDEP_ID EM_MICROBLAZE
+
+#define ELF64_MACHDEP_ENDIANNESS ELFDATA2LSB
+#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
+
+#define ELF32_MACHDEP_ID_CASES \
+  case EM_MICROBLAZE:          \
+    break;
+
+#define ELF64_MACHDEP_ID_CASES \
+  case EM_MICROBLAZE:          \
+    break;
+
+#define KERN_ELFSIZE 32
+#define ARCH_ELFSIZE 32 /* MD native binary size */
+
+/* Processor specific relocation types */
+
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+#define R_MICROBLAZE_GNU_VTINHERIT 11
+#define R_MICROBLAZE_GNU_VTENTRY 12
+#define R_MICROBLAZE_GOTPC_64 13
+#define R_MICROBLAZE_GOT_64 14
+#define R_MICROBLAZE_PLT_64 15
+#define R_MICROBLAZE_REL 16
+#define R_MICROBLAZE_JUMP_SLOT 17
+#define R_MICROBLAZE_GLOB_DAT 18
+#define R_MICROBLAZE_GOTOFF_64 19
+#define R_MICROBLAZE_GOTOFF_32 20
+#define R_MICROBLAZE_COPY 21
+#define R_MICROBLAZE_TLS 22
+#define R_MICROBLAZE_TLSGD 23
+#define R_MICROBLAZE_TLSLD 24
+#define R_MICROBLAZE_TLSDTPMOD32 25
+#define R_MICROBLAZE_TLSDTPREL32 26
+#define R_MICROBLAZE_TLSDTPREL64 27
+#define R_MICROBLAZE_TLSGOTTPREL32 28
+#define R_MICROBLAZE_TLSTPREL32 29
+
+#define R_TYPE( name ) R_MICROBLAZE_##name
+
+#endif /* _MICROBLAZE_ELF_MACHDEP_H_ */
diff --git a/spec/build/cpukit/cpumicroblaze.yml b/spec/build/cpukit/cpumicroblaze.yml
index adbfb40759..4a4b2e75cc 100644
--- a/spec/build/cpukit/cpumicroblaze.yml
+++ b/spec/build/cpukit/cpumicroblaze.yml
@@ -9,6 +9,9 @@ enabled-by:
 - microblaze
 includes: []
 install:
+- destination: ${BSP_INCLUDEDIR}/machine
+  source:
+  - cpukit/score/cpu/microblaze/include/machine/elf_machdep.h
 - destination: ${BSP_INCLUDEDIR}/rtems
   source:
   - cpukit/score/cpu/microblaze/include/rtems/asm.h
diff --git a/spec/build/cpukit/objdl.yml b/spec/build/cpukit/objdl.yml
index f6dc9478a6..ae96f21ff0 100644
--- a/spec/build/cpukit/objdl.yml
+++ b/spec/build/cpukit/objdl.yml
@@ -36,6 +36,8 @@ links:
   uid: objdli386
 - role: build-dependency
   uid: objdlm68k
+- role: build-dependency
+  uid: objdlmicroblaze 
 - role: build-dependency
   uid: objdlmips
 - role: build-dependency
diff --git a/spec/build/cpukit/objdlmicroblaze.yml b/spec/build/cpukit/objdlmicroblaze.yml
new file mode 100644
index 0000000000..6740d75cf1
--- /dev/null
+++ b/spec/build/cpukit/objdlmicroblaze.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: objects
+cflags: []
+copyrights:
+- Copyright (C) 2023 On-Line Applications Research (OAR)
+cppflags: []
+cxxflags: []
+enabled-by:
+- microblaze
+includes: []
+install: []
+links: []
+source:
+- cpukit/libdl/rtl-mdreloc-microblaze.c
+type: build
diff --git a/spec/build/cpukit/optlibdl.yml b/spec/build/cpukit/optlibdl.yml
index 74458daba1..cb45d0e70c 100644
--- a/spec/build/cpukit/optlibdl.yml
+++ b/spec/build/cpukit/optlibdl.yml
@@ -12,6 +12,7 @@ enabled-by:
 - arm
 - i386
 - m68k
+- microblaze
 - mips
 - moxie
 - powerpc
-- 
2.34.1



More information about the devel mailing list