microblaze: Add libdl support

This commit is contained in:
Alex White
2023-08-25 16:04:04 -05:00
committed by Joel Sherrill
parent ceb136c7b6
commit feee169aa7
7 changed files with 402 additions and 1 deletions

View File

@@ -0,0 +1,297 @@
/* 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;
}
uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
{
(void) obj;
return sizeof(uint32_t);
}
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);
}

View File

@@ -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

View File

@@ -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_ */

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -12,6 +12,7 @@ enabled-by:
- arm
- i386
- m68k
- microblaze
- mips
- moxie
- powerpc