summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2008-01-05 10:05:27 +0000
committerMike Frysinger <vapier@gentoo.org>2008-01-05 10:05:27 +0000
commit124ec188720b6bdea85ade49e7ea195161b12fce (patch)
tree2bce39bc1e51bd587e010a61419b47d122be3165
parent9c95d5d28d8d40f7b826c9399f5ce781bbc61567 (diff)
Chris Zankel writes:
The following patches add support for the Xtensa processor architecture to uClibc. They are based on a recent SVN checkout (12/05/2007). The first patch (attached to this post) adds Xtensa support to various shared configuration and make files. The following patches then include the Xtensa specific files and directories. I welcome any feedback and would appreciate it if you could include the patches into the mainline tree. I am certainly committed to maintain the port. Bob Wilson was kind enough to review the patches. Some notes about the architecture: Xtensa is a configurable and extensible processor architecture developed by Tensilica. For more information, please visit: www.linux-xtensa.org.
-rw-r--r--Rules.mak3
-rw-r--r--extra/Configs/Config.in7
-rw-r--r--extra/Configs/Config.xtensa12
-rw-r--r--include/elf.h58
-rw-r--r--ldso/include/dl-string.h2
-rw-r--r--ldso/ldso/xtensa/dl-debug.h61
-rw-r--r--ldso/ldso/xtensa/dl-startup.h106
-rw-r--r--ldso/ldso/xtensa/dl-syscalls.h7
-rw-r--r--ldso/ldso/xtensa/dl-sysdep.h132
-rw-r--r--ldso/ldso/xtensa/elfinterp.c285
-rw-r--r--ldso/ldso/xtensa/resolve.S61
-rw-r--r--libc/string/xtensa/Makefile13
-rw-r--r--libc/string/xtensa/memcpy.S297
-rw-r--r--libc/string/xtensa/memset.S165
-rw-r--r--libc/string/xtensa/strcmp.S313
-rw-r--r--libc/string/xtensa/strcpy.S150
-rw-r--r--libc/string/xtensa/strlen.S104
-rw-r--r--libc/string/xtensa/strncpy.S241
-rw-r--r--libc/sysdeps/linux/xtensa/Makefile13
-rw-r--r--libc/sysdeps/linux/xtensa/Makefile.arch14
-rw-r--r--libc/sysdeps/linux/xtensa/__longjmp.S126
-rw-r--r--libc/sysdeps/linux/xtensa/__syscall_error.c18
-rw-r--r--libc/sysdeps/linux/xtensa/bits/endian.h10
-rw-r--r--libc/sysdeps/linux/xtensa/bits/fcntl.h196
-rw-r--r--libc/sysdeps/linux/xtensa/bits/ipc.h54
-rw-r--r--libc/sysdeps/linux/xtensa/bits/kernel_stat.h57
-rw-r--r--libc/sysdeps/linux/xtensa/bits/kernel_types.h48
-rw-r--r--libc/sysdeps/linux/xtensa/bits/mathdef.h43
-rw-r--r--libc/sysdeps/linux/xtensa/bits/mman.h104
-rw-r--r--libc/sysdeps/linux/xtensa/bits/msq.h88
-rw-r--r--libc/sysdeps/linux/xtensa/bits/setjmp.h46
-rw-r--r--libc/sysdeps/linux/xtensa/bits/shm.h115
-rw-r--r--libc/sysdeps/linux/xtensa/bits/sigcontextinfo.h33
-rw-r--r--libc/sysdeps/linux/xtensa/bits/stackinfo.h28
-rw-r--r--libc/sysdeps/linux/xtensa/bits/stat.h153
-rw-r--r--libc/sysdeps/linux/xtensa/bits/syscalls.h140
-rw-r--r--libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h44
-rw-r--r--libc/sysdeps/linux/xtensa/bits/uClibc_page.h31
-rw-r--r--libc/sysdeps/linux/xtensa/bits/wordsize.h19
-rw-r--r--libc/sysdeps/linux/xtensa/bits/xtensa-config.h53
-rw-r--r--libc/sysdeps/linux/xtensa/brk.c43
-rw-r--r--libc/sysdeps/linux/xtensa/bsd-_setjmp.S1
-rw-r--r--libc/sysdeps/linux/xtensa/bsd-setjmp.S1
-rw-r--r--libc/sysdeps/linux/xtensa/clone.S103
-rw-r--r--libc/sysdeps/linux/xtensa/crt1.S119
-rw-r--r--libc/sysdeps/linux/xtensa/crti.S16
-rw-r--r--libc/sysdeps/linux/xtensa/crtn.S8
-rw-r--r--libc/sysdeps/linux/xtensa/fork.c25
-rw-r--r--libc/sysdeps/linux/xtensa/mmap.S57
-rw-r--r--libc/sysdeps/linux/xtensa/posix_fadvise.c29
-rw-r--r--libc/sysdeps/linux/xtensa/posix_fadvise64.c39
-rw-r--r--libc/sysdeps/linux/xtensa/pread_write.c193
-rw-r--r--libc/sysdeps/linux/xtensa/setjmp.S131
-rw-r--r--libc/sysdeps/linux/xtensa/sys/procfs.h121
-rw-r--r--libc/sysdeps/linux/xtensa/sys/ptrace.h156
-rw-r--r--libc/sysdeps/linux/xtensa/sys/ucontext.h49
-rw-r--r--libc/sysdeps/linux/xtensa/syscall.S42
-rw-r--r--libc/sysdeps/linux/xtensa/sysdep.h160
-rw-r--r--libc/sysdeps/linux/xtensa/vfork.S170
-rw-r--r--libc/sysdeps/linux/xtensa/windowspill.S95
-rw-r--r--libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h48
-rw-r--r--test/Rules.mak1
62 files changed, 5055 insertions, 2 deletions
diff --git a/Rules.mak b/Rules.mak
index c14a907d7..99d7efa2d 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -50,7 +50,8 @@ BUILD_CFLAGS = -O2 -Wall
export ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun.*/sparc/ -e s/sparc.*/sparc/ \
-e s/arm.*/arm/ -e s/sa110/arm/ -e s/sh.*/sh/ \
-e s/s390x/s390/ -e s/parisc.*/hppa/ \
- -e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
+ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+ -e s/xtensa.*/xtensa/ )
#---------------------------------------------------------
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index ec4cb4bdc..37dc0ba1e 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -82,6 +82,9 @@ config TARGET_vax
config TARGET_x86_64
bool "x86_64"
+config TARGET_xtensa
+ bool "xtensa"
+
endchoice
@@ -183,6 +186,10 @@ if TARGET_x86_64
source "extra/Configs/Config.x86_64"
endif
+if TARGET_xtensa
+source "extra/Configs/Config.xtensa"
+endif
+
config TARGET_SUBARCH
string
default "e500" if CONFIG_E500
diff --git a/extra/Configs/Config.xtensa b/extra/Configs/Config.xtensa
new file mode 100644
index 000000000..75132471a
--- /dev/null
+++ b/extra/Configs/Config.xtensa
@@ -0,0 +1,12 @@
+#
+# For a description of the syntax of this configuration file,
+# see extra/config/kconfig-language.txt
+#
+
+config TARGET_ARCH
+ string
+ default "xtensa"
+
+config ARCH_CFLAGS
+ string
+
diff --git a/include/elf.h b/include/elf.h
index 5ce5c694a..4c6d09012 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -2977,6 +2977,64 @@ typedef Elf32_Addr Elf32_Conflict;
/* Keep this the last entry. */
#define R_NIOS2_NUM 22
+/* Xtensa-specific declarations */
+
+/* Xtensa values for the Dyn d_tag field. */
+#define DT_XTENSA_GOT_LOC_OFF (DT_LOPROC + 0)
+#define DT_XTENSA_GOT_LOC_SZ (DT_LOPROC + 1)
+#define DT_XTENSA_NUM 2
+
+/* Xtensa relocations. */
+#define R_XTENSA_NONE 0
+#define R_XTENSA_32 1
+#define R_XTENSA_RTLD 2
+#define R_XTENSA_GLOB_DAT 3
+#define R_XTENSA_JMP_SLOT 4
+#define R_XTENSA_RELATIVE 5
+#define R_XTENSA_PLT 6
+#define R_XTENSA_OP0 8
+#define R_XTENSA_OP1 9
+#define R_XTENSA_OP2 10
+#define R_XTENSA_ASM_EXPAND 11
+#define R_XTENSA_ASM_SIMPLIFY 12
+#define R_XTENSA_GNU_VTINHERIT 15
+#define R_XTENSA_GNU_VTENTRY 16
+#define R_XTENSA_DIFF8 17
+#define R_XTENSA_DIFF16 18
+#define R_XTENSA_DIFF32 19
+#define R_XTENSA_SLOT0_OP 20
+#define R_XTENSA_SLOT1_OP 21
+#define R_XTENSA_SLOT2_OP 22
+#define R_XTENSA_SLOT3_OP 23
+#define R_XTENSA_SLOT4_OP 24
+#define R_XTENSA_SLOT5_OP 25
+#define R_XTENSA_SLOT6_OP 26
+#define R_XTENSA_SLOT7_OP 27
+#define R_XTENSA_SLOT8_OP 28
+#define R_XTENSA_SLOT9_OP 29
+#define R_XTENSA_SLOT10_OP 30
+#define R_XTENSA_SLOT11_OP 31
+#define R_XTENSA_SLOT12_OP 32
+#define R_XTENSA_SLOT13_OP 33
+#define R_XTENSA_SLOT14_OP 34
+#define R_XTENSA_SLOT0_ALT 35
+#define R_XTENSA_SLOT1_ALT 36
+#define R_XTENSA_SLOT2_ALT 37
+#define R_XTENSA_SLOT3_ALT 38
+#define R_XTENSA_SLOT4_ALT 39
+#define R_XTENSA_SLOT5_ALT 40
+#define R_XTENSA_SLOT6_ALT 41
+#define R_XTENSA_SLOT7_ALT 42
+#define R_XTENSA_SLOT8_ALT 43
+#define R_XTENSA_SLOT9_ALT 44
+#define R_XTENSA_SLOT10_ALT 45
+#define R_XTENSA_SLOT11_ALT 46
+#define R_XTENSA_SLOT12_ALT 47
+#define R_XTENSA_SLOT13_ALT 48
+#define R_XTENSA_SLOT14_ALT 49
+/* Keep this the last entry. */
+#define R_XTENSA_NUM 50
+
__END_DECLS
#endif /* elf.h */
diff --git a/ldso/include/dl-string.h b/ldso/include/dl-string.h
index bf993b29c..746bd91c6 100644
--- a/ldso/include/dl-string.h
+++ b/ldso/include/dl-string.h
@@ -286,7 +286,7 @@ static __always_inline char * _dl_simple_ltoahex(char * local, unsigned long i)
* This requires that load_addr must already be defined... */
#if defined(mc68000) || defined(__arm__) || defined(__thumb__) || \
defined(__mips__) || defined(__sh__) || defined(__powerpc__) || \
- defined(__avr32__)
+ defined(__avr32__) || defined(__xtensa__)
# define CONSTANT_STRING_GOT_FIXUP(X) \
if ((X) < (const char *) load_addr) (X) += load_addr
# define NO_EARLY_SEND_STDERR
diff --git a/ldso/ldso/xtensa/dl-debug.h b/ldso/ldso/xtensa/dl-debug.h
new file mode 100644
index 000000000..327defc07
--- /dev/null
+++ b/ldso/ldso/xtensa/dl-debug.h
@@ -0,0 +1,61 @@
+/* vi: set sw=4 ts=4: */
+/* Xtensa ELF shared library loader suppport
+ *
+ * Copyright (C) 2007 Tensilica Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+static const char *_dl_reltypes_tab[] =
+{
+ "R_XTENSA_NONE",
+ "R_XTENSA_32",
+ "R_XTENSA_RTLD",
+ "R_XTENSA_GLOB_DAT",
+ "R_XTENSA_JMP_SLOT",
+ "R_XTENSA_RELATIVE",
+ "R_XTENSA_PLT",
+ "R_XTENSA_UNUSED7",
+ "R_XTENSA_OP0",
+ "R_XTENSA_OP1",
+ "R_XTENSA_OP2",
+ "R_XTENSA_ASM_EXPAND",
+ "R_XTENSA_ASM_SIMPLIFY",
+ "R_XTENSA_UNUSED13",
+ "R_XTENSA_UNUSED14",
+ "R_XTENSA_GNU_VTINHERIT",
+ "R_XTENSA_GNU_VTENTRY",
+ "R_XTENSA_DIFF8",
+ "R_XTENSA_DIFF16",
+ "R_XTENSA_DIFF32",
+ "R_XTENSA_SLOT0_OP",
+ "R_XTENSA_SLOT1_OP",
+ "R_XTENSA_SLOT2_OP",
+ "R_XTENSA_SLOT3_OP",
+ "R_XTENSA_SLOT4_OP",
+ "R_XTENSA_SLOT5_OP",
+ "R_XTENSA_SLOT6_OP",
+ "R_XTENSA_SLOT7_OP",
+ "R_XTENSA_SLOT8_OP",
+ "R_XTENSA_SLOT9_OP",
+ "R_XTENSA_SLOT10_OP",
+ "R_XTENSA_SLOT11_OP",
+ "R_XTENSA_SLOT12_OP",
+ "R_XTENSA_SLOT13_OP",
+ "R_XTENSA_SLOT14_OP",
+ "R_XTENSA_SLOT0_ALT",
+ "R_XTENSA_SLOT1_ALT",
+ "R_XTENSA_SLOT2_ALT",
+ "R_XTENSA_SLOT3_ALT",
+ "R_XTENSA_SLOT4_ALT",
+ "R_XTENSA_SLOT5_ALT",
+ "R_XTENSA_SLOT6_ALT",
+ "R_XTENSA_SLOT7_ALT",
+ "R_XTENSA_SLOT8_ALT",
+ "R_XTENSA_SLOT9_ALT",
+ "R_XTENSA_SLOT10_ALT",
+ "R_XTENSA_SLOT11_ALT",
+ "R_XTENSA_SLOT12_ALT",
+ "R_XTENSA_SLOT13_ALT",
+ "R_XTENSA_SLOT14_ALT"
+};
diff --git a/ldso/ldso/xtensa/dl-startup.h b/ldso/ldso/xtensa/dl-startup.h
new file mode 100644
index 000000000..2fd012846
--- /dev/null
+++ b/ldso/ldso/xtensa/dl-startup.h
@@ -0,0 +1,106 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Xtensa ELF code used by dl-startup.c.
+ *
+ * Copyright (C) 2007 Tensilica Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ * Parts taken from glibc/sysdeps/xtensa/dl-machine.h.
+ */
+
+__asm__ (
+ " .text\n"
+ " .align 4\n"
+ " .global _start\n"
+ " .type _start, @function\n"
+ "_start:\n"
+ " # Compute load offset in a2: the GOT has not yet been relocated\n"
+ " # but the entries for local symbols contain the relative offsets\n"
+ " # and we can explicitly add the load offset in this code.\n"
+ " _call0 0f\n"
+ " .align 4\n"
+ "0: movi a3, _start+3\n"
+ " sub a2, a0, a3\n"
+ " # Make sure a0 is cleared to mark the top of stack.\n"
+ " movi a0, 0\n"
+ " # user_entry_point = _dl_start(pointer to argument block)\n"
+ " movi a4, _dl_start\n"
+ " mov a6, sp\n"
+ " add a4, a4, a2\n"
+ " callx4 a4\n"
+ " # Save user_entry_point so we can jump to it.\n"
+ " mov a3, a6\n"
+ " l32i a7, sp, 0 # load argc\n"
+ " # Load _dl_skip_args into a4.\n"
+ " movi a4, _dl_skip_args\n"
+ " l32i a4, a4, 0\n"
+ " bnez a4, .Lfixup_stack\n"
+ ".Lfixup_stack_ret:\n"
+ " # Pass finalizer (_dl_fini) in a2 to the user entry point.\n"
+ " movi a2, _dl_fini\n"
+ " # Jump to user's entry point (_start).\n"
+ " jx a3\n"
+ ".Lfixup_stack:\n"
+ " # argc -= _dl_skip_args (with argc @ sp+0)\n"
+ " sub a7, a7, a4\n"
+ " s32i a7, sp, 0\n"
+ " # Shift everything by _dl_skip_args.\n"
+ " addi a5, sp, 4 # a5 = destination ptr = argv\n"
+ " add a4, a5, a4 # a4 = source ptr = argv + _dl_skip_args\n"
+ " # Shift argv.\n"
+ "1: l32i a6, a4, 0\n"
+ " addi a4, a4, 4\n"
+ " s32i a6, a5, 0\n"
+ " addi a5, a5, 4\n"
+ " bnez a6, 1b\n"
+ " # Shift envp.\n"
+ "2: l32i a6, a4, 0\n"
+ " addi a4, a4, 4\n"
+ " s32i a6, a5, 0\n"
+ " addi a5, a5, 4\n"
+ " bnez a6, 2b\n"
+ " # Shift auxiliary table.\n"
+ "3: l32i a6, a4, 0\n"
+ " l32i a8, a4, 4\n"
+ " addi a4, a4, 8\n"
+ " s32i a6, a5, 0\n"
+ " s32i a8, a5, 4\n"
+ " addi a5, a5, 8\n"
+ " bnez a6, 3b\n"
+ " j .Lfixup_stack_ret");
+
+/* Get a pointer to the argv value. */
+#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS) + 1)
+
+/* Function calls are not safe until the GOT relocations have been done. */
+#define NO_FUNCS_BEFORE_BOOTSTRAP
+
+#define PERFORM_BOOTSTRAP_GOT(tpnt) \
+do { \
+ xtensa_got_location *got_loc; \
+ unsigned long l_addr = tpnt->loadaddr; \
+ Elf32_Word relative_count; \
+ unsigned long rel_addr; \
+ int x; \
+\
+ got_loc = (xtensa_got_location *) \
+ (tpnt->dynamic_info[DT_XTENSA (GOT_LOC_OFF)] + l_addr); \
+\
+ for (x = 0; x < tpnt->dynamic_info[DT_XTENSA (GOT_LOC_SZ)]; x++) { \
+ Elf32_Addr got_start, got_end; \
+ got_start = got_loc[x].offset & ~(PAGE_SIZE - 1); \
+ got_end = ((got_loc[x].offset + got_loc[x].length + PAGE_SIZE - 1) \
+ & ~(PAGE_SIZE - 1)); \
+ _dl_mprotect ((void *)(got_start + l_addr), got_end - got_start, \
+ PROT_READ | PROT_WRITE | PROT_EXEC); \
+ } \
+\
+ /* The following is a stripped down version of the code following \
+ the invocation of PERFORM_BOOTSTRAP_GOT in dl-startup.c. That \
+ code is skipped when PERFORM_BOOTSTRAP_GOT is defined, so it has \
+ to be done here instead. */ \
+ relative_count = tpnt->dynamic_info[DT_RELCONT_IDX]; \
+ rel_addr = tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]; \
+ if (rel_addr) \
+ elf_machine_relative(load_addr, rel_addr, relative_count); \
+} while (0)
diff --git a/ldso/ldso/xtensa/dl-syscalls.h b/ldso/ldso/xtensa/dl-syscalls.h
new file mode 100644
index 000000000..4b42a57e0
--- /dev/null
+++ b/ldso/ldso/xtensa/dl-syscalls.h
@@ -0,0 +1,7 @@
+/* We can't use the real errno in ldso, since it has not yet
+ * been dynamicly linked in yet. */
+#include "sys/syscall.h"
+extern int _dl_errno;
+#undef __set_errno
+#define __set_errno(X) {(_dl_errno) = (X);}
+
diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h
new file mode 100644
index 000000000..afbbf3bfe
--- /dev/null
+++ b/ldso/ldso/xtensa/dl-sysdep.h
@@ -0,0 +1,132 @@
+/* Machine-dependent ELF dynamic relocation.
+ Parts copied from glibc/sysdeps/xtensa/dl-machine.h
+ Copyright (C) 2001, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* Define this if the system uses RELOCA. */
+#define ELF_USES_RELOCA
+#include <elf.h>
+#include <link.h>
+
+/* Translate a processor specific dynamic tag to the index
+ in l_info array. */
+#define DT_XTENSA(x) (DT_XTENSA_##x - DT_LOPROC + DT_NUM + OS_NUM)
+
+typedef struct xtensa_got_location_struct {
+ Elf32_Off offset;
+ Elf32_Word length;
+} xtensa_got_location;
+
+/* Initialization sequence for the GOT. */
+#define INIT_GOT(GOT_BASE, MODULE) \
+ do { \
+ xtensa_got_location *got_loc; \
+ Elf32_Addr l_addr = MODULE->loadaddr; \
+ int x; \
+ \
+ got_loc = (xtensa_got_location *) \
+ (MODULE->dynamic_info[DT_XTENSA (GOT_LOC_OFF)] + l_addr); \
+ \
+ for (x = 0; x < MODULE->dynamic_info[DT_XTENSA (GOT_LOC_SZ)]; x++) \
+ { \
+ Elf32_Addr got_start, got_end; \
+ got_start = got_loc[x].offset & ~(PAGE_SIZE - 1); \
+ got_end = ((got_loc[x].offset + got_loc[x].length + PAGE_SIZE - 1) \
+ & ~(PAGE_SIZE - 1)); \
+ _dl_mprotect ((void *)(got_start + l_addr) , got_end - got_start, \
+ PROT_READ | PROT_WRITE | PROT_EXEC); \
+ } \
+ \
+ /* Fill in first GOT entry according to the ABI. */ \
+ GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \
+ } while (0)
+
+/* Parse dynamic info */
+#define ARCH_NUM 2
+#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \
+ do { \
+ if (dpnt->d_tag == DT_XTENSA_GOT_LOC_OFF) \
+ dynamic[DT_XTENSA (GOT_LOC_OFF)] = dpnt->d_un.d_ptr; \
+ else if (dpnt->d_tag == DT_XTENSA_GOT_LOC_SZ) \
+ dynamic[DT_XTENSA (GOT_LOC_SZ)] = dpnt->d_un.d_val; \
+ } while (0)
+
+/* Here we define the magic numbers that this dynamic loader should accept. */
+#define MAGIC1 EM_XTENSA
+#undef MAGIC2
+
+/* Used for error messages. */
+#define ELF_TARGET "Xtensa"
+
+struct elf_resolve;
+extern unsigned long _dl_linux_resolver (struct elf_resolve *, int);
+
+/* 4096 bytes alignment */
+#define PAGE_ALIGN 0xfffff000
+#define ADDR_ALIGN 0xfff
+#define OFFS_ALIGN 0x7ffff000
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+ undefined references should not be allowed to define the value. */
+#define elf_machine_type_class(type) \
+ (((type) == R_XTENSA_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
+
+/* Return the link-time address of _DYNAMIC. */
+static inline Elf32_Addr
+elf_machine_dynamic (void)
+{
+ /* This function is only used while bootstrapping the runtime linker.
+ The "_DYNAMIC" symbol is always local so its GOT entry will initially
+ contain the link-time address. */
+ return (Elf32_Addr) &_DYNAMIC;
+}
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr
+elf_machine_load_address (void)
+{
+ Elf32_Addr addr, tmp;
+
+ /* At this point, the runtime linker is being bootstrapped and the GOT
+ entry used for ".Lhere" will contain the link address. The CALL0 will
+ produce the dynamic address of ".Lhere" + 3. Thus, the end result is
+ equal to "dynamic_address(.Lhere) - link_address(.Lhere)". */
+ __asm__ ("\
+ movi %0, .Lhere\n\
+ mov %1, a0\n\
+.Lhere: _call0 0f\n\
+ .align 4\n\
+0: sub %0, a0, %0\n\
+ mov a0, %1"
+ : "=a" (addr), "=a" (tmp));
+
+ return addr - 3;
+}
+
+static inline void
+elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
+ Elf32_Word relative_count)
+{
+ Elf32_Rela *rpnt = (Elf32_Rela *) rel_addr;
+ while (relative_count--)
+ {
+ Elf32_Addr *const reloc_addr = (Elf32_Addr *) (load_off + rpnt->r_offset);
+ *reloc_addr += load_off + rpnt->r_addend;
+ rpnt++;
+ }
+}
diff --git a/ldso/ldso/xtensa/elfinterp.c b/ldso/ldso/xtensa/elfinterp.c
new file mode 100644
index 000000000..a459431b1
--- /dev/null
+++ b/ldso/ldso/xtensa/elfinterp.c
@@ -0,0 +1,285 @@
+/* vi: set sw=4 ts=4: */
+/* Xtensa ELF shared library loader suppport
+ *
+ * Copyright (C) 2007 Tensilica Inc.
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
+ * David Engel, Hongjiu Lu and Mitch D'Souza
+ * Copyright (C) 2001-2004 Erik Andersen
+ *
+ * All rights reserved.
+ *
+ * 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. The name of the above contributors may not be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE 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 CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "ldso.h"
+
+unsigned long
+_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
+{
+ int reloc_type;
+ ELF_RELOC *this_reloc;
+ char *strtab;
+ Elf32_Sym *symtab;
+ int symtab_index;
+ char *rel_addr;
+ char *new_addr;
+ char **got_addr;
+ char *symname;
+
+ rel_addr = (char *) tpnt->dynamic_info[DT_JMPREL];
+ this_reloc = (ELF_RELOC *) (rel_addr + reloc_entry);
+ reloc_type = ELF32_R_TYPE (this_reloc->r_info);
+ symtab_index = ELF32_R_SYM (this_reloc->r_info);
+
+ symtab = (Elf32_Sym *) tpnt->dynamic_info[DT_SYMTAB];
+ strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
+ symname = strtab + symtab[symtab_index].st_name;
+
+ if (unlikely (reloc_type != R_XTENSA_JMP_SLOT)) {
+ _dl_dprintf (2, "%s: Incorrect relocation type in jump relocations\n",
+ _dl_progname);
+ _dl_exit (1);
+ }
+
+ /* Address of the literal to fix up. */
+ got_addr = (char **) (this_reloc->r_offset + tpnt->loadaddr);
+
+ /* Get the address of the GOT entry. */
+ new_addr = _dl_find_hash (symname, tpnt->symbol_scope, tpnt,
+ ELF_RTYPE_CLASS_PLT);
+ if (unlikely (!new_addr)) {
+ _dl_dpri