cpukit: Add libdl with the Runtime Loader (RTL) code.

This is a merge of the RTL project.
This commit is contained in:
Chris Johns
2014-10-31 11:04:15 +11:00
parent 513668f6f1
commit ae5fe7e6bc
91 changed files with 14746 additions and 5 deletions
+19 -1
View File
@@ -11,6 +11,7 @@ SUBDIRS += libi2c
SUBDIRS += libmisc
SUBDIRS += libmd
SUBDIRS += libgnat
SUBDIRS += libdl
SUBDIRS += wrapup
SUBDIRS += zlib
@@ -41,7 +42,6 @@ include_uuid_HEADERS = libmisc/uuid/uuid.h
include_utf8procdir = $(includedir)/utf8proc
include_utf8proc_HEADERS = libmisc/utf8proc/utf8proc.h
if NEWLIB
include_sysdir = $(includedir)/sys
include_sys_HEADERS =
@@ -69,6 +69,24 @@ include_rtems_bsdnetdir = $(includedir)/rtems/bsdnet
include_rtems_bsdnet_HEADERS = libnetworking/rtems/bsdnet/servers.h
include_rtems_bsdnet_HEADERS += libnetworking/rtems/bsdnet/_types.h
endif
if LIBDL
include_HEADERS += libdl/dlfcn.h
include_HEADERS += libdl/include/link.h
include_HEADERS += libdl/include/link_elf.h
include_sys_HEADERS += libdl/include/sys/cdefs_elf.h
include_sys_HEADERS += libdl/include/sys/exec_elf.h
include_arch_machinedir = $(includedir)/machine
include_arch_machine_HEADERS =
include_arch_machine_HEADERS += libdl/include/arch/@RTEMS_CPU@/machine/elf_machdep.h
include_rtems_rtldir = $(includedir)/rtems/rtl
include_rtems_rtl_HEADERS =
include_rtems_rtl_HEADERS += libdl/dlfcn-shell.h
include_rtems_rtl_HEADERS += libdl/rtl.h libdl/rtl-allocator.h libdl/rtl-obj-fwd.h
include_rtems_rtl_HEADERS += libdl/rtl-fwd.h libdl/rtl-obj.h libdl/rtl-obj-cache.h
include_rtems_rtl_HEADERS += libdl/rtl-obj-comp.h libdl/rtl-unresolved.h
include_rtems_rtl_HEADERS += libdl/rtl-indirect-ptr.h libdl/rtl-sym.h
include_rtems_rtl_HEADERS += libdl/rap.h libdl/rap-shell.h
endif
include_rtems_HEADERS += include/rtems/bspIo.h
+16 -2
View File
@@ -298,7 +298,7 @@ AC_ENABLE_MULTILIB([Makefile],[..])
AC_MSG_CHECKING([for assignable stdio])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <stdio.h>],
[#include <stdio.h>],
[stdin = fopen("/tmp", "r")])],
[HAVE_ASSIGNABLE_STDIO=yes],
[HAVE_ASSIGNABLE_STDIO=no])
@@ -322,7 +322,7 @@ AC_CHECK_SIZEOF([time_t])
AC_CHECK_SIZEOF([size_t])
# FIXME: Mandatory in SUSv4, optional in SUSv3.
# FIXME: Mandatory in SUSv4, optional in SUSv3.
# Not implemented in GCC/newlib, so far.
AC_CHECK_DECLS([WORD_BIT],,,[#include <limits.h>])
AC_CHECK_DECLS([LONG_BIT],,,[#include <limits.h>])
@@ -372,6 +372,19 @@ AM_CONDITIONAL([RPCTOOLS],[test "$RPCGEN" = rpcgen \
&& test -n "$AWK" \
&& test "$enable_rpcgen" = yes])
# Filter dynamic loading to only build for architectures that have
# reloc backends
AC_MSG_CHECKING([whether CPU supports libdl])
case $RTEMS_CPU in
arm | bfin | h8300 | i386 | lm32 | m32r | m68k | mips | \
moxie | nios2 | powerpc | sparc | v850)
HAVE_LIBDL=yes ;;
*)
HAVE_LIBDL=no ;;
esac
AM_CONDITIONAL(LIBDL,[test x"$HAVE_LIBDL" = x"yes"])
AC_MSG_RESULT([$HAVE_LIBDL])
RTEMS_AMPOLISH3
# Explicitly list all Makefiles here
@@ -412,6 +425,7 @@ librpc/Makefile
libmisc/Makefile
libi2c/Makefile
libmd/Makefile
libdl/Makefile
zlib/Makefile
ftpd/Makefile
telnetd/Makefile
+36
View File
@@ -0,0 +1,36 @@
if LIBDL
include $(top_srcdir)/automake/compile.am
noinst_LIBRARIES = libdl.a
libdl_a_SOURCES = \
dlfcn-shell.c \
dlfcn.c \
fastlz.c \
rap-shell.c \
rap.c \
rtl.c \
rtl-alloc-heap.c \
rtl-allocator.c \
rtl-chain-iterator.c \
rtl-debugger.c \
rtl-elf.c \
rtl-error.c \
rtl-find-file.c \
rtl-obj-cache.c \
rtl-obj-comp.c \
rtl-obj.c \
rtl-rap.c \
rtl-shell.c \
rtl-string.c \
rtl-sym.c \
rtl-trace.c \
rtl-unresolved.c
libdl_a_SOURCES += rtl-mdreloc-@RTEMS_CPU@.c
libdl_a_CPPFLAGS = $(AM_CPPFLAGS) -DRTEMS_RTL_RAP_LOADER=1 -DRTEMS_RTL_ELF_LOADER=1
include $(srcdir)/preinstall.am
include $(top_srcdir)/automake/local.am
endif
+117
View File
@@ -0,0 +1,117 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtld
*
* @brief RTEMS Run-Time Link Editor Dynamic Loading API Shell Support.
*
* Shell command wrappers for the Dynamic Loading API.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <rtems/rtl/dlfcn-shell.h>
static void*
convert_ascii_to_voidp (const char* arg)
{
if (strcmp (arg, "base") == 0)
return RTLD_DEFAULT;
return (void*) strtoul (arg, NULL, 16);
}
int
shell_dlopen (int argc, char* argv[])
{
int arg;
for (arg = 1; arg < argc; arg++)
{
void* handle = dlopen (argv[arg], RTLD_NOW | RTLD_GLOBAL);
if (handle)
{
int unresolved;
char* message = "loaded";
if (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) < 0)
message = "dlinfo error checking unresolved status";
else if (unresolved)
message = "has unresolved externals";
printf ("handle: %p %s\n", handle, message);
}
else
printf ("error: %s\n", dlerror ());
}
return 0;
}
int
shell_dlclose (int argc, char* argv[])
{
return 0;
}
static bool
lookup_dlsym (void** value, int argc, char* argv[])
{
if (argc >= 3)
{
void* handle = convert_ascii_to_voidp (argv[1]);
if (handle)
{
*value = dlsym (handle, argv[2]);
if (*value)
return true;
else
printf ("error: invalid handle or symbol\n");
}
else
printf ("error: invalid handle");
}
else
printf ("error: requires handle and symbol name\n");
return false;
}
int
shell_dlsym (int argc, char* argv[])
{
void* value;
if (lookup_dlsym (&value, argc, argv))
{
printf ("%s = %p\n", argv[2], value);
return 0;
}
return -1;
}
typedef int (*call_t)(int argc, char* argv[]);
int
shell_dlcall (int argc, char* argv[])
{
void* value;
if (lookup_dlsym (&value, argc, argv))
{
call_t call = value;
int r;
printf ("(*%p)(%d, ....)\n", value, argc - 3);
r = call (argc - 3, argv + 3);
printf ("return %d\n", r);
return 0;
}
return -1;
}
+17
View File
@@ -0,0 +1,17 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#if !defined(_DLFCN_SHELL_H_)
#define _DLFCN_SHELL_H_
int shell_dlopen (int argc, char* argv[]);
int shell_dlclose (int argc, char* argv[]);
int shell_dlsym (int argc, char* argv[]);
int shell_dlcall (int argc, char* argv[]);
#endif
+153
View File
@@ -0,0 +1,153 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtl
*
* @brief RTEMS POSIX Dynamic Module Loading Interface.
*
* This is the POSIX interface to run-time loading of code into RTEMS.
*/
#include <stdint.h>
#include <dlfcn.h>
#include <rtems/rtl/rtl.h>
static rtems_rtl_obj_t*
dl_get_obj_from_handle (void* handle)
{
rtems_rtl_obj_t* obj;
/*
* Handle the special cases provided in NetBSD and Sun documentation.
* http://download.oracle.com/docs/cd/E19253-01/816-5168/dlsym-3c/index.html
* We currently do not manage the loading dependences in the module mappings
* so we cannot handle the searching based on loading order where overriding
* can occur.
*/
if ((handle == RTLD_DEFAULT) || (handle == RTLD_SELF))
obj = rtems_rtl_baseimage ();
else
obj = rtems_rtl_check_handle (handle);
return obj;
}
void*
dlopen (const char* name, int mode)
{
rtems_rtl_obj_t* obj = NULL;
if (!rtems_rtl_lock ())
return NULL;
_rtld_debug.r_state = RT_ADD;
_rtld_debug_state ();
if (name)
obj = rtems_rtl_load_object (name, mode);
else
obj = rtems_rtl_baseimage ();
_rtld_debug.r_state = RT_CONSISTENT;
_rtld_debug_state();
rtems_rtl_unlock ();
return obj;
}
int
dlclose (void* handle)
{
rtems_rtl_obj_t* obj;
int r;
if (!rtems_rtl_lock ())
return -1;
obj = rtems_rtl_check_handle (handle);
if (!obj)
{
rtems_rtl_unlock ();
return -1;
}
_rtld_debug.r_state = RT_DELETE;
_rtld_debug_state ();
r = rtems_rtl_unload_object (obj) ? 0 : -1;
_rtld_debug.r_state = RT_CONSISTENT;
_rtld_debug_state ();
rtems_rtl_unlock ();
return r;
}
void*
dlsym (void* handle, const char *symbol)
{
rtems_rtl_obj_t* obj;
rtems_rtl_obj_sym_t* sym;
void* symval = NULL;
if (!rtems_rtl_lock ())
return NULL;
obj = dl_get_obj_from_handle (handle);
if (obj)
{
sym = rtems_rtl_symbol_obj_find (obj, symbol);
if (sym)
symval = sym->value;
}
rtems_rtl_unlock ();
return symval;
}
const char*
dlerror (void)
{
static char msg[64];
rtems_rtl_get_error (msg, sizeof (msg));
return msg;
}
int
dlinfo (void* handle, int request, void* p)
{
rtems_rtl_obj_t* obj;
int rc = -1;
if (!rtems_rtl_lock () || !p)
return -1;
obj = dl_get_obj_from_handle (handle);
if (obj)
{
switch (request)
{
case RTLD_DI_UNRESOLVED:
*((int*) p) = rtems_rtl_obj_unresolved (obj) ? 1 : 0;
rc = 0;
break;
default:
break;
}
}
rtems_rtl_unlock ();
return rc;
}
+112
View File
@@ -0,0 +1,112 @@
/* $NetBSD: dlfcn.h,v 1.21 2010/01/07 07:35:35 skrll Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Paul Kranenburg.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 _DLFCN_H_
#define _DLFCN_H_
//#include <sys/featuretest.h>
#include <sys/cdefs.h>
#if defined(_NETBSD_SOURCE)
typedef struct _dl_info {
const char *dli_fname; /* File defining the symbol */
void *dli_fbase; /* Base address */
const char *dli_sname; /* Symbol name */
const void *dli_saddr; /* Symbol address */
} Dl_info;
#endif /* defined(_NETBSD_SOURCE) */
/*
* User interface to the run-time linker.
*/
__BEGIN_DECLS
void *dlopen(const char *, int);
int dlclose(void *);
void *dlsym(void * __restrict, const char * __restrict);
#if defined(_NETBSD_SOURCE)
int dladdr(void * __restrict, Dl_info * __restrict);
int dlctl(void *, int, void *);
#endif
int dlinfo(void *, int, void *);
const char *dlerror(void);
__END_DECLS
/* Values for dlopen `mode'. */
#define RTLD_LAZY 1
#define RTLD_NOW 2
#define RTLD_GLOBAL 0x100 /* Allow global searches in object */
#define RTLD_LOCAL 0x200
#if defined(_NETBSD_SOURCE)
#define DL_LAZY RTLD_LAZY /* Compat */
#endif
/*
* Special handle arguments for dlsym().
*/
#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
#define RTLD_SELF ((void *) -3) /* Search the caller itself. */
/*
* dlctl() commands
*/
#if defined(_NETBSD_SOURCE)
#define DL_GETERRNO 1
#define DL_GETSYMBOL 2
#if 0
#define DL_SETSRCHPATH x
#define DL_GETLIST x
#define DL_GETREFCNT x
#define DL_GETLOADADDR x
#endif /* 0 */
#endif /* defined(_NETBSD_SOURCE) */
/*
* dlinfo() commands
*
* From Solaris: http://docs.sun.com/app/docs/doc/816-5168/dlinfo-3c?a=view
*/
#define RTLD_DI_UNRESOLVED 10
#if defined(_NETBSD_SOURCE)
#define RTLD_DI_LINKMAP 3
#if 0
#define RTLD_DI_ARGSINFO 1
#define RTLD_DI_CONFIGADDR 2
#define RTLD_DI_LMID 4
#define RTLD_DI_SERINFO 5
#define RTLD_DI_SERINFOSIZE 6
#define RTLD_DI_ORIGIN 7
#define RTLD_DI_GETSIGNAL 8
#define RTLD_DI_SETSIGNAL 9
#endif
#endif /* _NETBSD_SOURCE */
#endif /* !defined(_DLFCN_H_) */
File diff suppressed because it is too large Load Diff
+100
View File
@@ -0,0 +1,100 @@
/*
FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef FASTLZ_H
#define FASTLZ_H
#define FASTLZ_VERSION 0x000100
#define FASTLZ_VERSION_MAJOR 0
#define FASTLZ_VERSION_MINOR 0
#define FASTLZ_VERSION_REVISION 0
#define FASTLZ_VERSION_STRING "0.1.0"
#if defined (__cplusplus)
extern "C" {
#endif
/**
Compress a block of data in the input buffer and returns the size of
compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16.
The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than
length (input buffer size).
The input buffer and the output buffer can not overlap.
*/
int fastlz_compress(const void* input, int length, void* output);
/**
Decompress a block of compressed data and returns the size of the
decompressed block. If error occurs, e.g. the compressed data is
corrupted or the output buffer is not large enough, then 0 (zero)
will be returned instead.
The input buffer and the output buffer can not overlap.
Decompression is memory safe and guaranteed not to write the output buffer
more than what is specified in maxout.
*/
int fastlz_decompress(const void* input, int length, void* output, int maxout);
/**
Compress a block of data in the input buffer and returns the size of
compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16.
The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than
length (input buffer size).
The input buffer and the output buffer can not overlap.
Compression level can be specified in parameter level. At the moment,
only level 1 and level 2 are supported.
Level 1 is the fastest compression and generally useful for short data.
Level 2 is slightly slower but it gives better compression ratio.
Note that the compressed data, regardless of the level, can always be
decompressed using the function fastlz_decompress above.
*/
int fastlz_compress_level(int level, const void* input, int length, void* output);
#if defined (__cplusplus)
}
#endif
#endif /* FASTLZ_H */
@@ -0,0 +1,131 @@
/* $NetBSD: elf_machdep.h,v 1.8 2009/05/30 05:56:52 skrll Exp $ */
#if defined(__ARMEB__)
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#else
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
#endif
#define ELF64_MACHDEP_ENDIANNESS XXX /* break compilation */
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
/* Processor specific flags for the ELF header e_flags field. */
#define EF_ARM_RELEXEC 0x00000001
#define EF_ARM_HASENTRY 0x00000002
#define EF_ARM_INTERWORK 0x00000004 /* GNU binutils 000413 */
#define EF_ARM_SYMSARESORTED 0x00000004 /* ARM ELF A08 */
#define EF_ARM_APCS_26 0x00000008 /* GNU binutils 000413 */
#define EF_ARM_DYNSYMSUSESEGIDX 0x00000008 /* ARM ELF B01 */
#define EF_ARM_APCS_FLOAT 0x00000010 /* GNU binutils 000413 */
#define EF_ARM_MAPSYMSFIRST 0x00000010 /* ARM ELF B01 */
#define EF_ARM_PIC 0x00000020
#define EF_ARM_ALIGN8 0x00000040 /* 8-bit structure alignment. */
#define EF_ARM_NEW_ABI 0x00000080
#define EF_ARM_OLD_ABI 0x00000100
#define EF_ARM_SOFT_FLOAT 0x00000200
#define EF_ARM_EABIMASK 0xff000000
#define ELF32_MACHDEP_ID_CASES \
case EM_ARM: \
break;
#define ELF32_MACHDEP_ID EM_ARM
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* Processor specific relocation types */
#define R_ARM_NONE 0
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
#define R_ARM_REL32 3
#define R_ARM_PC13 4
#define R_ARM_ABS16 5
#define R_ARM_ABS12 6
#define R_ARM_THM_ABS5 7
#define R_ARM_ABS8 8
#define R_ARM_SBREL32 9
#define R_ARM_THM_CALL 10
#define R_ARM_THM_PC8 11
#define R_ARM_AMP_VCALL9 12
#define R_ARM_SWI24 13
#define R_ARM_THM_SWI8 14
#define R_ARM_XPC25 15
#define R_ARM_THM_XPC22 16
/* TLS relocations */
#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
/* 20-31 are reserved for ARM Linux. */
#define R_ARM_COPY 20
#define R_ARM_GLOB_DAT 21
#define R_ARM_JUMP_SLOT 22
#define R_ARM_RELATIVE 23
#define R_ARM_GOTOFF 24
#define R_ARM_GOTPC 25
#define R_ARM_GOT32 26
#define R_ARM_PLT32 27
#define R_ARM_CALL 28
#define R_ARM_JUMP24 29
#define R_ARM_THM_JUMP24 30
#define R_ARM_BASE_ABS 31
#define R_ARM_ALU_PCREL_7_0 32
#define R_ARM_ALU_PCREL_15_8 33
#define R_ARM_ALU_PCREL_23_15 34
#define R_ARM_ALU_SBREL_11_0 35
#define R_ARM_ALU_SBREL_19_12 36
#define R_ARM_ALU_SBREL_27_20 37
#define R_ARM_V4BX 40
#define R_ARM_PREL31 41
#define R_ARM_MOVW_ABS_NC 43
#define R_ARM_MOVT_ABS 44
#define R_ARM_THM_MOVW_ABS_NC 47
#define R_ARM_THM_MOVT_ABS 48
#define R_ARM_THM_JUMP19 51
/* 96-111 are reserved to G++. */
#define R_ARM_GNU_VTENTRY 100
#define R_ARM_GNU_VTINHERIT 101
#define R_ARM_THM_JUMP11 102
#define R_ARM_THM_JUMP8 103
/* More TLS relocations */
#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic */
#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic */
#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS */
#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of */
#define R_ARM_TLS_LE32 108
#define R_ARM_TLS_LDO12 109
#define R_ARM_TLS_LE12 110
#define R_ARM_TLS_IE12GP 111
/* 112-127 are reserved for private experiments. */
#define R_ARM_RXPC25 249
#define R_ARM_RSBREL32 250
#define R_ARM_THM_RPC22 251
#define R_ARM_RREL32 252
#define R_ARM_RABS32 253
#define R_ARM_RPC24 254
#define R_ARM_RBASE 255
#define R_TYPE(name) __CONCAT(R_ARM_,name)
/* Processor specific program header flags */
#define PF_ARM_SB 0x10000000
#define PF_ARM_PI 0x20000000
#define PF_ARM_ENTRY 0x80000000
/* Processor specific section header flags */
#define SHF_ENTRYSECT 0x10000000
#define SHF_COMDEF 0x80000000
/* Processor specific symbol types */
#define STT_ARM_TFUNC STT_LOPROC
@@ -0,0 +1,28 @@
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
#define ELF32_MACHDEP_ID_CASES \
case EM_BLACKFIN: \
break;
#define ELF32_MACHDEP_ID EM_BLACKFIN
#define ARCH_ELFSIZE 32
#define R_BFIN_UNUSED0 0
#define R_BFIN_RIMM16 5
#define R_BFIN_LUIMM16 6
#define R_BFIN_HUIMM16 7
#define R_BFIN_PCREL12_JUMP_S 8
#define R_BFIN_PCREL24_JUMP_X 9
#define R_BFIN_PCREL24 10
#define R_BFIN_PCREL24_JU 13
#define R_BFIN_PCREL24_CALL_X 14
#define R_BFIN_BYTE_DATA 16
#define R_BFIN_BYTE2_DATA 17
#define R_BFIN_BYTE4_DATA 18
#define R_TYPE(name) __CONCAT(R_BFIN_,name)
@@ -0,0 +1,59 @@
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF32_MACHDEP_ID_CASES \
case EM_H8_300: \
case EM_H8_300H: \
case EM_H8S: \
case EM_H8_500: \
break;
#define ELF32_MACHDEP_ID EM_H8_300
#define ARCH_ELFSIZE 32
#define R_H8_NONE 0
#define R_H8_DIR32 1
#define R_H8_DIR32_28 2
#define R_H8_DIR32_24 3
#define R_H8_DIR32_16 4
#define R_H8_DIR32U 6
#define R_H8_DIR32U_28 7
#define R_H8_DIR32U_24 8
#define R_H8_DIR32U_20 9
#define R_H8_DIR32U_16 10
#define R_H8_DIR24 11
#define R_H8_DIR24_20 12
#define R_H8_DIR24_16 13
#define R_H8_DIR24U 14
#define R_H8_DIR24U_20 15
#define R_H8_DIR24U_16 16
#define R_H8_DIR16 17
#define R_H8_DIR16U 18
#define R_H8_DIR16S_32 19
#define R_H8_DIR16S_28 20
#define R_H8_DIR16S_24 21
#define R_H8_DIR16S_20 22
#define R_H8_DIR16S 23
#define R_H8_DIR8 24
#define R_H8_DIR8U 25
#define R_H8_DIR8Z_32 26
#define R_H8_DIR8Z_28 27
#define R_H8_DIR8Z_24 28
#define R_H8_DIR8Z_20 29
#define R_H8_DIR8Z_16 30
#define R_H8_PCREL16 31
#define R_H8_PCREL8 32
#define R_H8_BPOS 33
#define R_H8_PCREL32 34
#define R_H8_GOT32O 35
#define R_H8_GOT16O 36
#define R_H8_DIR16A8 59
#define R_H8_DIR16R8 60
#define R_H8_DIR24A8 61
#define R_H8_DIR24R8 62
#define R_H8_DIR32A16 63
#define R_H8_ABS32 65
#define R_H8_ABS32A16 127
#define R_TYPE(name) __CONCAT(R_H8_,name)
@@ -0,0 +1,63 @@
/* $NetBSD: elf_machdep.h,v 1.10 2009/05/30 05:56:52 skrll Exp $ */
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
#define ELF32_MACHDEP_ID_CASES \
case EM_386: \
case EM_486: \
break;
#define ELF64_MACHDEP_ENDIANNESS XXX /* break compilation */
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
#define ELF32_MACHDEP_ID EM_386
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* i386 relocations */
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
#define R_386_GOT32 3
#define R_386_PLT32 4
#define R_386_COPY 5
#define R_386_GLOB_DAT 6
#define R_386_JMP_SLOT 7
#define R_386_RELATIVE 8
#define R_386_GOTOFF 9
#define R_386_GOTPC 10
/* TLS relocations */
#define R_386_TLS_TPOFF 14
#define R_386_TLS_IE 15
#define R_386_TLS_GOTIE 16
#define R_386_TLS_LE 17
#define R_386_TLS_GD 18
#define R_386_TLS_LDM 19
/* The following relocations are GNU extensions. */
#define R_386_16 20
#define R_386_PC16 21
#define R_386_8 22
#define R_386_PC8 23
/* More TLS relocations */
#define R_386_TLS_GD_32 24
#define R_386_TLS_GD_PUSH 25
#define R_386_TLS_GD_CALL 26
#define R_386_TLS_GD_POP 27
#define R_386_TLS_LDM_32 28
#define R_386_TLS_LDM_PUSH 29
#define R_386_TLS_LDM_CALL 30
#define R_386_TLS_LDM_POP 31
#define R_386_TLS_LDO_32 32
#define R_386_TLS_IE_32 33
#define R_386_TLS_LE_32 34
#define R_386_TLS_DTPMOD32 35
#define R_386_TLS_DTPOFF32 36
#define R_386_TLS_TPOFF32 37
#define R_386_TLS_GOTDESC 39
#define R_386_TLS_DESC_CALL 40
#define R_386_TLS_DESC 41
#define R_TYPE(name) __CONCAT(R_386_,name)
@@ -0,0 +1,34 @@
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF32_MACHDEP_ID_CASES \
case EM_LATTICEMICO32: \
break;
#define ELF32_MACHDEP_ID EM_LATTICEMICO32
#define EF_MACH32_MACH 0x00000001
//#define EF_BLACKFIN
#define ARCH_ELFSIZE 32
#define R_LM32_NONE 0
#define R_LM32_8 1
#define R_LM32_16 2
#define R_LM32_32 3
#define R_LM32_HI16 4
#define R_LM32_LO16 5
#define R_LM32_GPREL16 6
#define R_LM32_CALL 7
#define R_LM32_BRANCH 8
#define R_LM32_GNU_VTINHERIT 9
#define R_LM32_GNU_VTENTRY 10
#define R_LM32_16_GOT 11
#define R_LM32_GOTOFF_HI16 12
#define R_LM32_GOTOFF_LO16 13
#define R_LM32_COPY 14
#define R_LM32_GLOT_DAT 15
#define R_LM32_JMP_SLOT 16
#define R_LM32_RELATIVE 17
#define R_TYPE(name) __CONCAT(R_LM32_,name)
@@ -0,0 +1,39 @@
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF32_MACHDEP_ID_CASES \
case EM_M32R: \
break;
#define ELF32_MACHDEP_ID EM_M32R
#define ARCH_ELFSIZE 32
#define R_M32R_NONE 0
/*-----------OLD TYPE-------------*/
#define R_M32R_16 1
#define R_M32R_32 2
#define R_M32R_24 3
#define R_M32R_10_PCREL 4
#define R_M32R_18_PCREL 5
#define R_M32R_26_PCREL 6
#define R_M32R_HI16_ULO 7
#define R_M32R_HI16_SLO 8
#define R_M32R_LO16 9
#define R_M32R_SDA16 10
#define R_M32R_GNU_VTINHERIT 11
#define R_M32R_GNU_VTENTRY 12
/*--------------------------------*/
#define R_M32R_16_RELA 33
#define R_M32R_32_RELA 34
#define R_M32R_24_RELA 35
#define R_M32R_18_PCREL_RELA 37
#define R_M32R_26_PCREL_RELA 38
#define R_M32R_HI16_ULO_RELA 39
#define R_M32R_HI16_SLO_RELA 40
#define R_M32R_LO16_RELA 41
#define R_M32R_SDA16_RELA 42
#define R_M32R_RELA_GNU_VTINHERIT 43
#define R_M32R_RELA_GNU_VTENTRY 44
#define R_TYPE(name) __CONCAT(R_M32R_,name)
@@ -0,0 +1,47 @@
/* $NetBSD: elf_machdep.h,v 1.7 2002/01/28 21:34:48 thorpej Exp $ */
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF32_MACHDEP_ID_CASES \
case EM_68K: \
break;
#define ELF64_MACHDEP_ENDIANNESS XXX /* break compilation */
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
#define ELF32_MACHDEP_ID EM_68K
/*
* Machine-dependent ELF flags. These are defined by the GNU tools.
*/
#define EF_CPU32 0x00810000
#define EF_M68000 0x01000000
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* m68k relocation types */
#define R_68K_NONE 0
#define R_68K_32 1
#define R_68K_16 2
#define R_68K_8 3
#define R_68K_PC32 4
#define R_68K_PC16 5
#define R_68K_PC8 6
#define R_68K_GOT32 7
#define R_68K_GOT16 8
#define R_68K_GOT8 9
#define R_68K_GOT32O 10
#define R_68K_GOT16O 11
#define R_68K_GOT8O 12
#define R_68K_PLT32 13
#define R_68K_PLT16 14
#define R_68K_PLT8 15
#define R_68K_PLT32O 16
#define R_68K_PLT16O 17
#define R_68K_PLT8O 18
#define R_68K_COPY 19
#define R_68K_GLOB_DAT 20
#define R_68K_JMP_SLOT 21
#define R_68K_RELATIVE 22
#define R_TYPE(name) __CONCAT(R_68K_,name)
@@ -0,0 +1,196 @@
/* $NetBSD: elf_machdep.h,v 1.15 2011/03/15 07:39:22 matt Exp $ */
#ifndef _MIPS_ELF_MACHDEP_H_
#define _MIPS_ELF_MACHDEP_H_
#ifdef _LP64
#define ARCH_ELFSIZE 64 /* MD native binary size */
#else
#define ARCH_ELFSIZE 32 /* MD native binary size */
#endif
#if ELFSIZE == 32
#define ELF32_MACHDEP_ID_CASES \
case EM_MIPS: \
break;
#define ELF32_MACHDEP_ID EM_MIPS
#elif ELFSIZE == 64
#define ELF64_MACHDEP_ID_CASES \
case EM_MIPS: \
break;
#define ELF64_MACHDEP_ID EM_MIPS
#endif
/* mips relocs. */
#define R_MIPS_NONE 0
#define R_MIPS_16 1
#define R_MIPS_32 2
#define R_MIPS_REL32 3
#define R_MIPS_REL R_MIPS_REL32
#define R_MIPS_26 4
#define R_MIPS_HI16 5 /* high 16 bits of symbol value */
#define R_MIPS_LO16 6 /* low 16 bits of symbol value */
#define R_MIPS_GPREL16 7 /* GP-relative reference */
#define R_MIPS_LITERAL 8 /* Reference to literal section */
#define R_MIPS_GOT16 9 /* Reference to global offset table */
#define R_MIPS_GOT R_MIPS_GOT16
#define R_MIPS_PC16 10 /* 16 bit PC relative reference */
#define R_MIPS_CALL16 11 /* 16 bit call thru glbl offset tbl */
#define R_MIPS_CALL R_MIPS_CALL16
#define R_MIPS_GPREL32 12
/* 13, 14, 15 are not defined at this point. */
#define R_MIPS_UNUSED1 13
#define R_MIPS_UNUSED2 14
#define R_MIPS_UNUSED3 15
/*
* The remaining relocs are apparently part of the 64-bit Irix ELF ABI.
*/
#define R_MIPS_SHIFT5 16
#define R_MIPS_SHIFT6 17
#define R_MIPS_64 18
#define R_MIPS_GOT_DISP 19
#define R_MIPS_GOT_PAGE 20
#define R_MIPS_GOT_OFST 21
#define R_MIPS_GOT_HI16 22
#define R_MIPS_GOT_LO16 23
#define R_MIPS_SUB 24
#define R_MIPS_INSERT_A 25
#define R_MIPS_INSERT_B 26
#define R_MIPS_DELETE 27
#define R_MIPS_HIGHER 28
#define R_MIPS_HIGHEST 29
#define R_MIPS_CALL_HI16 30
#define R_MIPS_CALL_LO16 31
#define R_MIPS_SCN_DISP 32
#define R_MIPS_REL16 33
#define R_MIPS_ADD_IMMEDIATE 34
#define R_MIPS_PJUMP 35
#define R_MIPS_RELGOT 36
#define R_MIPS_JALR 37
/* TLS relocations */
#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */
#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */
#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */
#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */
#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */
#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */
#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */
#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */
#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */
#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */
#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
#define R_MIPS_max 51
#define R_TYPE(name) __CONCAT(R_MIPS_,name)
#define R_MIPS16_min 100
#define R_MIPS16_26 100
#define R_MIPS16_GPREL 101
#define R_MIPS16_GOT16 102
#define R_MIPS16_CALL16 103
#define R_MIPS16_HI16 104
#define R_MIPS16_LO16 105
#define R_MIPS16_max 106
/* mips dynamic tags */
#define DT_MIPS_RLD_VERSION 0x70000001
#define DT_MIPS_TIME_STAMP 0x70000002
#define DT_MIPS_ICHECKSUM 0x70000003
#define DT_MIPS_IVERSION 0x70000004
#define DT_MIPS_FLAGS 0x70000005
#define DT_MIPS_BASE_ADDRESS 0x70000006
#define DT_MIPS_CONFLICT 0x70000008
#define DT_MIPS_LIBLIST 0x70000009
#define DT_MIPS_CONFLICTNO 0x7000000b
#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* number of local got ents */
#define DT_MIPS_LIBLISTNO 0x70000010
#define DT_MIPS_SYMTABNO 0x70000011 /* number of .dynsym entries */
#define DT_MIPS_UNREFEXTNO 0x70000012
#define DT_MIPS_GOTSYM 0x70000013 /* first dynamic sym in got */
#define DT_MIPS_HIPAGENO 0x70000014
#define DT_MIPS_RLD_MAP 0x70000016 /* address of loader map */
/*
* ELF Flags
*/
#define EF_MIPS_PIC 0x00000002 /* Contains PIC code */
#define EF_MIPS_CPIC 0x00000004 /* STD PIC calling sequence */
#define EF_MIPS_ABI2 0x00000020 /* N32 */
#define EF_MIPS_ARCH_ASE 0x0f000000 /* Architectural extensions */
#define EF_MIPS_ARCH_MDMX 0x08000000 /* MDMX multimedia extension */
#define EF_MIPS_ARCH_M16 0x04000000 /* MIPS-16 ISA extensions */
#define EF_MIPS_ARCH 0xf0000000 /* Architecture field */
#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code */
#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code */
#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code */
#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code */
#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code */
#define EF_MIPS_ARCH_32 0x50000000 /* -mips32 code */
#define EF_MIPS_ARCH_64 0x60000000 /* -mips64 code */
#define EF_MIPS_ARCH_32R2 0x70000000 /* -mips32r2 code */
#define EF_MIPS_ARCH_64R2 0x80000000 /* -mips64r2 code */
#define EF_MIPS_ABI 0x0000f000
#define EF_MIPS_ABI_O32 0x00001000
#define EF_MIPS_ABI_O64 0x00002000
#define EF_MIPS_ABI_EABI32 0x00003000
#define EF_MIPS_ABI_EABI64 0x00004000
#if defined(__MIPSEB__)
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF64_MACHDEP_ENDIANNESS ELFDATA2MSB
#elif defined(__MIPSEL__)
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
#define ELF64_MACHDEP_ENDIANNESS ELFDATA2LSB
#elif !defined(HAVE_NBTOOL_CONFIG_H)
#error neither __MIPSEL__ nor __MIPSEB__ are defined.
#endif
#ifdef _KERNEL
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
#endif
#ifdef COMPAT_16
/*
* Up to 1.6, the ELF dynamic loader (ld.elf_so) was not relocatable.
* Tell the kernel ELF exec code not to try relocating the interpreter
* for dynamically-linked ELF binaries.
*/
#define ELF_INTERP_NON_RELOCATABLE
#endif /* COMPAT_16 */
/*
* We need to be able to include the ELF header so we can pick out the
* ABI being used.
*/
#ifdef ELFSIZE
#define ELF_MD_PROBE_FUNC ELFNAME2(mips_netbsd,probe)
#define ELF_MD_COREDUMP_SETUP ELFNAME2(coredump,setup)
#endif
struct exec_package;
int mips_netbsd_elf32_probe(struct lwp *, struct exec_package *, void *, char *,
vaddr_t *);
void coredump_elf32_setup(struct lwp *, void *);
int mips_netbsd_elf64_probe(struct lwp *, struct exec_package *, void *, char *,
vaddr_t *);
void coredump_elf64_setup(struct lwp *, void *);
#endif /* _KERNEL */
#endif /* _MIPS_ELF_MACHDEP_H_ */
@@ -0,0 +1,15 @@
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF32_MACHDEP_ID_CASES \
case EM_MOXIE: \
break;
#define ELF32_MACHDEP_ID EM_MOXIE
#define ARCH_ELFSIZE 32
#define R_MOXIE_NONE 0
#define R_MOXIE_32 1
#define R_MOXIE_PCREL10 2
#define R_TYPE(name) __CONCAT(R_MOXIE_,name)
@@ -0,0 +1,46 @@
/* $NetBSD: elf_machdep.h,v 1.7 2002/01/28 21:34:48 thorpej Exp $ */
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF32_MACHDEP_ID_CASES \
case EM_ALTERA_NIOS2: \
break;
#define ELF64_MACHDEP_ENDIANNESS XXX /* break compilation */
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
#define ELF32_MACHDEP_ID EM_ALTERA_NIOS2
/*
* Machine-dependent ELF flags. These are defined by the GNU tools.
*/
#define EF_NIOS2 0x00810000
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* NIOS2 relocation types */
#define R_NIOS2_NONE 0
#define R_NIOS2_32 1
#define R_NIOS2_16 2
#define R_NIOS2_8 3
#define R_NIOS2_PC32 4
#define R_NIOS2_PC16 5
#define R_NIOS2_PC8 6
#define R_NIOS2_GOT32 7
#define R_NIOS2_GOT16 8
#define R_NIOS2_GOT8 9
#define R_NIOS2_GOT32O 10
#define R_NIOS2_GOT16O 11
#define R_NIOS2_GOT8O 12
#define R_NIOS2_PLT32 13
#define R_NIOS2_PLT16 14
#define R_NIOS2_PLT8 15
#define R_NIOS2_PLT32O 16
#define R_NIOS2_PLT16O 17
#define R_NIOS2_PLT8O 18
#define R_NIOS2_COPY 19
#define R_NIOS2_GLOB_DAT 20
#define R_NIOS2_JMP_SLOT 21
#define R_NIOS2_RELATIVE 22
#define R_TYPE(name) __CONCAT(R_NIOS2_,name)
@@ -0,0 +1,105 @@
/* $NetBSD: elf_machdep.h,v 1.9 2011/01/15 10:00:07 matt Exp $ */
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF32_MACHDEP_ID_CASES \
case EM_PPC: \
break;
#define ELF64_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF64_MACHDEP_ID_CASES \
case EM_PPC64: \
break;
#define ELF32_MACHDEP_ID EM_PPC
#define ELF64_MACHDEP_ID EM_PPC64
#ifdef _LP64
#define ARCH_ELFSIZE 64 /* MD native binary size */
#else
#define ARCH_ELFSIZE 32 /* MD native binary size */
#endif
/* Specify the value of _GLOBAL_OFFSET_TABLE_ */
#define DT_PPC_GOT DT_LOPROC
#define R_PPC_NONE 0
#define R_PPC_32 1
#define R_PPC_24 2
#define R_PPC_16 3
#define R_PPC_16_LO 4
#define R_PPC_16_HI 5 /* R_PPC_ADDIS */
#define R_PPC_16_HA 6
#define R_PPC_14 7
#define R_PPC_14_TAKEN 8
#define R_PPC_14_NTAKEN 9
#define R_PPC_REL24 10 /* R_PPC_BRANCH */
#define R_PPC_REL14 11
#define R_PPC_REL14_TAKEN 12
#define R_PPC_REL14_NTAKEN 13
#define R_PPC_GOT16 14
#define R_PPC_GOT16_LO 15
#define R_PPC_GOT16_HI 16
#define R_PPC_GOT16_HA 17
#define R_PPC_PLT24 18
#define R_PPC_COPY 19
#define R_PPC_GLOB_DAT 20
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
#define R_PPC_LOCAL24PC 23
#define R_PPC_U32 24
#define R_PPC_U16 25
#define R_PPC_REL32 26
#define R_PPC_PLT32 27
#define R_PPC_PLTREL32 28
#define R_PPC_PLT16_LO 29
#define R_PPC_PLT16_HI 30
#define R_PPC_PLT16_HA 31
#define R_PPC_SDAREL16 32
#define R_PPC_SECTOFF 33
#define R_PPC_SECTOFF_LO 34
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
#define R_PPC_ADDR30 37
/* TLS relocations */
#define R_PPC_TLS 67
#define R_PPC_DTPMOD32 68
#define R_PPC_TPREL16 69
#define R_PPC_TPREL16_LO 70
#define R_PPC_TPREL16_HI 71
#define R_PPC_TPREL16_HA 72
#define R_PPC_TPREL32 73
#define R_PPC_DTPREL16 74
#define R_PPC_DTPREL16_LO 75
#define R_PPC_DTPREL16_HI 76
#define R_PPC_DTPREL16_HA 77
#define R_PPC_DTPREL32 78
#define R_PPC_GOT_TLSGD16 79
#define R_PPC_GOT_TLSGD16_LO 80
#define R_PPC_GOT_TLSGD16_HI 81
#define R_PPC_GOT_TLSGD16_HA 82
#define R_PPC_GOT_TLSLD16 83
#define R_PPC_GOT_TLSLD16_LO 84
#define R_PPC_GOT_TLSLD16_HI 85
#define R_PPC_GOT_TLSLD16_HA 86
#define R_PPC_GOT_TPREL16 87
#define R_PPC_GOT_TPREL16_LO 88
#define R_PPC_GOT_TPREL16_HI 89
#define R_PPC_GOT_TPREL16_HA 90
#define R_PPC_GOT_DTPREL16 91
#define R_PPC_GOT_DTPREL16_LO 92
#define R_PPC_GOT_DTPREL16_HI 93
#define R_PPC_GOT_DTPREL16_HA 94
#define R_PPC_TLSGD 95
#define R_PPC_TLSLD 96
/* Used for the secure-plt PIC code sequences */
#define R_PPC_REL16 249
#define R_PPC_REL16_LO 250
#define R_PPC_REL16_HI 251
#define R_PPC_REL16_HA 252
#define R_TYPE(name) __CONCAT(R_PPC_,name)
@@ -0,0 +1,92 @@
/* $NetBSD: elf_machdep.h,v 1.7 2009/05/30 05:56:53 skrll Exp $ */
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF32_MACHDEP_ID_CASES \
case EM_SPARC: \
case EM_SPARC32PLUS: \
break;
#define ELF64_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF64_MACHDEP_ID_CASES \
case EM_SPARC32PLUS: \
case EM_SPARCV9: \
/* no 64-bit ELF machine types supported */
#define ELF32_MACHDEP_ID EM_SPARC /* XXX right? */
#define ARCH_ELFSIZE 32 /* MD native binary size */
#define R_SPARC_NONE 0
#define R_SPARC_8 1
#define R_SPARC_16 2
#define R_SPARC_32 3
#define R_SPARC_DISP8 4
#define R_SPARC_DISP16 5
#define R_SPARC_DISP32 6
#define R_SPARC_WDISP30 7
#define R_SPARC_WDISP22 8
#define R_SPARC_HI22 9
#define R_SPARC_22 10
#define R_SPARC_13 11
#define R_SPARC_LO10 12
#define R_SPARC_GOT10 13
#define R_SPARC_GOT13 14
#define R_SPARC_GOT22 15
#define R_SPARC_PC10 16
#define R_SPARC_PC22 17
#define R_SPARC_WPLT30 18
#define R_SPARC_COPY 19
#define R_SPARC_GLOB_DAT 20
#define R_SPARC_JMP_SLOT 21
#define R_SPARC_RELATIVE 22
#define R_SPARC_UA32 23
#define R_SPARC_PLT32 24
#define R_SPARC_HIPLT22 25
#define R_SPARC_LOPLT10 26
#define R_SPARC_PCPLT32 27
#define R_SPARC_PCPLT22 28
#define R_SPARC_PCPLT10 29
#define R_SPARC_10 30
#define R_SPARC_11 31
#define R_SPARC_64 32
#define R_SPARC_OLO10 33
#define R_SPARC_HH22 34
#define R_SPARC_HM10 35
#define R_SPARC_LM22 36
#define R_SPARC_PC_HH22 37
#define R_SPARC_PC_HM10 38
#define R_SPARC_PC_LM22 39
#define R_SPARC_WDISP16 40
#define R_SPARC_WDISP19 41
#define R_SPARC_GLOB_JMP 42
#define R_SPARC_7 43
#define R_SPARC_5 44
#define R_SPARC_6 45
/* TLS relocations */
#define R_SPARC_TLS_GD_HI22 56
#define R_SPARC_TLS_GD_LO10 57
#define R_SPARC_TLS_GD_ADD 58
#define R_SPARC_TLS_GD_CALL 59
#define R_SPARC_TLS_LDM_HI22 60
#define R_SPARC_TLS_LDM_LO10 61
#define R_SPARC_TLS_LDM_ADD 62
#define R_SPARC_TLS_LDM_CALL 63
#define R_SPARC_TLS_LDO_HIX22 64
#define R_SPARC_TLS_LDO_LOX10 65
#define R_SPARC_TLS_LDO_ADD 66
#define R_SPARC_TLS_IE_HI22 67
#define R_SPARC_TLS_IE_LO10 68
#define R_SPARC_TLS_IE_LD 69
#define R_SPARC_TLS_IE_LDX 70
#define R_SPARC_TLS_IE_ADD 71
#define R_SPARC_TLS_LE_HIX22 72
#define R_SPARC_TLS_LE_LOX10 73
#define R_SPARC_TLS_DTPMOD32 74
#define R_SPARC_TLS_DTPMOD64 75
#define R_SPARC_TLS_DTPOFF32 76
#define R_SPARC_TLS_DTPOFF64 77
#define R_SPARC_TLS_TPOFF32 78
#define R_SPARC_TLS_TPOFF64 79
#define R_TYPE(name) __CONCAT(R_SPARC_,name)
@@ -0,0 +1,74 @@
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
#define ELF32_MACHDEP_ID_CASES \
case EM_V850: \
break;
#define ELF32_MACHDEP_ID EM_V850
#define EF_V850_ARCH 0xf0000000
#define E_V850_ARCH 0x00000000
#define E_V850E_ARCH 0x10000000
#define E_V850E1_ARCH 0x20000000
#define E_V850E2_ARCH 0x30000000
#define E_V850E2V3_ARCH 0x40000000
#define ARCH_ELFSIZE 32
#define R_V850_NONE 0
#define R_V850_9_PCREL 1
#define R_V850_22_PCREL 2
#define R_V850_HI16_S 3
#define R_V850_HI16 4
#define R_V850_LO16 5
#define R_V850_ABS32 6
#define R_V850_16 7
#define R_V850_8 8
#define R_V850_SDA_16_16_OFFSET 9
#define R_V850_SDA_15_16_OFFSET 10
#define R_V850_ZDA_16_16_OFFSET 11
#define R_V850_ZDA_15_16_OFFSET 12
#define R_V850_TDA_6_8_OFFSET 13
#define R_V850_TDA_7_8_OFFSET 14
#define R_V850_TDA_7_7_OFFSET 15
#define R_V850_TDA_16_16_OFFSET 16
#define R_V850_TDA_4_5_OFFSET 17
#define R_V850_TDA_4_4_OFFSET 18
#define R_V850_SDA_16_16_SPLIT_OFFSET 19
#define R_V850_ZDA_16_16_SPLIT_OFFSET 20
#define R_V850_CALLT_6_7_OFFSET 21
#define R_V850_CALLT_16_16_OFFSET 22
#define R_V850_GNU_VTINHERIT 23
#define R_V850_GNU_VTENTRY 24
#define R_V850_LONGCALL 25
#define R_V850_LONGJUMP 26
#define R_V850_ALIGN 27
#define R_V850_REL32 28
#define R_V850_LO16_SPLIT_OFFSET 29
#define R_V850_16_PCREL 30
#define R_V850_17_PCREL 31
#define R_V850_23 32
#define R_V850_32_PCREL 33
#define R_V850_32_ABS 34
#define R_V850_16_SPLIT_OFFSET 35
#define R_V850_16_S1 36
#define R_V850_LO16_S1 37
#define R_V850_CALLT_15_16_OFFSET 38
#define R_V850_32_GOTPCREL 39
#define R_V850_16_GOT 40
#define R_V850_32_GOT 41
#define R_V850_22_PLT 42
#define R_V850_32_PLT 43
#define R_V850_COPY 44
#define R_V850_GLOB_DAT 45
#define R_V850_JMP_SLOT 46
#define R_V850_RELATIVE 47
#define R_V850_16_GOTOFF 48
#define R_V850_32_GOTOFF 49
#define R_V850_CODE 50
#define R_V850_DATA 51
#define R_TYPE(name) __CONCAT(R_V850_,name)
+45
View File
@@ -0,0 +1,45 @@
/* $NetBSD: link.h,v 1.13 2008/04/28 20:22:54 martin Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 _LINK_H_
#define _LINK_H_
/*
* Pull in the correct definitions for our toolchain target.
*/
#ifdef __ELF__
#include <link_elf.h>
#else
#include <link_aout.h>
#endif
#endif /* _LINK_H_ */
+79
View File
@@ -0,0 +1,79 @@
/* $NetBSD: link_elf.h,v 1.8 2009/11/04 19:28:03 pooka Exp $ */
/*
* This only exists for GDB.
*/
#ifndef _LINK_ELF_H_
#define _LINK_ELF_H_
#include <sys/types.h>
#include <machine/elf_machdep.h>
#include <stdint.h>
#include <rtems/rtl/rtl-obj-fwd.h>
enum sections
{
rap_text = 0,
rap_const = 1,
rap_ctor = 2,
rap_dtor = 3,
rap_data = 4,
rap_bss = 5,
rap_secs = 6
};
/**
* Object details.
*/
typedef struct
{
const char* name; /**< Section name. */
uint32_t offset; /**< The offset in the elf file. */
uint32_t size; /**< The size of the section. */
uint32_t rap_id; /**< Which obj does this section belongs to. */
}section_detail;
/**
* link map structure will be used for GDB support.
*/
struct link_map {
const char* name; /**< Name of the obj. */
uint32_t sec_num; /**< The count of section. */
section_detail* sec_detail; /**< The section details. */
uint32_t* sec_addr[rap_secs]; /**< The RAP section addr. */
uint32_t rpathlen; /**< The length of the path. */
char* rpath; /**< The path of object files. */
struct link_map* l_next; /**< Linked list of mapped libs. */
struct link_map* l_prev;
};
/**
* r_debug is used to manage the debug related structures.
*/
struct r_debug {
int r_version; /* not used */
struct link_map *r_map; /* list of loaded images */
enum {
RT_CONSISTENT, /* things are stable */
RT_ADD, /* adding a shared library */
RT_DELETE /* removing a shared library */
} r_state;
};
/*
* stub function. It is empty.
*/
void _rtld_debug_state (void);
/*
* add link map to the list.
*/
int _rtld_linkmap_add (rtems_rtl_obj_t* obj);
/*
* Remove link map from the list.
*/
void _rtld_linkmap_delete (rtems_rtl_obj_t* obj);
#endif /* _LINK_ELF_H_ */
+152
View File
@@ -0,0 +1,152 @@
/* $NetBSD: cdefs_elf.h,v 1.24 2005/07/16 17:53:36 christos Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
#ifndef _SYS_CDEFS_ELF_H_
#define _SYS_CDEFS_ELF_H_
#ifdef __LEADING_UNDERSCORE
#define _C_LABEL(x) __CONCAT(_,x)
#define _C_LABEL_STRING(x) "_"x
#else
#define _C_LABEL(x) x
#define _C_LABEL_STRING(x) x
#endif
#if __STDC__
#define ___RENAME(x) __asm__(___STRING(_C_LABEL(x)))
#else
#ifdef __LEADING_UNDERSCORE
#define ___RENAME(x) ____RENAME(_/**/x)
#define ____RENAME(x) __asm__(___STRING(x))
#else
#define ___RENAME(x) __asm__(___STRING(x))
#endif
#endif
#define __indr_reference(sym,alias) /* nada, since we do weak refs */
#if __STDC__
#define __strong_alias(alias,sym) \
__asm__(".global " _C_LABEL_STRING(#alias) "\n" \
_C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
#define __weak_alias(alias,sym) \
__asm__(".weak " _C_LABEL_STRING(#alias) "\n" \
_C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
#define __weak_extern(sym) \
__asm__(".weak " _C_LABEL_STRING(#sym));
#define __warn_references(sym,msg) \
__asm__(".section .gnu.warning." #sym "\n\t.ascii \"" msg "\"\n\t.text");
#else /* !__STDC__ */
#ifdef __LEADING_UNDERSCORE
#define __weak_alias(alias,sym) ___weak_alias(_/**/alias,_/**/sym)
#define ___weak_alias(alias,sym) \
__asm__(".weak alias\nalias = sym");
#else
#define __weak_alias(alias,sym) \
__asm__(".weak alias\nalias = sym");
#endif
#ifdef __LEADING_UNDERSCORE
#define __weak_extern(sym) ___weak_extern(_/**/sym)
#define ___weak_extern(sym) \
__asm__(".weak sym");
#else
#define __weak_extern(sym) \
__asm__(".weak sym");
#endif
#define __warn_references(sym,msg) \
__asm__(".section .gnu.warning.sym\n\t.ascii msg ; .text");
#endif /* !__STDC__ */
#if __STDC__
#define __SECTIONSTRING(_sec, _str) \
__asm__(".section " #_sec "\n\t.asciz \"" _str "\"\n\t.previous")
#else
#define __SECTIONSTRING(_sec, _str) \
__asm__(".section _sec\n\t.asciz _str\n\t.previous")
#endif
#define __IDSTRING(_n,_s) __SECTIONSTRING(.ident,_s)
#define __RCSID(_s) __IDSTRING(rcsid,_s)
#define __SCCSID(_s)
#define __SCCSID2(_s)
#if 0 /* XXX userland __COPYRIGHTs have \ns in them */
#define __COPYRIGHT(_s) __SECTIONSTRING(.copyright,_s)
#else
#define __COPYRIGHT(_s) \
static const char copyright[] \
__attribute__((__unused__,__section__(".copyright"))) = _s
#endif
#define __KERNEL_RCSID(_n, _s) __RCSID(_s)
#define __KERNEL_SCCSID(_n, _s)
#if 0 /* XXX see above */
#define __KERNEL_COPYRIGHT(_n, _s) __COPYRIGHT(_s)
#else
#define __KERNEL_COPYRIGHT(_n, _s) __SECTIONSTRING(.copyright, _s)
#endif
#ifndef __lint__
#define __link_set_make_entry(set, sym) \
static void const * const __link_set_##set##_sym_##sym \
__section("link_set_" #set) __used = &sym
#define __link_set_make_entry2(set, sym, n) \
static void const * const __link_set_##set##_sym_##sym##_##n \
__section("link_set_" #set) __used = &sym[n]
#else
#define __link_set_make_entry(set, sym) \
extern void const * const __link_set_##set##_sym_##sym
#define __link_set_make_entry2(set, sym, n) \
extern void const * const __link_set_##set##_sym_##sym##_##n
#endif /* __lint__ */
#define __link_set_add_text(set, sym) __link_set_make_entry(set, sym)
#define __link_set_add_rodata(set, sym) __link_set_make_entry(set, sym)
#define __link_set_add_data(set, sym) __link_set_make_entry(set, sym)
#define __link_set_add_bss(set, sym) __link_set_make_entry(set, sym)
#define __link_set_add_text2(set, sym, n) __link_set_make_entry2(set, sym, n)
#define __link_set_add_rodata2(set, sym, n) __link_set_make_entry2(set, sym, n)
#define __link_set_add_data2(set, sym, n) __link_set_make_entry2(set, sym, n)
#define __link_set_add_bss2(set, sym, n) __link_set_make_entry2(set, sym, n)
#define __link_set_decl(set, ptype) \
extern ptype * const __start_link_set_##set[]; \
extern ptype * const __stop_link_set_##set[] \
#define __link_set_start(set) (__start_link_set_##set)
#define __link_set_end(set) (__stop_link_set_##set)
#define __link_set_count(set) \
(__link_set_end(set) - __link_set_start(set))
#endif /* !_SYS_CDEFS_ELF_H_ */
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
## Automatically generated by ampolish3 - Do not edit
if AMPOLISH3
$(srcdir)/preinstall.am: Makefile.am
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
endif
+106
View File
@@ -0,0 +1,106 @@
/*
* COPYRIGHT (c) 2013 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtld
*
* @brief RTEMS Application Loader.
*
* Shell command wrappers for the RTEMS Application loader.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtems/rtl/rap.h>
#include <rtems/rtl/rap-shell.h>
static void
shell_rap_command_help (void)
{
printf ("usage: rap [cmd] [arg]\n" \
"Commands and options:\n" \
"ls: List the loaded applications (also list)\n" \
"ld: Load an application (also load)\n" \
"un: Unload an application (also unload)\n");
}
static void
shell_rap_get_error (const char* what)
{
char message[64];
int error;
error = rtems_rap_get_error (message, sizeof (message));
printf ("error: %s: (%d) %s\n", what, error, message);
}
static bool
shell_rap_list_handler (void* handle)
{
printf (" %-10p %-10p %-s\n",
handle, rtems_rap_dl_handle (handle), rtems_rap_name (handle));
return true;
}
static int
shell_rap_list (int argc, char* argv[])
{
printf (" App DL Handle Name\n");
return rtems_rap_iterate (shell_rap_list_handler) ? 0 : 1;
}
static int
shell_rap_load (int argc, char* argv[])
{
int r = 0;
if (argc == 0)
{
printf ("error: no application name\n");
return 0;
}
if (rtems_rap_load (argv[0], 0, argc - 1, (const char**) (argv + 1)))
printf ("%s loaded\n", argv[0]);
else
{
r = 1;
shell_rap_get_error ("loading");
}
return r;
}
int
shell_rap (int argc, char* argv[])
{
if (argc == 1)
{
shell_rap_command_help ();
return 0;
}
if ((strcmp (argv[1], "ls") == 0) ||
(strcmp (argv[1], "list") == 0))
{
return shell_rap_list (argc - 2, argv + 2);
}
else if ((strcmp (argv[1], "ld") == 0) ||
(strcmp (argv[1], "load") == 0))
{
return shell_rap_load (argc - 2, argv + 2);
}
printf ("error: invalid command: %s\n", argv[1]);
return 0;
}
+14
View File
@@ -0,0 +1,14 @@
/*
* COPYRIGHT (c) 2013 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#if !defined(_RAP_SHELL_H_)
#define _RAP_SHELL_H_
int shell_rap (int argc, char* argv[]);
#endif
+484
View File
@@ -0,0 +1,484 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rap
*
* @brief RTEMS Application Loader
*
* This is the RAP implementation.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <rtems/libio_.h>
#include <dlfcn.h>
#include <rtems/rtl/rap.h>
#include <rtems/rtl/rtl.h>
#include "rtl-find-file.h"
/**
* The global RAP data. This structure is allocated on the heap when the first
* call to location an application and is never released.
*/
typedef struct rtems_rap_data_s
{
rtems_id lock; /**< The RAP lock id */
rtems_chain_control apps; /**< List if loaded application. */
int last_errno; /**< Last error number. */
char last_error[64]; /**< Last error string. */
} rtems_rap_data_t;
/**
* The RAP file data. This structure is allocated on the heap when a file is
* loaded.
*/
typedef struct rtems_rap_app_s
{
rtems_chain_node node; /**< The node's link in the chain. */
const char* name; /**< The file name */
void* handle; /**< The dlopen handle. */
} rtems_rap_app_t;
/**
* Semaphore configuration to create a mutex.
*/
#define RTEMS_MUTEX_ATTRIBS \
(RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | \
RTEMS_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL)
/**
* RTL entry.
*/
#if (RTL_GLUE(__USER_LABEL_PREFIX__, 1) == RTL_GLUE(_, 1))
#define RTL_ENTRY_POINT "_rtems"
#else
#define RTL_ENTRY_POINT "rtems"
#endif
/**
* Static RAP data is returned to the user when the loader is locked.
*/
static rtems_rap_data_t rap_;
/**
* Verbose level for the RAP loader.
*/
static bool rap_verbose;
/**
* RAP entry call signature.
*/
typedef int (*rtems_rap_entry_t)(int argc, const char* argv[]);
/**
* Forward decl.
*/
static bool rtems_rap_unlock (void);
static bool
rtems_rap_data_init (void)
{
/*
* Lock the RAP. We only create a lock if a call is made. First we test if a
* lock is present. If one is present we lock it. If not the libio lock is
* locked and we then test the lock again. If not present we create the lock
* then release libio lock.
*/
if (!rap_.lock)
{
rtems_libio_lock ();
if (!rap_.lock)
{
rtems_status_code sc;
rtems_id lock;
/*
* Create the RAP lock.
*/
sc = rtems_semaphore_create (rtems_build_name ('R', 'A', 'P', '_'),
1, RTEMS_MUTEX_ATTRIBS,
RTEMS_NO_PRIORITY, &lock);
if (sc != RTEMS_SUCCESSFUL)
return false;
sc = rtems_semaphore_obtain (lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
{
rtems_semaphore_delete (lock);
return false;
}
rap_.lock = lock;
/*
* Initialise the objects list and create any required services.
*/
rtems_chain_initialize_empty (&rap_.apps);
}
rtems_libio_unlock ();
rtems_rap_unlock ();
}
return true;
}
static rtems_rap_data_t*
rtems_rap_lock (void)
{
rtems_status_code sc;
if (!rtems_rap_data_init ())
return NULL;
sc = rtems_semaphore_obtain (rap_.lock,
RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
{
errno = EINVAL;
return NULL;
}
return &rap_;
}
static bool
rtems_rap_unlock (void)
{
/*
* Not sure any error should be returned or an assert.
*/
rtems_status_code sc;
sc = rtems_semaphore_release (rap_.lock);
if ((sc != RTEMS_SUCCESSFUL) && (errno == 0))
{
errno = EINVAL;
return false;
}
return true;
}
static rtems_rap_app_t*
rtems_rap_check_handle (void* handle)
{
rtems_rap_app_t* app;
rtems_chain_node* node;
app = handle;
node = rtems_chain_first (&rap_.apps);
while (!rtems_chain_is_tail (&rap_.apps, node))
{
rtems_rap_app_t* check = (rtems_rap_app_t*) node;
if (check == app)
return app;
node = rtems_chain_next (node);
}
return NULL;
}
static rtems_rap_app_t*
rtems_rap_app_alloc (void)
{
rtems_rap_app_t* app = malloc (sizeof (rtems_rap_app_t));
memset (app, 0, sizeof (rtems_rap_app_t));
rtems_chain_append (&rap_.apps, &app->node);
return app;
}
static void
rtems_rap_app_free (rtems_rap_app_t* app)
{
if (app->handle)
{
dlclose (app->handle);
app->handle = NULL;
}
if (!rtems_chain_is_node_off_chain (&app->node))
rtems_chain_extract (&app->node);
}
static bool
rtems_rap_match_name (rtems_rap_app_t* app, const char* name)
{
const char* a;
/*
* Assume the app name is absolute, ie points to the file on disk. This means
* there is at least one delimiter in the name.
*/
if (strncmp (app->name, name, strlen (name)) == 0)
return true;
a = app->name + strlen (app->name) - 1;
while (a >= app->name)
{
if (rtems_filesystem_is_delimiter (*a))
{
const char* n = name;
++a;
while (*a && *n)
{
if (*a == '.')
{
if (*n == '\0')
return true;
}
++a;
++n;
}
return false;
}
--a;
}
return false;
}
static void
rtems_rap_get_rtl_error (void)
{
rap_.last_errno =
rtems_rtl_get_error (rap_.last_error, sizeof (rap_.last_error));
}
static void
rtems_rap_set_error (int error, const char* format, ...)
{
rtems_rap_data_t* rap = rtems_rap_lock ();
va_list ap;
va_start (ap, format);
rap->last_errno = error;
vsnprintf (rap->last_error, sizeof (rap->last_error), format, ap);
rtems_rap_unlock ();
va_end (ap);
}
bool
rtems_rap_load (const char* name, int mode, int argc, const char* argv[])
{
rtems_rap_data_t* rap = rtems_rap_lock ();
if (!rap)
return false;
if (rap_verbose)
printf ("rap: loading '%s'\n", name);
/*
* See if the app has already been loaded.
*/
if (!rtems_rap_find (name))
{
rtems_rap_app_t* app;
rtems_rap_entry_t init;
rtems_rap_entry_t fini;
size_t size = 0;
int r;
/*
* Allocate a new application descriptor and attempt to load it.
*/
app = rtems_rap_app_alloc ();
if (app == NULL)
{
rtems_rap_set_error (ENOMEM, "no memory for application");
rtems_rap_unlock ();
return false;
}
/*
* Find the file in the file system using the search path.
*/
if (!rtems_rtl_find_file (name, getenv ("PATH"), &app->name, &size))
{
rtems_rap_set_error (ENOENT, "file not found");
rtems_rap_app_free (app);
rtems_rap_unlock ();
return false;
}
app->handle = dlopen (app->name, RTLD_NOW | mode);
if (!app->handle)
{
rtems_rap_get_rtl_error ();
rtems_rap_app_free (app);
rtems_rap_unlock ();
return false;
}
init = dlsym (app->handle, RTL_ENTRY_POINT);
if (!init)
{
rtems_rap_get_rtl_error ();
rtems_rap_app_free (app);
rtems_rap_unlock ();
return false;
}
fini = dlsym (app->handle, RTL_ENTRY_POINT);
if (!fini)
{
rtems_rap_get_rtl_error ();
rtems_rap_app_free (app);
rtems_rap_unlock ();
return false;
}
r = init (argc, argv);
if (r != 0)
{
rtems_rap_set_error (r, "init call failure");
rtems_rap_app_free (app);
rtems_rap_unlock ();
return false;
}
}
rtems_rap_unlock ();
return true;
}
bool
rtems_rap_unload (const char* name)
{
rtems_rap_app_t* app;
rtems_rap_entry_t fini;
int r;
rtems_rap_lock ();
app = rtems_rap_find (name);
if (rap_verbose)
printf ("rap: unloading '%s'\n", name);
if (!app)
{
rtems_rap_set_error (ENOENT, "invalid handle");
rtems_rap_unlock ();
return false;
}
fini = dlsym (app->handle, RTL_ENTRY_POINT);
if (!fini)
{
rtems_rap_get_rtl_error ();
rtems_rap_unlock ();
return false;
}
r = fini (0, NULL);
if (r != 0)
{
rtems_rap_set_error (r, "fini failure");
rtems_rap_unlock ();
return false;
}
rtems_rap_app_free (app);
rtems_rap_unlock ();
return true;
}
void*
rtems_rap_find (const char* name)
{
rtems_rap_data_t* rap = rtems_rap_lock ();
rtems_chain_node* node;
node = rtems_chain_first (&rap->apps);
while (!rtems_chain_is_tail (&rap->apps, node))
{
rtems_rap_app_t* app = (rtems_rap_app_t*) node;
if (rtems_rap_match_name (app, name))
{
rtems_rap_unlock ();
return app;
}
node = rtems_chain_next (node);
}
rtems_rap_unlock ();
return NULL;
}
bool
rtems_rap_iterate (rtems_rap_iterator_t iterator)
{
rtems_rap_data_t* rap = rtems_rap_lock ();
rtems_chain_node* node;
bool result = true;
node = rtems_chain_first (&rap->apps);
while (!rtems_chain_is_tail (&rap->apps, node))
{
rtems_rap_app_t* app = (rtems_rap_app_t*) node;
result = iterator (app);
if (!result)
break;
node = rtems_chain_next (node);
}
rtems_rap_unlock ();
return result;
}
const char*
rtems_rap_name (void* handle)
{
rtems_rap_app_t* app = rtems_rap_check_handle (handle);
if (app)
return app->name;
return NULL;
}
void*
rtems_rap_dl_handle (void* handle)
{
rtems_rap_app_t* app = rtems_rap_check_handle (handle);
if (app)
return app->handle;
return NULL;
}
int
rtems_rap_get_error (char* message, size_t max_message)
{
rtems_rap_data_t* rap = rtems_rap_lock ();
int last_errno = rap->last_errno;
strncpy (message, rap->last_error, sizeof (rap->last_error));
rtems_rap_unlock ();
return last_errno;
}
+115
View File
@@ -0,0 +1,115 @@
/*
* COPYRIGHT (c) 2013 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rap
*
* @brief RTEMS Application Loader
*
* This is the RTEMS Application loader for files in the RAP format.
*/
#if !defined (_RAP_H_)
#define _RAP_H_
#include <rtems.h>
#include <rtems/chain.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup rtems_rap RTEMS Application Loader
*
* The module implements an application loader for files in the RAP format. The
* RAP format is:
*
* <header>
* <compressed container>
*
* The compressed container is a stream of ELF relocatable object files.
*
* TBD.
*/
/**
* The module iterator handle.
*/
typedef bool (*rtems_rap_iterator_t) (void* handle);
/**
* Load an application.
*
* @param name The name of the application file.
* @return bool True if the module loads else an error.
*/
bool rtems_rap_load (const char* name, int mode, int argc, const char* argv[]);
/**
* Unload an application.
*
* @param obj The application descriptor.
* @retval true The application file has been unloaded.
* @retval false The application could not be unloaded.
*/
bool rtems_rap_unload (const char* name);
/**
* Find the application handle given a file name.
*
* @param name The name of the application file. It can be absolute or
* relative. Relative names can the basename with an extension.
* @retval NULL No application file with that name found.
* @return void* The application descriptor.
*/
void* rtems_rap_find (const char* name);
/**
* Run an iterator over the modules calling the iterator function.
*
* @param iterator The iterator function.
* @retval true The iterator function returned did not return false.
* @retval false The iterator function returned false..
*/
bool rtems_rap_iterate (rtems_rap_iterator_t iterator);
/**
* Return the name of the module given a handle.
*
* @param handle The module handle.
* @return const char* The name of the module if the handle is valid else it
* is NULL.
*/
const char* rtems_rap_name (void* handle);
/**
* Return the DL handle used to load the module given the RAP handle.
*
* @param handle The module handle.
* @return void* The DL handle returned by the dlopen call.
*/
void* rtems_rap_dl_handle (void* handle);
/**
* Get the last error message clearing it. This call is not thread safe is
* multiple threads are loading object files at the same time. This call
* follows the model provided by the dlopen family of calls.
*
* @param message Pointer to a buffer to copy the message into.
* @param max_message The maximum message that can be copied.
* @return int The last error number.
*/
int rtems_rap_get_error (char* message, size_t max_message);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+33
View File
@@ -0,0 +1,33 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Allocator for the standard heap.
*/
#include <stdlib.h>
#include "rtl-alloc-heap.h"
void
rtems_rtl_alloc_heap (bool allocate,
rtems_rtl_alloc_tag_t tag,
void** address,
size_t size)
{
if (allocate)
*address = malloc (size);
else
{
free (*address);
*address = NULL;
}
}
+47
View File
@@ -0,0 +1,47 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Allocator for the standard heap.
*/
#if !defined (_RTEMS_RTL_ALLOC_HEAP_H_)
#define _RTEMS_RTL_ALLOC_HEAP_H_
#include <rtems/rtl/rtl-allocator.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Allocator handler for the standard libc heap.
*
* @param allocation If true the request is to allocate memory else free.
* @param tag The type of allocation request.
* @param address Pointer to the memory address. If an allocation the value is
* unspecific on entry and the allocated address or NULL on
* exit. The NULL value means the allocation failed. If a delete
* or free request the memory address is the block to free. A
* free request of NULL is silently ignored.
* @param size The size of the allocation if an allocation request and
* not used if deleting or freeing a previous allocation.
*/
void rtems_rtl_alloc_heap(bool allocate,
rtems_rtl_alloc_tag_t tag,
void** address,
size_t size);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+210
View File
@@ -0,0 +1,210 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Allocator
*/
#include <stdio.h>
#include <rtems/rtl/rtl.h>
#include "rtl-alloc-heap.h"
#include "rtl-trace.h"
/**
* Tags as symbols for tracing.
*/
#if RTEMS_RTL_TRACE
static const char* tag_labels[6] =
{
"OBJECT",
"SYMBOL",
"EXTERNAL",
"READ",
"READ_WRITE",
"READ_EXEC",
};
#define rtems_rtl_trace_tag_label(_l) tag_labels[_l]
#else
#define rtems_rtl_trace_tag_label(_l) ""
#endif
void
rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data)
{
int c;
data->allocator = rtems_rtl_alloc_heap;
for (c = 0; c < RTEMS_RTL_ALLOC_TAGS; ++c)
rtems_chain_initialize_empty (&data->indirects[c]);
}
void*
rtems_rtl_alloc_new (rtems_rtl_alloc_tag_t tag, size_t size, bool zero)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
void* address = NULL;
if (rtl)
rtl->allocator.allocator (true, tag, &address, size);
rtems_rtl_unlock ();
if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
printf ("rtl: alloc: new: %s addr=%p size=%zu\n",
rtems_rtl_trace_tag_label (tag), address, size);
if (zero)
memset (address, 0, size);
return address;
}
void
rtems_rtl_alloc_del (rtems_rtl_alloc_tag_t tag, void* address)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
printf ("rtl: alloc: del: %s addr=%p\n",
rtems_rtl_trace_tag_label (tag), address);
if (rtl && address)
rtl->allocator.allocator (false, tag, &address, 0);
rtems_rtl_unlock ();
}
rtems_rtl_allocator_t
rtems_rtl_alloc_hook (rtems_rtl_allocator_t handler)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
rtems_rtl_allocator_t previous = rtl->allocator.allocator;
rtl->allocator.allocator = handler;
rtems_rtl_unlock ();
return previous;
}
void
rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag,
rtems_rtl_ptr_t* handle,
size_t size)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
{
if (!rtems_rtl_ptr_null (handle))
printf ("rtl: alloc: inew: %s handle=%p: not null\n",
rtems_rtl_trace_tag_label (tag), handle);
printf ("rtl: alloc: inew: %s handle=%p size=%zd\n",
rtems_rtl_trace_tag_label (tag), handle, size);
}
if (rtl)
{
rtems_rtl_alloc_data_t* allocator = &rtl->allocator;
handle->pointer = rtems_rtl_alloc_new (tag, size, false);
if (!rtems_rtl_ptr_null (handle))
rtems_chain_append_unprotected (&allocator->indirects[tag],
&handle->node);
}
rtems_rtl_unlock ();
}
void
rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
rtems_rtl_ptr_t* handle)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
{
if (rtems_rtl_ptr_null (handle))
printf ("rtl: alloc: idel: %s handle=%p: is null\n",
rtems_rtl_trace_tag_label (tag), handle);
printf ("rtl: alloc: idel: %s handle=%p\n",
rtems_rtl_trace_tag_label (tag), handle);
}
if (rtl && !rtems_rtl_ptr_null (handle))
{
rtems_chain_extract_unprotected (&handle->node);
rtems_rtl_alloc_del (tag, &handle->pointer);
}
}
bool
rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
void** const_base, size_t const_size,
void** data_base, size_t data_size,
void** bss_base, size_t bss_size)
{
*text_base = *const_base = *data_base = *bss_base = NULL;
if (text_size)
{
*text_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_EXEC,
text_size, false);
if (!*text_base)
{
return false;
}
}
if (const_size)
{
*const_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ,
const_size, false);
if (!*const_base)
{
rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
return false;
}
}
if (data_size)
{
*data_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
data_size, false);
if (!*data_base)
{
rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
return false;
}
}
if (bss_size)
{
*bss_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
bss_size, false);
if (!*bss_base)
{
rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
return false;
}
}
return true;
}
void
rtems_rtl_alloc_module_del (void** text_base,
void** const_base,
void** data_base,
void** bss_base)
{
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *bss_base);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *data_base);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *const_base);
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_EXEC, *text_base);
*text_base = *const_base = *data_base = *bss_base = NULL;
}
+176
View File
@@ -0,0 +1,176 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Allocator
*/
#if !defined (_RTEMS_RTL_ALLOCATOR_H_)
#define _RTEMS_RTL_ALLOCATOR_H_
#include <stdbool.h>
#include "rtl-indirect-ptr.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Define the types of allocation the loader requires.
*
* @note It is best to use the object tag for general memory allocation and to
* leave the tags with specific access properties to the module data
*/
enum rtems_rtl_alloc_tags_e {
RTEMS_RTL_ALLOC_OBJECT, /**< A generic memory object. */
RTEMS_RTL_ALLOC_SYMBOL, /**< Memory used for symbols. */
RTEMS_RTL_ALLOC_EXTERNAL, /**< Memory used for external symbols. */
RTEMS_RTL_ALLOC_READ, /**< The memory is read only. */
RTEMS_RTL_ALLOC_READ_WRITE, /**< The memory is read and write. */
RTEMS_RTL_ALLOC_READ_EXEC /**< The memory is read and executable. */
};
/**
* The allocator tag type.
*/
typedef enum rtems_rtl_alloc_tags_e rtems_rtl_alloc_tag_t;
/**
* The number of tags.
*/
#define RTEMS_RTL_ALLOC_TAGS ((size_t) (RTEMS_RTL_ALLOC_READ_EXEC + 1))
/**
* Allocator handler handles all RTL allocations. It can be hooked and
* overridded for customised allocation schemes or memory maps.
*
* @param allocation If true the request is to allocate memory else free.
* @param tag The type of allocation request.
* @param address Pointer to the memory address. If an allocation the value is
* unspecific on entry and the allocated address or NULL on
* exit. The NULL value means the allocation failed. If a delete
* or free request the memory address is the block to free. A
* free request of NULL is silently ignored.
* @param size The size of the allocation if an allocation request and
* not used if deleting or freeing a previous allocation.
*/
typedef void (*rtems_rtl_allocator_t)(bool allocate,
rtems_rtl_alloc_tag_t tag,
void** address,
size_t size);
/**
* The allocator data.
*/
struct rtems_rtl_alloc_data_s {
/**< The memory allocator handler. */
rtems_rtl_allocator_t allocator;
/**< The indirect pointer chains. */
rtems_chain_control indirects[RTEMS_RTL_ALLOC_TAGS];
};
typedef struct rtems_rtl_alloc_data_s rtems_rtl_alloc_data_t;
/**
* Initialise the allocate data.
*
* @param data The data to initialise.
*/
void rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data);
/**
* The Runtime Loader allocator new allocates new memory and optionally clear
* the memory if requested.
*
* @param tag The type of allocation request.
* @param size The size of the allocation.
* @param zero If true the memory is cleared.
* @return void* The memory address or NULL is not memory available.
*/
void* rtems_rtl_alloc_new (rtems_rtl_alloc_tag_t tag, size_t size, bool zero);
/**
* The Runtime Loader allocator delete deletes allocated memory.
*
* @param tag The type of allocation request.
* @param address The memory address to delete. A NULL is ignored.
*/
void rtems_rtl_alloc_del (rtems_rtl_alloc_tag_t tag, void* address);
/**
* Hook the Runtime Loader allocatior. A handler can call the previous handler
* in the chain to use it for specific tags. The default handler uses the
* system heap. Do not unhook your handler if memory it allocates has not been
* returned.
*
* @param handler The handler to use as the allocator.
* @return rtems_rtl_alloc_handler_t The previous handler.
*/
rtems_rtl_allocator_t rtems_rtl_alloc_hook (rtems_rtl_allocator_t handler);
/**
* Allocate memory to an indirect handle.
*
* @param tag The type of allocation request.
* @param handle The handle to allocate the memory to.
* @param size The size of the allocation.
*/
void rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag,
rtems_rtl_ptr_t* handle,
size_t size);
/**
* Free memory from an indirect handle.
*
* @param tag The type of allocation request.
* @param handle The handle to free the memory from.
*/
void rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
rtems_rtl_ptr_t* handle);
/**
* Allocate the memory for a module given the size of the text, const, data and
* bss sections. If any part of the allocation fails the no memory is
* allocated.
*
* @param text_base Pointer to the text base pointer.
* @param text_size The size of the read/exec section.
* @param const_base Pointer to the const base pointer.
* @param const_size The size of the read only section.
* @param data_base Pointer to the data base pointer.
* @prarm data_size The size of the read/write secton.
* @param bss_base Pointer to the bss base pointer.
* @param bss_size The size of the read/write.
* @retval true The memory has been allocated.
* @retval false The allocation of memory has failed.
*/
bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
void** const_base, size_t const_size,
void** data_base, size_t data_size,
void** bss_base, size_t bss_size);
/**
* Free the memory allocated to a module.
*
* @param text_base Pointer to the text base pointer.
* @param const_base Pointer to the const base pointer.
* @param data_base Pointer to the data base pointer.
* @param bss_base Pointer to the bss base pointer.
*/
void rtems_rtl_alloc_module_del (void** text_base, void** const_base,
void** data_base, void** bss_base);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+57
View File
@@ -0,0 +1,57 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtld
*
* @brief RTEMS Run-Time Link Editor Chain Iterator
*
* A means of executing an iterator on a chain.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "rtl-chain-iterator.h"
bool
rtems_rtl_chain_iterate (rtems_chain_control* chain,
rtems_chain_iterator iterator,
void* data)
{
rtems_chain_node* node = rtems_chain_first (chain);
while (!rtems_chain_is_tail (chain, node))
{
rtems_chain_node* next_node = rtems_chain_next (node);
if (!iterator (node, data))
return false;
node = next_node;
}
return true;
}
/**
* Count iterator.
*/
static bool
rtems_rtl_count_iterator (rtems_chain_node* node, void* data)
{
int* count = data;
++(*count);
return true;
}
int
rtems_rtl_chain_count (rtems_chain_control* chain)
{
int count = 0;
rtems_rtl_chain_iterate (chain, rtems_rtl_count_iterator, &count);
return count;
}
+59
View File
@@ -0,0 +1,59 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Chain Iterator.
*/
#if !defined (_RTEMS_RTL_CHAIN_ITERATOR_H_)
#define _RTEMS_RTL_CHAIN_ITERATOR_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <rtems/chain.h>
/**
* Chain iterator handler.
*/
typedef bool (*rtems_chain_iterator) (rtems_chain_node* node, void* data);
/**
* Iterate a chain of nodes invoking the iterator handler. Supply a data
* pointer the iterator moves data between the invoker and the iterator.
*
* The iterator allows removal of the node from the chain.
*
* @param chain The chain of nodes to iterator over.
* @param iterator The iterator handler called once for each node.
* @param data Pointer to the data used by the iterator.
* @retval true The whole chain was iterated over.
* @retval false The iterator returned false.
*/
bool
rtems_rtl_chain_iterate (rtems_chain_control* chain,
rtems_chain_iterator iterator,
void* data);
/**
* Count the number of nodes on the chain.
*
* @param chain The chain to count the nodes of.
* @return int The number of nodes.
*/
int rtems_rtl_chain_count (rtems_chain_control* chain);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+96
View File
@@ -0,0 +1,96 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtl
*
* @brief RTEMS Module Loading Debugger Interface.
*
* Inspection of run-time linkers in NetBSD and Android show a common type of
* structure that is used to interface to GDB. The NetBSD definition of this
* interface is being used and is defined in <link.h>. It defines a protocol
* that is used by GDB to inspect the state of dynamic libraries. I have not
* checked GDB code at when writing this comment but I suspect GDB sets a break
* point on the r_brk field of _rtld_debug and it has code that detects this
* break point being hit. When this happens it reads the state and performs the
* operation based on the r_state field.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <link.h>
#include <rtems/rtl/rtl.h>
#include "rtl-trace.h"
#include "rtl-obj-fwd.h"
struct r_debug _rtld_debug;
void
_rtld_debug_state (void)
{
/*
* Empty. GDB only needs to hit this location.
*/
}
int
_rtld_linkmap_add (rtems_rtl_obj_t* obj)
{
struct link_map* l = (struct link_map*)obj->detail;
struct link_map* prev;
uint32_t obj_num = obj->obj_num;
int i;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
printf ("rtl: linkmap_add\n");
for (i = 0; i < obj_num; ++i)
{
l[i].sec_addr[rap_text] = obj->text_base;
l[i].sec_addr[rap_const] = obj->const_base;
l[i].sec_addr[rap_data] = obj->data_base;
l[i].sec_addr[rap_bss] = obj->bss_base;
}
if (_rtld_debug.r_map == NULL)
{
_rtld_debug.r_map = l;
return true;
}
for (prev = _rtld_debug.r_map; prev->l_next != NULL; prev = prev->l_next);
l->l_prev = prev;
prev->l_next = l;
return true;
}
void
_rtld_linkmap_delete (rtems_rtl_obj_t* obj)
{
struct link_map* l = (struct link_map*)obj->detail;
/* link_maps are allocated together if not 1 */
struct link_map* e = l + obj->obj_num - 1;
while (e && e->l_next) e = e->l_next;
if (l->l_prev == NULL)
{
if ((_rtld_debug.r_map = e->l_next) != NULL)
e->l_next->l_prev = NULL;
return;
}
if ((l->l_prev->l_next = e->l_next) != NULL)
e->l_next->l_prev = l->l_prev;
return;
}
File diff suppressed because it is too large Load Diff
+165
View File
@@ -0,0 +1,165 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker ELF Headers
*/
#if !defined (_RTEMS_RTL_ELF_H_)
#define _RTEMS_RTL_ELF_H_
#include "rtl-fwd.h"
#include "rtl-obj-fwd.h"
#include "rtl-sym.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
** Imported NetBSD ELF Specifics Start.
**/
/*
* Always 32bit for RTEMS at the moment. Do not add '()'. Leave plain.
*/
#define ELFSIZE 32
/*
* Define _STANDALONE then remove after.
*/
#define _STANDALONE 1
#include <sys/cdefs.h>
#include <sys/exec_elf.h>
#undef _STANDALONE
/**
** Imported NetBSD ELF Specifics End.
**/
/**
* Maximum string length. This a read buffering limit rather than a
* specific ELF length. I hope this is ok as I am concerned about
* some C++ symbol lengths.
*/
#define RTEMS_RTL_ELF_STRING_MAX (256)
/**
* Architecture specific handler to check is a relocation record's type is
* required to resolve a symbol.
*
* @param type The type field in the relocation record.
* @retval true The relocation record require symbol resolution.
* @retval false The relocation record does not require symbol resolution.
*/
bool rtems_rtl_elf_rel_resolve_sym (Elf_Word type);
/**
* Architecture specific relocation handler compiled in for a specific
* architecture by the build system. The handler applies the relocation
* to the target.
*
* @param obj The object file being relocated.
* @param rel The ELF relocation record.
* @param sect The section of the object file the relocation is for.
* @param symname The symbol's name.
* @param syminfo The ELF symbol info field.
* @param symvalue If a symbol is referenced, this is the symbols value.
* @retval bool The relocation has been applied.
* @retval bool The relocation could not be applied.
*/
bool rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue);
/**
* Architecture specific relocation handler compiled in for a specific
* architecture by the build system. The handler applies the relocation
* to the target.
*
* @param obj The object file being relocated.
* @param rela The ELF addend relocation record.
* @param sect The section of the object file the relocation is for.
* @param symname The symbol's name.
* @param syminfo The ELF symbol info field.
* @param symvalue If a symbol is referenced, this is the symbols value.
* @retval bool The relocation has been applied.
* @retval bool The relocation could not be applied.
*/
bool rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue);
/**
* Find the symbol. The symbol is passed as an ELF type symbol with the name
* and the value returned is the absolute address of the symbol.
*
* If the symbol type is STT_NOTYPE the symbol references a global symbol. The
* gobal symbol table is searched to find it and that value returned. If the
* symbol is local to the object module the section for the symbol is located
* and it's base added to the symbol's value giving an absolute location.
*
* @param obj The object the symbol is being resolved for.
* @param sym The ELF type symbol.
* @param symname The sym's name read from the symbol string table.
* @param value Return the value of the symbol. Only valid if the return value
* is true.
* @retval true The symbol resolved.
* @retval false The symbol could not be result. The RTL error is set.
*/
bool rtems_rtl_elf_find_symbol (rtems_rtl_obj_t* obj,
const Elf_Sym* sym,
const char* symname,
Elf_Word* value);
/**
* The ELF format check handler.
*
* @param obj The object being checked.
* @param fd The file descriptor.
*/
bool rtems_rtl_elf_file_check (rtems_rtl_obj_t* obj, int fd);
/**
* The ELF file details handler.
*
* @param obj Load the details of the obj.
*/
bool rtems_rtl_elf_load_details (rtems_rtl_obj_t* obj);
/**
* The ELF format load handler.
*
* @param obj The object to load.
* @param fd The file descriptor.
*/
bool rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd);
/**
* The ELF format signature handler.
*
* @return rtems_rtl_loader_format_t* The format's signature.
*/
rtems_rtl_loader_format_t* rtems_rtl_elf_file_sig (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+47
View File
@@ -0,0 +1,47 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtl
*
* @brief RTEMS Run-Time Linker Error
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdarg.h>
#include <rtems/rtl/rtl.h>
#include "rtl-error.h"
void
rtems_rtl_set_error (int error, const char* format, ...)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
va_list ap;
va_start (ap, format);
rtl->last_errno = error;
vsnprintf (rtl->last_error, sizeof (rtl->last_error), format, ap);
rtems_rtl_unlock ();
va_end (ap);
}
int
rtems_rtl_get_error (char* message, size_t max_message)
{
rtems_rtl_data_t* rtl = rtems_rtl_lock ();
int last_errno = rtl->last_errno;
strncpy (message, rtl->last_error, sizeof (rtl->last_error));
rtems_rtl_unlock ();
return last_errno;
}
+44
View File
@@ -0,0 +1,44 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Error
*/
#if !defined (_RTEMS_RTL_ERROR_H_)
#define _RTEMS_RTL_ERROR_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if __GNUC__
#define RTEMS_RTL_PRINTF_ATTR __attribute__((__format__(__printf__,2,3)))
#else
#define RTEMS_RTL_PRINTF_ATTR
#endif
/**
* Sets the error.
*
* Assumes the RTL has been locked.
*
* @param error The errno error number.
* @param format The error format string.
* @param ... The variable arguments that depend on the format string.
*/
void rtems_rtl_set_error (int error, const char* format, ...) RTEMS_RTL_PRINTF_ATTR;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+110
View File
@@ -0,0 +1,110 @@
/*
* COPYRIGHT (c) 2012-2013 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtl
*
* @brief RTEMS Run-Time Linker Error
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <rtems/libio_.h>
#include <rtems/rtl/rtl.h>
#include "rtl-find-file.h"
#include "rtl-error.h"
#include "rtl-string.h"
#include "rtl-trace.h"
#if WAF_BUILD
#define rtems_filesystem_is_delimiter rtems_filesystem_is_separator
#endif
bool
rtems_rtl_find_file (const char* name,
const char* paths,
const char** file_name,
size_t* size)
{
struct stat sb;
*file_name = NULL;
*size = 0;
if (rtems_filesystem_is_delimiter (name[0]) || (name[0] == '.'))
{
if (stat (name, &sb) == 0)
*file_name = rtems_rtl_strdup (name);
}
else if (paths)
{
const char* start;
const char* end;
int len;
char* fname;
start = paths;
end = start + strlen (paths);
len = strlen (name);
while (!*file_name && (start != end))
{
const char* delimiter = strchr (start, ':');
if (delimiter == NULL)
delimiter = end;
/*
* Allocate the path fragment, separator, name, terminating nul. Form the
* path then see if the stat call works.
*/
fname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
(delimiter - start) + 1 + len + 1, true);
if (!fname)
{
rtems_rtl_set_error (ENOMEM, "no memory searching for file");
return false;
}
memcpy (fname, start, delimiter - start);
fname[delimiter - start] = '/';
memcpy (fname + (delimiter - start) + 1, name, len);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
printf ("rtl: find-file: path: %s\n", fname);
if (stat (fname, &sb) < 0)
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, fname);
else
*file_name = fname;
start = delimiter;
if (start != end)
++start;
}
}
if (!*file_name)
return false;
*size = sb.st_size;
return true;
}
+45
View File
@@ -0,0 +1,45 @@
/*
* COPYRIGHT (c) 2012-2013 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Object Support.
*/
#if !defined (_RTEMS_RTL_FIND_FILE_H_)
#define _RTEMS_RTL_FIND_FILE_H_
#include <rtems.h>
#include <rtems/chain.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Find a file on disk given a name and a path.
*
* @param name The file name to find. Can be relative or absolute.
* @param paths The paths to search.
* @param file_name Place the full path in this location if found.
* @param size The size of the file if found as returned by the 'stat' call.
* @retval true The file was found.
* @retval false The file was not found.
*/
bool rtems_rtl_find_file (const char* name,
const char* paths,
const char** file_name,
size_t* size);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+33
View File
@@ -0,0 +1,33 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker ELF Headers
*/
#if !defined (_RTEMS_RTL_FWD_H_)
#define _RTEMS_RTL_FWD_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* The forward declaration of the obj structure.
*/
struct rtems_rtl_data_s;
typedef struct rtems_rtl_data_s rtems_rtl_data_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+235
View File
@@ -0,0 +1,235 @@
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Indirect Pointer Management allows memory
* compaction in the allocator.
*/
#if !defined (_RTEMS_RTL_INDIRECT_PTR_H_)
#define _RTEMS_RTL_INDIRECT_PTR_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <rtems/chain.h>
/**
* The RTL Indirect pointer.
*/
struct rtems_rtl_ptr_s {
rtems_chain_node node; /**< Indirect pointers are held on lists. */
void* pointer; /**< The actual pointer. */
};
typedef struct rtems_rtl_ptr_s rtems_rtl_ptr_t;
/**
* The RTL Indirect size and pointer.
*/
struct rtems_rtl_sptr_s {
rtems_rtl_ptr_t ptr; /**< The indirect pointer. */
size_t size; /**< The size of the memory block. */
};
typedef struct rtems_rtl_sptr_s rtems_rtl_sptr_t;
/**
* A chain of indirect pointers for users to chain in applications.
*
* @note The chain the pointer is on is internal to the allocator and cannot be
* used by applications.
*/
struct rtems_rtl_ptr_chain_s {
rtems_chain_node node; /**< Chain of indirect pointers. */
rtems_rtl_ptr_t ptr; /**< The indirect pointer. */
};
typedef struct rtems_rtl_ptr_chain_s rtems_rtl_ptr_chain_t;
/**
* A chain of indirect sized pointers for users to chain in applications.
*
* @note The chain the pointer is on is internal to the allocator and cannot be
* used by applications.
*/
struct rtems_rtl_sptr_chain_s {
rtems_chain_node node; /**< Chain of indirect pointers. */
rtems_rtl_sptr_t ptr; /**< The indirect pointer. */
};
typedef struct rtems_rtl_sptr_chain_s rtems_rtl_sptr_chain_t;
/**
* Get the pointer given an indirect handle.
*
* @param handle The handle the pointer is returned from.
* @return void* The pointer held in the handle.
*/
static inline void* rtems_rtl_ptr_get (rtems_rtl_ptr_t* handle)
{
return handle->pointer;
}
/**
* Set the pointer given an indirect handle and the pointer.
*
* @param handle The handle the pointer is returned from.
* @param pointer The pointer to set in the handle.
*/
static inline void rtems_rtl_ptr_set (rtems_rtl_ptr_t* handle, void* pointer)
{
handle->pointer = pointer;
}
/**
* Initialise the indirect handle.
*
* @param handle The handle to initialise.
*/
static inline void rtems_rtl_ptr_init (rtems_rtl_ptr_t* handle)
{
rtems_chain_set_off_chain (&handle->node);
handle->pointer = NULL;
}
/**
* Is the indirect handle NULL ?
*
* @param handle The handle to test.
* @return bool True if the pointer is NULL.
*/
static inline bool rtems_rtl_ptr_null (rtems_rtl_ptr_t* handle)
{
return handle->pointer == NULL;
}
/**
* Move the allocated pointer from one handle to another. The source handle is
* cleared and removed from the list of handles.
*
* @param src The source handle to move the pointer from.
* @param dst The destination handle to receive the pointer.
*/
static inline void rtems_rtl_ptr_move (rtems_rtl_ptr_t* dst, rtems_rtl_ptr_t* src)
{
/*
* We do not know which chain the src handle resides on so insert the dst
* handle after the src handle then extract the src handle.
*/
rtems_chain_insert_unprotected (&src->node, &dst->node);
rtems_chain_extract_unprotected (&src->node);
dst->pointer = src->pointer;
rtems_rtl_ptr_init (src);
}
/**
* Return the pointer as the type provided.
*
* @param _h The handle.
* @param _t The type.
*/
#define rtems_rtl_ptr_type_get(_h, _t) ((_t*) rtems_rtl_ptr_get (_h))
/**
* Get the pointer given an indirect handle.
*
* @param handle The handle the pointer is returned from.
* @return void* The pointer held in the handle.
*/
static inline void* rtems_rtl_sptr_get (rtems_rtl_sptr_t* handle)
{
return rtems_rtl_ptr_get (&handle->ptr);
}
/**
* Set the pointer given an indirect handle and the pointer.
*
* @param handle The handle the pointer is returned from.
* @param pointer The pointer to set in the handle.
*/
static inline void rtems_rtl_sptr_set (rtems_rtl_sptr_t* handle, void* pointer)
{
rtems_rtl_ptr_set (&handle->ptr, pointer);
}
/**
* Initialise the indirect handle.
*
* @param handle The handle to initialise.
*/
static inline void rtems_rtl_sptr_init (rtems_rtl_sptr_t* handle)
{
rtems_rtl_ptr_init (&handle->ptr);
handle->size = 0;
}
/**
* Is the indirect handle NULL ?
*
* @param handle The handle to test.
* @return bool True if the pointer is NULL.
*/
static inline bool rtems_rtl_sptr_null (rtems_rtl_sptr_t* handle)
{
return rtems_rtl_ptr_null (&handle->ptr);
}
/**
* Move the allocated pointer from one handle to another. The source handle is
* cleared and removed from the list of handles.
*
* @param src The source handle to move the pointer from.
* @param dst The destination handle to receive the pointer.
*/
static inline void rtems_rtl_sptr_move (rtems_rtl_sptr_t* dst, rtems_rtl_sptr_t* src)
{
rtems_rtl_ptr_move (&dst->ptr, &src->ptr);
dst->size = src->size;
src->size = 0;
}
/**
* Get the size.
*
* @param handle The handle to get the size from.
* @return size_t The size_t.
*/
static inline size_t rtems_rtl_sptr_get_size (rtems_rtl_sptr_t* handle)
{
return handle->size;
}
/**
* Set the size.
*
* @param handle The handle to set the size.
* @param size The size to set..
*/
static inline void rtems_rtl_sptr_set_size (rtems_rtl_sptr_t* handle, size_t size)
{
handle->size = size;
}
/**
* Return the pointer as the type provided.
*
* @param _h The handle.
* @param _t The type.
*/
#define rtems_rtl_sptr_type_get(_h, _t) ((_t*) rtems_rtl_sptr_get (_h))
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+323
View File
@@ -0,0 +1,323 @@
/*
* Taken from NetBSD and stripped of the relocations not needed on RTEMS.
*/
/* $NetBSD: mdreloc.c,v 1.33 2010/01/14 12:12:07 skrll Exp $ */
#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 "rtl-trace.h"
/*
* It is possible for the compiler to emit relocations for unaligned data.
* We handle this situation with these inlines.
*/
#define RELOC_ALIGNED_P(x) \
(((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
static inline Elf_Addr
load_ptr(void *where)
{
Elf_Addr res;
memcpy(&res, where, sizeof(res));
return (res);
}
static inline void
store_ptr(void *where, Elf_Addr val)
{
memcpy(where, &val, sizeof(val));
}
/*
* The address of Thumb function symbols is it's real address plus one.
* This is done by compiler, thus do not consider symtype here.
*/
static inline int
isThumb(Elf_Word symvalue)
{
if ((symvalue & 0x1) == 0x1)
return true;
else return false;
}
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
{
return true;
}
bool
rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
rtems_rtl_set_error (EINVAL, "rela type record not supported");
return false;
}
bool
rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
Elf_Addr *where;
Elf_Addr tmp;
Elf_Word insn, addend;
Elf_Word sign, i1, i2;
uint16_t lower_insn, upper_insn;
where = (Elf_Addr *)(sect->base + rel->r_offset);
switch (ELF_R_TYPE(rel->r_info)) {
case R_TYPE(NONE):
break;
case R_TYPE(CALL): /* BL/BLX */
case R_TYPE(JUMP24): /* B/BL<cond> */
insn = *where;
if (insn & 0x00800000)
addend = insn | 0xff000000;
else addend = insn & 0x00ffffff;
if (isThumb(symvalue)) {
if ((insn & 0xfe000000) == 0xfa000000); /* Already blx */
else {
if ((insn & 0xff000000) == 0xeb000000) { /* BL <label> */
*where = (insn & 0x00ffffff) | 0xfa000000; /* BL-->BLX */
} else {
printf("JUMP24 is not suppored from arm to thumb\n");
return false;
}
}
}
tmp = symvalue + (addend << 2) - (Elf_Addr)where;
tmp = (Elf_Sword)tmp >> 2;
if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
printf("CALL/JUMP24 Overflow\n");
return false;
}
*where = (*where & 0xff000000) | (tmp & 0xffffff);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: JUMP24/PC24/CALL %p @ %p in %s\n",
(void *)*where, where, rtems_rtl_obj_oname (obj));
break;
case R_TYPE(V4BX):
/* Miscellaneous, ignore */
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
printf ("rtl: V4BX %p @ %p in %s\n",
(void *)*where, where, rtems_rtl_obj_oname (obj));
}
break;
case R_TYPE(MOVT_ABS):
case R_TYPE(MOVW_ABS_NC):
insn = *where;
addend = ((insn >> 4) & 0xf000) | (insn & 0x0fff);
if (addend & 0x8000)
addend |= 0xffff0000;
tmp = symvalue + addend;
if (ELF_R_TYPE(rel->r_info) == R_TYPE(MOVW_ABS_NC))
tmp &= 0xffff;
else {
tmp = (Elf_Sword)tmp >> 16;
if (((Elf_Sword)tmp > 0x7fff) || ((Elf_Sword)tmp < -0x8000)) {
printf("MOVT_ABS Overflow\n");
return false;
}
}
*where = (insn & 0xfff0f000) | ((tmp & 0xf000) << 4) | (tmp & 0xfff);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: MOVT_ABS/MOVW_ABS_NC %p @ %p in %s\n",
(void *)*where, where, rtems_rtl_obj_oname (obj));
break;
case R_TYPE(REL32): /* word32 (S + A) | T - P */
case R_TYPE(ABS32): /* word32 (S + A) | T */
case R_TYPE(GLOB_DAT): /* word32 (S + A) | T */
if (__predict_true(RELOC_ALIGNED_P(where))) {
tmp = *where + symvalue;
if (isThumb(symvalue))
tmp |= 1;
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32))
tmp -= (Elf_Addr)where;
*where = tmp;
} else {
tmp = load_ptr(where) + symvalue;
if (isThumb(symvalue))
tmp |= 1;
if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32))
tmp -= (Elf_Addr)where;
store_ptr(where, tmp);
}
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: REL32/ABS32/GLOB_DAT %p @ %p in %s",
(void *)tmp, where, rtems_rtl_obj_oname (obj));
break;
case R_TYPE(THM_MOVT_ABS):
case R_TYPE(THM_MOVW_ABS_NC):
upper_insn = *(uint16_t *)where;
lower_insn = *((uint16_t *)where + 1);
addend = ((upper_insn & 0x000f) << 12) | ((upper_insn & 0x0400) << 1) |
((lower_insn & 0x7000) >> 4) | (lower_insn & 0x00ff);
addend = (addend ^ 0x8000) - 0x8000;
tmp = addend + symvalue;
if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
tmp >>= 16;
*(uint16_t *)where = (uint16_t)((upper_insn & 0xfbf0) |
((tmp & 0xf000) >> 12) |
((tmp & 0x0800) >> 1));
*((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0x8f00) |
((tmp & 0x0700) << 4) |
(tmp & 0x00ff));
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
printf ("rtl: THM_MOVT_ABS/THM_MOVW_ABS_NC %p @ %p in %s\n",
(void *)*where, where, rtems_rtl_obj_oname (obj));
}
break;
case R_TYPE(THM_JUMP24):
/* same to THM_CALL; insn b.w */
case R_TYPE(THM_CALL):
upper_insn = *(uint16_t *)where;
lower_insn = *((uint16_t *)where + 1);
sign = (upper_insn & (1 << 10)) >> 10;
i1 = ((lower_insn >> 13) & 1) ^ sign ? 0 : 1;
i2 = ((lower_insn >> 11) & 1) ^ sign ? 0 : 1;
tmp = (i1 << 23) | (i2 << 22) | ((upper_insn & 0x3ff) << 12) | ((lower_insn & 0x7ff) << 1);
addend = (tmp | ((sign ? 0 : 1) << 24)) - (1 << 24);
if (isThumb(symvalue)) ;/*Thumb to Thumb call, nothing to care */
else {
if (ELF_R_TYPE(rel->r_info) == R_TYPE(THM_JUMP24)) {
tmp = (tmp + 2) & ~3; /* aligned to 4 bytes only for JUMP24 */
printf("THM_JUMP24 to arm not supported\n");
return false;
}
else {
/* THM_CALL bl-->blx */
lower_insn &=~(1<<12);
}
}
tmp = symvalue + addend;
tmp = tmp - (Elf_Addr)where;
if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
printf("THM_CALL/JUMP24 overflow\n");
return false;
}
sign = (tmp >> 24) & 1;
*(uint16_t *)where = (uint16_t)((upper_insn & 0xf800) | (sign << 10) |
((tmp >> 12) & 0x3ff));
*((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0xd000)|
((sign ^ (~(tmp >> 23) & 1)) << 13) |
((sign ^ (~(tmp >> 22) & 1)) << 11) |
((tmp >> 1) & 0x7ff));
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)){
printf ("rtl: THM_CALL/JUMP24 %p @ %p in %s\n",
(void *)*where, where, rtems_rtl_obj_oname (obj));
}
break;
case R_TYPE(THM_JUMP19):
if (!isThumb(symvalue)) {
printf("THM_JUMP19 to arm not supported\n");
return false;
}
upper_insn = *(uint16_t *)where;
lower_insn = *((uint16_t *)where + 1);
sign = (upper_insn >> 10) & 0x1;
if ((((upper_insn & 0x3f) >> 7) & 0x7) == 0x7) {
printf("THM_JUMP19 failed\n");
return false; /*if cond <3:1> == '111', see Related codings in armv7a manual */
}
i1 = (lower_insn >> 13) & 0x1;
i2 = (lower_insn >> 11) & 0x1;
tmp = ((i2 << 19) | (i1 << 18) | ((upper_insn & 0x3f) << 12) | ((lower_insn & 0x7ff) << 1));
addend = (tmp | ((sign ? 0 : 1) << 20)) - (1 << 20);
tmp = symvalue + addend;
tmp = tmp - (Elf_Addr)where;
if (((Elf_Sword)tmp > 0x7ffffe) || ((Elf_Sword)tmp < -0x800000)) {
rtems_rtl_set_error (EINVAL, "%s: Overflow %ld "
"THM_JUMP19 relocations",
sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
return false;
}
sign = (tmp >> 20) & 0x1;
i2 = (tmp >> 19) & 0x1;
i1 = (tmp >> 18) & 0x1;
*(uint16_t*)where = (upper_insn & 0xfbc0) | (sign << 10) | ((tmp >> 12) & 0x3f);
*((uint16_t*)where + 1) = (lower_insn & 0xd000) | (i1 << 13) |
(i2 << 11) | ((tmp >> 1) & 0x7ff);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: THM_JUMP19 %p @ %p in %s\n",
(void *)*where, where, rtems_rtl_obj_oname (obj));
break;
default:
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
"contents = %p\n",
ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
(void *)rel->r_offset, (void *)*where);
rtems_rtl_set_error (EINVAL,
"%s: Unsupported relocation type %ld "
"in non-PLT relocations",
sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
return false;
}
return true;
}
+115
View File
@@ -0,0 +1,115 @@
#include <sys/cdefs.h>
#include <stdio.h>
#include <rtl.h>
#include <errno.h>
#include "rtl-elf.h"
#include "rtl-error.h"
#include "rtl-trace.h"
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
{
return true;
}
static inline Elf_Addr
load_ptr(void *where)
{
Elf_Addr res;
memcpy(&res, where, sizeof(res));
return (res);
}
bool
rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
Elf_Addr target = 0;
Elf_Addr *where;
Elf_Word tmp;
Elf_Word size; //byte
where = (Elf_Addr *)(sect->base + rela->r_offset);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
printf("rela relocation type is %d relocated address 0x%08x",
ELF_R_TYPE(rela->r_info), where);
}
tmp = symvalue;
switch (ELF_R_TYPE(rela->r_info)) {
case R_TYPE(UNUSED0):
break;
case R_TYPE(HUIMM16):
tmp = symvalue >> 16;
case R_TYPE(LUIMM16):
case R_TYPE(RIMM16):
size = 2;
break;
case R_TYPE(BYTE4_DATA):
size = 4;
break;
case R_TYPE(PCREL24):
case R_TYPE(PCREL24_JU):
where = (Elf_Addr*)((Elf_Addr)where - 2); /* Back 2 bytes */
tmp = symvalue - (Elf_Addr)where;
tmp >>= 1;
if ((tmp & 0x20000000) == 0x20000000)
tmp |= 0xc0000000;
if ((tmp & 0xff000000) && (~tmp & 0xff800000)) {
printf("PCREL24/PCREL24_JU Overflow\n");
return false;
}
tmp = (load_ptr(where) & 0x0000ff00) | ((tmp & 0x0000ffff) << 16) |
((tmp & 0x00ff0000) >> 16);
size = 4;
break;
case R_TYPE(PCREL12_JUMP_S):
tmp = symvalue - (Elf_Addr)where;
tmp >>= 1;
if ((tmp & 0x20000000) == 0x20000000)
tmp |= 0xc0000000;
if ((tmp & 0xfffff000) && (~tmp & 0xfffff800)) {
printf("PCREL12_JUMP_S Overflow\n");
return false;
}
tmp = ((*(uint16_t *)where) & 0xf000) | (tmp & 0xfff);
size = 2;
break;
default:
printf("Unspported rela type\n");
return false;
}
memcpy((void*)where, &tmp, size);
return true;
}
bool
rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
+101
View File
@@ -0,0 +1,101 @@
#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 "rtl-trace.h"
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
{
return true;
}
bool
rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
Elf_Addr *where;
Elf_Word tmp;
where = (Elf_Addr *)(sect->base + rela->r_offset);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
printf("rela relocation type is %ld\n", ELF_R_TYPE(rela->r_info));
printf("relocated address 0x%08lx\n", (Elf_Addr)where);
}
tmp = symvalue;
switch (ELF_R_TYPE(rela->r_info)) {
case R_TYPE(NONE):
break;
case R_TYPE(DIR16):
*(uint16_t *)where += symvalue + rela->r_addend;
break;
case R_TYPE(DIR32):
case R_TYPE(DIR32A16):
*where += symvalue + rela->r_addend;
break;
case R_TYPE(DIR24A8):
if (ELF32_R_SYM(rela->r_info))
*where += symvalue + rela->r_addend;
break;
case R_TYPE(DIR24R8):
where = (uint32_t *)((uint32_t)where - 1);
*where = (*where & 0xff000000) | ((*where & 0xffffff) + symvalue + rela->r_addend);
break;
case R_TYPE(PCREL8):
/* bcc instruction */
tmp = symvalue + rela->r_addend - (Elf_Addr)where - 1;
if (((Elf32_Sword)tmp > 0x7f) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x80)){
printf("PCREL8 overflow\n");
return false;
} else {
*(uint8_t *)where = tmp;
}
break;
case R_TYPE(PCREL16):
/* bcc instruction */
tmp = symvalue + rela->r_addend - (Elf_Addr)where - 2;
if (((Elf32_Sword)tmp > 0x7fff) || ((Elf32_Sword)tmp < -(Elf32_Sword)0x8000)){
printf("PCREL16 overflow\n");
return false;
} else {
*(uint16_t *)where = tmp;
}
break;
default:
rtems_rtl_set_error (EINVAL, "rela type record not supported");
printf("Unsupported reloc types\n");
return false;
}
return true;
}
bool
rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
+103
View File
@@ -0,0 +1,103 @@
/*
* Taken from NetBSD and stripped of the relocations not needed on RTEMS.
*/
/* $NetBSD: mdreloc.c,v 1.31 2010/01/14 11:58:32 skrll Exp $ */
#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 "rtl-trace.h"
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
{
return true;
}
bool
rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t* obj,
const Elf_Rela* rel,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
rtems_rtl_set_error (EINVAL, "rela type record not supported");
return false;
}
bool
rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect_t* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
Elf_Addr target = 0;
Elf_Addr* where;
Elf_Addr tmp;
where = (Elf_Addr *)(sect->base + rel->r_offset);
switch (ELF_R_TYPE(rel->r_info)) {
case R_TYPE(NONE):
break;
case R_TYPE(PC32):
target = (Elf_Addr) symvalue;
*where += target - (Elf_Addr)where;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: reloc PC32 in %s --> %p (%p @ %p) in %s\n",
sect->name, (void*) symvalue,
(void *)*where, where, rtems_rtl_obj_oname (obj));
break;
case R_TYPE(GOT32):
case R_TYPE(32):
case R_TYPE(GLOB_DAT):
target = (Elf_Addr) symvalue;
tmp = target + *where;
if (*where != tmp)
*where = tmp;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: reloc 32/GLOB_DAT in %s --> %p @ %p in %s\n",
sect->name, (void *)*where, where,
rtems_rtl_obj_oname (obj));
break;
case R_TYPE(RELATIVE):
*where += (Elf_Addr)sect->base;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: reloc RELATIVE in %s --> %p @ %p\n",
rtems_rtl_obj_oname (obj), (void *)*where, where);
break;
case R_TYPE(COPY):
printf ("rtl: reloc COPY (please report)\n");
break;
default:
printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
"contents = %p\n",
ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
(void *)rel->r_offset, (void *)*where);
rtems_rtl_set_error (EINVAL,
"%s: Unsupported relocation type %ld "
"in non-PLT relocations",
sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
return false;
}
return true;
}

Some files were not shown because too many files have changed in this diff Show More