mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-08-22 09:04:51 +08:00
cpukit: Add libdl with the Runtime Loader (RTL) code.
This is a merge of the RTL project.
This commit is contained in:
+19
-1
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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)
|
||||
@@ -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_ */
|
||||
@@ -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_ */
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user