[PATCH 4/7] The C6X port

Bernd Schmidt bernds_cb1 at t-online.de
Wed Mar 2 20:21:54 UTC 2011


From: Aurelien Jacquiot <a-jacquiot at ti.com>

This adds support for the TI C6X family of processors.

Signed-off-by: Mark Salter <msalter at redhat.com>
Signed-off-by: Aurelien Jacquiot <a-jacquiot at ti.com>
Signed-off-by: Bernd Schmidt <bernds at codesourcery.com>
---
 Rules.mak                                          |   12 +
 extra/Configs/Config.c6x                           |   34 +++
 extra/Configs/Config.in                            |    7 +
 extra/Configs/Config.in.arch                       |    4 +
 include/elf.h                                      |   45 +++
 ldso/ldso/c6x/dl-debug.h                           |   49 ++++
 ldso/ldso/c6x/dl-inlines.h                         |   91 ++++++
 ldso/ldso/c6x/dl-startup.h                         |  122 ++++++++
 ldso/ldso/c6x/dl-syscalls.h                        |   25 ++
 ldso/ldso/c6x/dl-sysdep.h                          |  209 ++++++++++++++
 ldso/ldso/c6x/elfinterp.c                          |  296 ++++++++++++++++++++
 ldso/ldso/c6x/resolve.S                            |   68 +++++
 libc/sysdeps/linux/c6x/Makefile                    |   13 +
 libc/sysdeps/linux/c6x/Makefile.arch               |   15 +
 libc/sysdeps/linux/c6x/__longjmp.S                 |   47 +++
 libc/sysdeps/linux/c6x/_vfork.S                    |   55 ++++
 libc/sysdeps/linux/c6x/bits/byteswap.h             |   35 +++
 libc/sysdeps/linux/c6x/bits/elf-dsbt.h             |  123 ++++++++
 libc/sysdeps/linux/c6x/bits/endian.h               |   11 +
 libc/sysdeps/linux/c6x/bits/fcntl.h                |  235 ++++++++++++++++
 libc/sysdeps/linux/c6x/bits/kernel_stat.h          |   52 ++++
 libc/sysdeps/linux/c6x/bits/kernel_types.h         |   46 +++
 libc/sysdeps/linux/c6x/bits/mathdef.h              |   39 +++
 libc/sysdeps/linux/c6x/bits/nan.h                  |   57 ++++
 libc/sysdeps/linux/c6x/bits/poll.h                 |   43 +++
 libc/sysdeps/linux/c6x/bits/resource.h             |  209 ++++++++++++++
 libc/sysdeps/linux/c6x/bits/setjmp.h               |   39 +++
 libc/sysdeps/linux/c6x/bits/sigcontextinfo.h       |   26 ++
 libc/sysdeps/linux/c6x/bits/stackinfo.h            |   28 ++
 libc/sysdeps/linux/c6x/bits/stat.h                 |  174 ++++++++++++
 libc/sysdeps/linux/c6x/bits/syscalls.h             |  182 ++++++++++++
 libc/sysdeps/linux/c6x/bits/uClibc_arch_features.h |   48 ++++
 libc/sysdeps/linux/c6x/bits/wordsize.h             |   19 ++
 libc/sysdeps/linux/c6x/brk.c                       |   54 ++++
 libc/sysdeps/linux/c6x/bsd-_setjmp.s               |   48 ++++
 libc/sysdeps/linux/c6x/bsd-setjmp.S                |   67 +++++
 libc/sysdeps/linux/c6x/clone.S                     |   97 +++++++
 libc/sysdeps/linux/c6x/crt1.S                      |   67 +++++
 libc/sysdeps/linux/c6x/crti.S                      |   17 ++
 libc/sysdeps/linux/c6x/crtn.S                      |   19 ++
 libc/sysdeps/linux/c6x/prctl.c                     |   43 +++
 libc/sysdeps/linux/c6x/pread_write.c               |  103 +++++++
 libc/sysdeps/linux/c6x/setjmp.s                    |   43 +++
 libc/sysdeps/linux/c6x/sigaction.c                 |  115 ++++++++
 libc/sysdeps/linux/c6x/sys/procfs.h                |  122 ++++++++
 libc/sysdeps/linux/c6x/sys/reg.h                   |   26 ++
 libc/sysdeps/linux/c6x/sys/ucontext.h              |   39 +++
 libc/sysdeps/linux/c6x/sys/user.h                  |   28 ++
 libc/sysdeps/linux/c6x/syscall.c                   |   49 ++++
 libc/sysdeps/linux/c6x/vfork.c                     |   26 ++
 libc/sysdeps/linux/common/Makefile.in              |    1 +
 .../linuxthreads.old/sysdeps/c6x/pt-machine.h      |   64 +++++
 52 files changed, 3486 insertions(+), 0 deletions(-)
 create mode 100644 extra/Configs/Config.c6x
 create mode 100644 ldso/ldso/c6x/dl-debug.h
 create mode 100644 ldso/ldso/c6x/dl-inlines.h
 create mode 100644 ldso/ldso/c6x/dl-startup.h
 create mode 100644 ldso/ldso/c6x/dl-syscalls.h
 create mode 100644 ldso/ldso/c6x/dl-sysdep.h
 create mode 100644 ldso/ldso/c6x/elfinterp.c
 create mode 100644 ldso/ldso/c6x/resolve.S
 create mode 100644 libc/sysdeps/linux/c6x/Makefile
 create mode 100644 libc/sysdeps/linux/c6x/Makefile.arch
 create mode 100644 libc/sysdeps/linux/c6x/__longjmp.S
 create mode 100644 libc/sysdeps/linux/c6x/_vfork.S
 create mode 100644 libc/sysdeps/linux/c6x/bits/byteswap.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/elf-dsbt.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/endian.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/fcntl.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/kernel_stat.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/kernel_types.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/mathdef.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/nan.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/poll.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/resource.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/setjmp.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/sigcontextinfo.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/stackinfo.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/stat.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/syscalls.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/uClibc_arch_features.h
 create mode 100644 libc/sysdeps/linux/c6x/bits/wordsize.h
 create mode 100644 libc/sysdeps/linux/c6x/brk.c
 create mode 100644 libc/sysdeps/linux/c6x/bsd-_setjmp.s
 create mode 100644 libc/sysdeps/linux/c6x/bsd-setjmp.S
 create mode 100644 libc/sysdeps/linux/c6x/clone.S
 create mode 100644 libc/sysdeps/linux/c6x/crt1.S
 create mode 100644 libc/sysdeps/linux/c6x/crti.S
 create mode 100644 libc/sysdeps/linux/c6x/crtn.S
 create mode 100644 libc/sysdeps/linux/c6x/prctl.c
 create mode 100644 libc/sysdeps/linux/c6x/pread_write.c
 create mode 100644 libc/sysdeps/linux/c6x/setjmp.s
 create mode 100644 libc/sysdeps/linux/c6x/sigaction.c
 create mode 100644 libc/sysdeps/linux/c6x/sys/procfs.h
 create mode 100644 libc/sysdeps/linux/c6x/sys/reg.h
 create mode 100644 libc/sysdeps/linux/c6x/sys/ucontext.h
 create mode 100644 libc/sysdeps/linux/c6x/sys/user.h
 create mode 100644 libc/sysdeps/linux/c6x/syscall.c
 create mode 100644 libc/sysdeps/linux/c6x/vfork.c
 create mode 100644 libpthread/linuxthreads.old/sysdeps/c6x/pt-machine.h

diff --git a/Rules.mak b/Rules.mak
index 8165cca..abf958b 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -218,10 +218,12 @@ ifeq ($(UCLIBC_HAS_SOFT_FLOAT),y)
 ifneq ($(TARGET_ARCH),nios)
 ifneq ($(TARGET_ARCH),nios2)
 ifneq ($(TARGET_ARCH),sh)
+ifneq ($(TARGET_ARCH),c6x)
 CPU_CFLAGS-y += -msoft-float
 endif
 endif
 endif
+endif
 ifeq ($(TARGET_ARCH),arm)
 # No longer needed with current toolchains, but leave it here for now.
 # If anyone is actually still using gcc 2.95 (say), they can uncomment it.
@@ -239,6 +241,7 @@ CPU_LDFLAGS-$(ARCH_BIG_ENDIAN)    += -Wl,-EB
 
 PICFLAG-y := -fPIC
 PICFLAG-$(UCLIBC_FORMAT_FDPIC_ELF) := -mfdpic
+PICFLAG-$(UCLIBC_FORMAT_DSBT_ELF)  := -mdsbt -fpic
 PICFLAG := $(PICFLAG-y)
 PIEFLAG_NAME:=-fPIE
 
@@ -485,6 +488,15 @@ ifeq ($(TARGET_ARCH),v850)
       SYMBOL_PREFIX=_
 endif
 
+ifeq ($(TARGET_ARCH),c6x)
+	PIEFLAG:=
+	CPU_CFLAGS-$(CONFIG_TMS320C64X) += -march=c64x
+	CPU_CFLAGS-$(CONFIG_TMS320C64XPLUS) += -march=c64x+
+	CPU_CFLAGS-$(ARCH_LITTLE_ENDIAN)+=-mlittle-endian
+	CPU_CFLAGS-$(ARCH_BIG_ENDIAN)+=-mbig-endian
+	CPU_LDFLAGS-y += $(CPU_CFLAGS)
+endif
+
 # Keep the check_gcc from being needlessly executed
 ifndef PIEFLAG
 export PIEFLAG:=$(call check_gcc,$(PIEFLAG_NAME),$(PICFLAG))
diff --git a/extra/Configs/Config.c6x b/extra/Configs/Config.c6x
new file mode 100644
index 0000000..d71df3f
--- /dev/null
+++ b/extra/Configs/Config.c6x
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see extra/config/Kconfig-language.txt
+#
+
+config TARGET_ARCH
+	default "c6x"
+
+config FORCE_OPTIONS_FOR_ARCH
+	bool
+	default y
+	select ARCH_ANY_ENDIAN
+
+config ARCH_CFLAGS
+	string
+
+config ARCH_LDFLAGS
+	string
+
+choice
+	prompt "Target Processor Type"
+	default CONFIG_GENERIC_C6X
+
+config CONFIG_GENERIC_C6X
+	bool "Generic C6X DSP"
+
+config CONFIG_TMS320C64X
+	bool "TMS320C64X"
+
+config CONFIG_TMS320C64XPLUS
+	bool "TMS320C64X+"
+
+endchoice
+
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index f152a96..8a1f6ea 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -114,6 +114,9 @@ config TARGET_x86_64
 config TARGET_xtensa
 	bool "xtensa"
 
+config TARGET_c6x
+	bool "c6x"
+
 endchoice
 
 
@@ -219,6 +222,10 @@ if TARGET_xtensa
 source "extra/Configs/Config.xtensa"
 endif
 
+if TARGET_c6x
+source "extra/Configs/Config.c6x"
+endif
+
 config TARGET_SUBARCH
 	string
 	default "e500" if CONFIG_E500
diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch
index 068bccc..5f7a2b0 100644
--- a/extra/Configs/Config.in.arch
+++ b/extra/Configs/Config.in.arch
@@ -17,6 +17,10 @@ config UCLIBC_FORMAT_FDPIC_ELF
 	bool "FDPIC ELF"
 	depends on !ARCH_USE_MMU && (TARGET_bfin || TARGET_frv)
 	select DOPIC
+config UCLIBC_FORMAT_DSBT_ELF
+	bool "DBST ELF"
+	depends on !ARCH_USE_MMU && TARGET_c6x
+	select DOPIC
 config UCLIBC_FORMAT_FLAT
 	bool "STATIC FLAT"
 	depends on !ARCH_USE_MMU
diff --git a/include/elf.h b/include/elf.h
index b86aa52..d71691e 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -268,6 +268,7 @@ typedef struct
 #define EM_ALTERA_NIOS2	113	/* Altera Nios II soft-core processor */
 #define EM_CRX		114		/* National Semiconductor CRX */
 #define EM_NUM		95
+#define EM_TI_C6000	140
 
 /* If it is necessary to assign new unofficial EM_* values, please pick large
    random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
@@ -3063,6 +3064,50 @@ typedef Elf32_Addr Elf32_Conflict;
 /* Keep this the last entry.  */
 #define R_XTENSA_NUM		50
 
+/* C6X specific relocs */
+#define R_C6000_NONE		0
+#define R_C6000_ABS32		1
+#define R_C6000_ABS16		2
+#define R_C6000_ABS8		3
+#define R_C6000_PCR_S21		4
+#define R_C6000_PCR_S12		5
+#define R_C6000_PCR_S10		6
+#define R_C6000_PCR_S7		7
+#define R_C6000_ABS_S16		8
+#define R_C6000_ABS_L16		9
+#define R_C6000_ABS_H16		10
+#define R_C6000_SBR_U15_B	11
+#define R_C6000_SBR_U15_H	12
+#define R_C6000_SBR_U15_W	13
+#define R_C6000_SBR_S16		14
+#define R_C6000_SBR_L16_B	15
+#define R_C6000_SBR_L16_H	16
+#define R_C6000_SBR_L16_W	17
+#define R_C6000_SBR_H16_B	18
+#define R_C6000_SBR_H16_H	19
+#define R_C6000_SBR_H16_W	20
+#define R_C6000_SBR_GOT_U15_W	21
+#define R_C6000_SBR_GOT_L16_W	22
+#define R_C6000_SBR_GOT_H16_W	23
+#define R_C6000_DSBT_INDEX	24
+#define R_C6000_PREL31		25
+#define R_C6000_COPY		26
+#define R_C6000_JUMP_SLOT	27
+#define R_C6000_SBR_GOT32	28
+#define R_C6000_PCR_H16		29
+#define R_C6000_PCR_L16		30
+#define R_C6000_ALIGN		253
+#define R_C6000_FPHEAD		254
+#define R_C6000_NOCMP		255
+
+/* C6x specific values for the Dyn d_tag field.  */
+#define DT_C6000_DSBT_BASE	(DT_LOPROC + 0)
+#define DT_C6000_DSBT_SIZE	(DT_LOPROC + 1)
+#define DT_C6000_PREEMPTMAP	(DT_LOPROC + 2)
+#define DT_C6000_DSBT_INDEX	(DT_LOPROC + 3)
+
+#define DT_C6000_NUM    4
+
 #ifdef	__cplusplus
 }
 #endif
diff --git a/ldso/ldso/c6x/dl-debug.h b/ldso/ldso/c6x/dl-debug.h
new file mode 100644
index 0000000..9c6edab
--- /dev/null
+++ b/ldso/ldso/c6x/dl-debug.h
@@ -0,0 +1,49 @@
+/* C6X DSBT ELF shared library loader suppport.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Contributed by Mark Salter <msalter at redhat.com>
+ *
+ * All rights reserved.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+static const char *_dl_reltypes_tab[] =
+{
+  	"R_C6000_NONE",			/* 0 */
+	"R_C6000_ABS32",
+	"R_C6000_ABS16",
+	"R_C6000_ABS8",
+	"R_C6000_PCR_S21",
+	"R_C6000_PCR_S12",		/* 5 */
+	"R_C6000_PCR_S10",
+	"R_C6000_PCR_S7",
+	"R_C6000_ABS_S16",
+	"R_C6000_ABS_L16",
+	"R_C6000_ABS_H16",		/* 10 */
+	"R_C6000_SBR_U15_B",
+	"R_C6000_SBR_U15_H",
+	"R_C6000_SBR_U15_W",
+	"R_C6000_SBR_S16",
+	"R_C6000_SBR_L16_B",		/* 15 */
+	"R_C6000_SBR_L16_H",
+	"R_C6000_SBR_L16_W",
+	"R_C6000_SBR_H16_B",
+	"R_C6000_SBR_H16_H",
+	"R_C6000_SBR_H16_W",		/* 20 */
+	"R_C6000_SBR_GOT_U15_W",
+	"R_C6000_SBR_GOT_L16_W",
+	"R_C6000_SBR_GOT_H16_W",
+	"R_C6000_DSBT_INDEX",
+	"R_C6000_PREL31",		/* 25 */
+	"R_C6000_COPY",
+	"R_C6000_JUMP_SLOT",
+	"R_C6000_SBR_GOT32",
+	"R_C6000_PCR_H16",
+	"R_C6000_PCR_L16",		/* 30 */
+#if 0
+	"R_C6000_ALIGN",		/* 253 */
+	"R_C6000_FPHEAD",		/* 254 */
+	"R_C6000_NOCMP",		/* 255 */
+#endif
+};
diff --git a/ldso/ldso/c6x/dl-inlines.h b/ldso/ldso/c6x/dl-inlines.h
new file mode 100644
index 0000000..d8fb42c
--- /dev/null
+++ b/ldso/ldso/c6x/dl-inlines.h
@@ -0,0 +1,91 @@
+/* Copyright (C) 2010 Texas Instruments Incorporated
+ * Contributed by Mark Salter <msalter at redhat.com>
+ *
+ * Borrowed heavily from frv arch:
+ * Copyright (C) 2003, 2004 Red Hat, Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* Figure out whether the given address is in one of the mapped
+   segments.  */
+static __always_inline int
+__dl_addr_in_loadaddr (void *p, struct elf32_dsbt_loadaddr loadaddr)
+{
+	struct elf32_dsbt_loadmap *map = loadaddr.map;
+	int c;
+
+	for (c = 0; c < map->nsegs; c++)
+		if ((void*)map->segs[c].addr <= p
+		    && (char*)p < (char*)map->segs[c].addr + map->segs[c].p_memsz)
+			return 1;
+
+	return 0;
+}
+
+/* Figure out how many LOAD segments there are in the given headers,
+   and allocate a block for the load map big enough for them.
+   got_value will be properly initialized later on, with INIT_GOT.  */
+static __always_inline int
+__dl_init_loadaddr (struct elf32_dsbt_loadaddr *loadaddr, Elf32_Phdr *ppnt,
+		    int pcnt)
+{
+	int count = 0, i;
+	size_t size;
+
+	for (i = 0; i < pcnt; i++)
+		if (ppnt[i].p_type == PT_LOAD)
+			count++;
+
+	size = sizeof (struct elf32_dsbt_loadmap)
+		+ sizeof (struct elf32_dsbt_loadseg) * count;
+	loadaddr->map = _dl_malloc (size);
+	if (! loadaddr->map)
+		_dl_exit (-1);
+
+	loadaddr->map->version = 0;
+	loadaddr->map->nsegs = 0;
+
+	return count;
+}
+
+/* Incrementally initialize a load map.  */
+static __always_inline void
+__dl_init_loadaddr_hdr (struct elf32_dsbt_loadaddr loadaddr, void *addr,
+			Elf32_Phdr *phdr, int maxsegs)
+{
+	struct elf32_dsbt_loadseg *segdata;
+
+	if (loadaddr.map->nsegs == maxsegs)
+		_dl_exit (-1);
+
+	segdata = &loadaddr.map->segs[loadaddr.map->nsegs++];
+	segdata->addr = (Elf32_Addr) addr;
+	segdata->p_vaddr = phdr->p_vaddr;
+	segdata->p_memsz = phdr->p_memsz;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	{
+		if (_dl_debug)
+			_dl_dprintf(_dl_debug_file, "%i: mapped %x at %x, size %x\n",
+				    loadaddr.map->nsegs-1,
+				    segdata->p_vaddr, segdata->addr, segdata->p_memsz);
+	}
+#endif
+}
+
+static __always_inline void
+__dl_loadaddr_unmap (struct elf32_dsbt_loadaddr loadaddr)
+{
+	int i;
+
+	for (i = 0; i < loadaddr.map->nsegs; i++)
+		_dl_munmap ((void*)loadaddr.map->segs[i].addr,
+			    loadaddr.map->segs[i].p_memsz);
+
+	/* _dl_unmap is only called for dlopen()ed libraries, for which
+	   calling free() is safe, or before we've completed the initial
+	   relocation, in which case calling free() is probably pointless,
+	   but still safe.  */
+	_dl_free (loadaddr.map);
+}
diff --git a/ldso/ldso/c6x/dl-startup.h b/ldso/ldso/c6x/dl-startup.h
new file mode 100644
index 0000000..b9ea304
--- /dev/null
+++ b/ldso/ldso/c6x/dl-startup.h
@@ -0,0 +1,122 @@
+/* Copyright (C) 2010 Texas Instruments Incorporated
+ * Contributed by Mark Salter <msalter at redhat.com>
+ *
+ * Borrowed heavily from frv arch:
+ * Copyright (C) 2003 Red Hat, Inc.
+ * 
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#undef DL_START
+#define DL_START(X)   \
+int  \
+_dl_start (unsigned placeholder, \
+	   struct elf32_dsbt_loadmap *dl_boot_progmap, \
+	   struct elf32_dsbt_loadmap *dl_boot_ldsomap, \
+	   Elf32_Dyn *dl_boot_ldso_dyn_pointer,	       \
+	   X)
+
+/*
+ * On entry, the kernel has set up the stack thusly:
+ *
+ *	0(sp)			pad0
+ *	4(sp)			pad1
+ *	8(sp)			argc
+ *	12(sp)			argv[0]
+ *	...
+ *	(4*(argc+3))(sp)	NULL
+ *	(4*(argc+4))(sp)	envp[0]
+ *	...
+ *				NULL
+ *
+ * Register values are unspecified, except:
+ *
+ *	B4  --> executable loadmap address
+ *	A6  --> interpreter loadmap address
+ *	B6  --> dynamic section address
+ *	B14 --> our DP setup by kernel
+ *
+ * NB: DSBT index is always 0 for the executable
+ *     and 1 for the interpreter
+ */
+
+__asm__("	.text\n"
+	".globl _start\n"
+	"_start:\n"
+	"          B .S2		_dl_start\n"
+	"          STW .D2T2		B14, *+B14[1]\n"
+	"          ADD .D1X		B15,8,A8\n"
+	"          ADDKPC .S2		ret_from_dl,B3,2\n"
+	"ret_from_dl:\n"
+	"	   B .S2X		A4\n"
+	" ||       LDW .D2T2		*+B14[0],B14\n"
+	" 	   ADDKPC .S2		__dl_fini,B0,0\n"
+	"          MV .S1X		B0,A4\n"
+	"	   NOP\n"
+	"	   NOP\n"
+	"	   NOP\n"
+	"__dl_fini:\n"
+	"          LDW .D2T2		*+B14[1],B14\n"
+	"	   NOP		4\n"
+	" 	   LDW .D2T1		*+B14($GOT(_dl_fini)), A0\n"
+	"          NOP		4\n"
+	"	   BNOP .S2X		A0, 5\n");
+
+__asm__("	.text\n"
+	"__c6x_cache_sync:\n"
+	"	   MVK .S2		330,B0\n"
+	"	   SWE\n"
+	"	   NOP\n"
+	"	   BNOP .S2		B3,5\n"
+	"	   NOP\n"
+	"	   NOP\n"
+	"	   NOP\n"
+	"	   NOP\n"
+	"\n"
+);
+
+/*
+ * Get a pointer to the argv array.  On many platforms this can be just
+ * the address of the first argument, on other platforms we need to
+ * do something a little more subtle here.
+ */
+#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS) + 1)
+
+struct elf32_dsbt_loadmap;
+
+/*
+ * Here is a macro to perform a relocation.  This is only used when
+ * bootstrapping the dynamic loader.  RELP is the relocation that we
+ * are performing, REL is the pointer to the address we are relocating.
+ * SYMBOL is the symbol involved in the relocation, and LOAD is the
+ * load address.
+ */
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
+	switch(ELF32_R_TYPE((RELP)->r_info)){				\
+	case R_C6000_ABS_L16:						\
+	    {								\
+		    unsigned int opcode = *(REL);			\
+		    unsigned int v = (SYMBOL) + (RELP)->r_addend;	\
+		    opcode &= ~0x7fff80;				\
+		    opcode |= ((v & 0xffff) << 7);			\
+		    *(REL) = opcode;					\
+	    }								\
+	    break;							\
+	case R_C6000_ABS_H16:						\
+	    {								\
+		    unsigned int opcode = *(REL);			\
+		    unsigned int v = (SYMBOL) + (RELP)->r_addend;	\
+		    opcode &= ~0x7fff80;				\
+		    opcode |= ((v >> 9) & 0x7fff80);			\
+		    *(REL) = opcode;					\
+	    }								\
+	    break;							\
+	case R_C6000_ABS32:						\
+	    *(REL) = (SYMBOL) + (RELP)->r_addend;			\
+	    break;							\
+	default:							\
+	  _dl_exit(1);							\
+	}
+
+extern void __c6x_cache_sync(unsigned long start, unsigned long end)
+  attribute_hidden;
diff --git a/ldso/ldso/c6x/dl-syscalls.h b/ldso/ldso/c6x/dl-syscalls.h
new file mode 100644
index 0000000..9ff3358
--- /dev/null
+++ b/ldso/ldso/c6x/dl-syscalls.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 2010 Texas Instruments Incorporated
+ * Contributed by Mark Salter <msalter at redhat.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* 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);}
+#include <sys/mman.h>
+
+#ifdef __NR_pread64
+#define __NR___syscall_pread __NR_pread64
+static __always_inline _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
+			size_t, count, off_t, offset_hi, off_t, offset_lo);
+
+static __always_inline ssize_t
+_dl_pread(int fd, void *buf, size_t count, off_t offset)
+{
+  return(__syscall_pread(fd,buf,count, offset, offset >> 31));
+}
+#endif
diff --git a/ldso/ldso/c6x/dl-sysdep.h b/ldso/ldso/c6x/dl-sysdep.h
new file mode 100644
index 0000000..8f1b122
--- /dev/null
+++ b/ldso/ldso/c6x/dl-sysdep.h
@@ -0,0 +1,209 @@
+/* Copyright (C) 2010 Texas Instruments Incorporated
+ * Contributed by Mark Salter <msalter at redhat.com>
+ *
+ * Borrowed heavily from frv arch:
+ * Copyright (C) 2003, 2004 Red Hat, Inc.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <bits/elf-dsbt.h>
+
+/*
+ * Define this if the system uses RELOCA.
+ */
+#define ELF_USES_RELOCA 1
+
+/* JMPREL relocs are inside the DT_RELA table.  */
+/* Actually looks like a linker bug sets DT_JMPREL anyway */
+#define ELF_MACHINE_PLTREL_OVERLAP 1
+
+#undef DL_NO_COPY_RELOCS
+
+#define HAVE_DL_INLINES_H
+
+
+/*
+ * Various assembly language/system dependent  hacks that are required
+ * so that we can minimize the amount of platform specific code.
+ */
+
+/* Initialization sequence for the GOT.  */
+#define INIT_GOT(GOT_BASE,MODULE) \
+{ \
+  GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \
+  GOT_BASE[1] = (unsigned long) MODULE; \
+}
+
+/* Here we define the magic numbers that this dynamic loader should accept */
+#define MAGIC1 EM_TI_C6000
+#undef  MAGIC2
+
+/* Used for error messages */
+#define ELF_TARGET "C6000"
+
+/* Need bootstrap relocations */
+#define ARCH_NEEDS_BOOTSTRAP_RELOCS
+
+struct elf_resolve;
+
+extern int _dl_linux_resolve(void) attribute_hidden;
+
+struct funcdesc_ht;
+struct elf32_dsbt_loadaddr;
+
+/* We must force strings used early in the bootstrap into the text
+   segment (const data), such that they are referenced relative to
+   the DP register rather than through the GOT which will not have
+   been relocated when these are used. */
+#undef SEND_EARLY_STDERR
+#define SEND_EARLY_STDERR(S) \
+  do { static char __s[] = (S); SEND_STDERR (__s); } while (0)
+
+#define DL_LOADADDR_TYPE struct elf32_dsbt_loadaddr
+
+#define DL_RELOC_ADDR(LOADADDR, ADDR) \
+  ((ElfW(Addr))__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
+
+#define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
+	do {						  		\
+	    struct elf32_dsbt_loadmap *map;				\
+	    map = dl_boot_ldsomap ?: dl_boot_progmap;			\
+	    if (map->version != 0) {			  		\
+	        SEND_EARLY_STDERR ("Invalid loadmap version number\n"); \
+                _dl_exit(-1);						\
+	    }								\
+	    if (map->nsegs < 2) {					\
+	        SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
+                _dl_exit(-1);						\
+	    }								\
+	    (LOADADDR).map = map;					\
+	} while(0)
+
+#define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
+	do {						  		\
+	    if (dl_boot_progmap->version != 0) {	  		\
+	        SEND_EARLY_STDERR ("Invalid loadmap version number\n"); \
+                _dl_exit(-1);						\
+	    }								\
+	    if (dl_boot_progmap->nsegs < 2) {				\
+	        SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
+                _dl_exit(-1);						\
+	    }								\
+	    (LOADADDR).map = dl_boot_progmap;				\
+	} while(0)
+
+#define DL_INIT_LOADADDR_EXTRA_DECLS \
+  int dl_init_loadaddr_load_count;
+
+#define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
+  (dl_init_loadaddr_load_count = \
+     __dl_init_loadaddr (&(LOADADDR), (PHDR), (PHDRCNT)))
+
+#define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
+  (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
+			   dl_init_loadaddr_load_count))
+
+#define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
+  (__dl_loadaddr_unmap ((LOADADDR)))
+
+#define DL_LIB_UNMAP(LIB, LEN) \
+  (__dl_loadaddr_unmap ((LIB)->loadaddr))
+
+#define DL_LOADADDR_BASE(LOADADDR) \
+  ((LOADADDR).map->dsbt_table)
+
+#define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
+  (! (TFROM) && __dl_addr_in_loadaddr ((void*)(ADDR), (TPNT)->loadaddr))
+
+
+/* We only support loading DSBT relocatable shared libraries.
+   It probably wouldn't be too hard to support loading statically
+   linked executables that require relocation.*/
+#define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
+do \
+{ \
+    (piclib) = 2; \
+} \
+while (0)
+
+/* We want want to apply all relocations in the interpreter during
+   bootstrap.  Because of this, we have to skip the interpreter
+   relocations in _dl_parse_relocation_information(), see
+   elfinterp.c.  */
+#define DL_SKIP_BOOTSTRAP_RELOC(SYMTAB, INDEX, STRTAB) 0
+
+#ifdef __NR_pread64
+#define _DL_PREAD(FD, BUF, SIZE, OFFSET) \
+  (_dl_pread((FD), (BUF), (SIZE), (OFFSET)))
+#endif
+
+#define DL_GET_READY_TO_RUN_EXTRA_PARMS \
+  , struct elf32_dsbt_loadmap *dl_boot_progmap \
+  , struct elf32_dsbt_loadmap *dl_boot_ldsomap
+#define DL_GET_READY_TO_RUN_EXTRA_ARGS \
+  , dl_boot_progmap \
+  , dl_boot_ldsomap
+
+
+/*
+ * Compute the GOT address.
+ * Also setup program and interpreter DSBT table entries.
+ */
+#define DL_BOOT_COMPUTE_GOT(GOT) \
+  do {								\
+    unsigned long *ldso_dsbt, *prog_dsbt;			\
+    ldso_dsbt = dl_boot_ldsomap->dsbt_table;			\
+    prog_dsbt = dl_boot_progmap->dsbt_table;			\
+    ldso_dsbt[0] = prog_dsbt[0] = (unsigned long)prog_dsbt;	\
+    ldso_dsbt[1] = prog_dsbt[1] = (unsigned long)ldso_dsbt;	\
+    (GOT) = ldso_dsbt + dl_boot_ldsomap->dsbt_size;		\
+  } while(0)
+
+#define DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr) \
+  ((dpnt) = dl_boot_ldso_dyn_pointer)
+
+
+#ifdef __USE_GNU
+# include <link.h>
+#else
+# define __USE_GNU
+# include <link.h>
+# undef __USE_GNU
+#endif
+
+static __always_inline Elf32_Addr
+elf_machine_load_address (void)
+{
+	/* this is never an issue on DSBT systems */
+	return 0;
+}
+
+static __always_inline void
+elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
+		      Elf32_Word relative_count)
+{
+}
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
+   PLT entries should not be allowed to define the value.
+   ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+   of the main executable's symbols, as for a COPY reloc.  */
+#define elf_machine_type_class(type) \
+  ((((type) == R_C6000_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT)	\
+   | (((type) == R_C6000_COPY) * ELF_RTYPE_CLASS_COPY))
+
+#define ARCH_NUM 3
+#define DT_DSBT_BASE_IDX	(DT_NUM + OS_NUM)
+#define DT_DSBT_SIZE_IDX	(DT_NUM + OS_NUM + 1)
+#define DT_DSBT_INDEX_IDX	(DT_NUM + OS_NUM + 2)
+
+#define ARCH_DYNAMIC_INFO(dpnt,  dynamic, debug_addr) \
+do { \
+if (dpnt->d_tag == DT_C6000_DSBT_BASE) \
+     dynamic[DT_DSBT_BASE_IDX] = dpnt->d_un.d_val; \
+else if (dpnt->d_tag == DT_C6000_DSBT_SIZE) \
+     dynamic[DT_DSBT_SIZE_IDX] = dpnt->d_un.d_val; \
+else if (dpnt->d_tag == DT_C6000_DSBT_INDEX) \
+     dynamic[DT_DSBT_INDEX_IDX] = dpnt->d_un.d_val; \
+} while (0)
diff --git a/ldso/ldso/c6x/elfinterp.c b/ldso/ldso/c6x/elfinterp.c
new file mode 100644
index 0000000..7c79171
--- /dev/null
+++ b/ldso/ldso/c6x/elfinterp.c
@@ -0,0 +1,296 @@
+/* TI C64X DSBT ELF shared library loader suppport
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Contributed by Mark Salter <msalter at redhat.com>
+ *
+ * Borrowed heavily from frv arch:
+ * Copyright (C) 2003, 2004 Red Hat, Inc.
+ * Contributed by Alexandre Oliva <aoliva at redhat.com>
+ * Lots of code copied from ../i386/elfinterp.c, so:
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
+ *               David Engel, Hongjiu Lu and Mitch D'Souza
+ * Copyright (C) 2001-2002, Erik Andersen
+ * All rights reserved.
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+
+/* Program to load an ELF binary on a linux system, and run it.
+   References to symbols in sharable libraries can be resolved by either
+   an ELF sharable library or a linux style of shared library. */
+
+/* Disclaimer:  I have never seen any AT&T source code for SVr4, nor have
+   I ever taken any courses on internals.  This program was developed using
+   information available through the book "UNIX SYSTEM V RELEASE 4,
+   Programmers guide: Ansi C and Programming Support Tools", which did
+   a more than adequate job of explaining everything required to get this
+   working. */
+
+extern void __c6x_cache_sync(unsigned long start, unsigned long end)
+    attribute_hidden;
+
+static void
+_dl_c6x_flush_relocs(struct elf32_dsbt_loadmap *map)
+{
+	unsigned long s, e;
+	s = map->segs[0].addr;
+	e = s + map->segs[0].p_memsz;
+	__c6x_cache_sync(s, e);
+	s = map->segs[1].addr;
+	e = s + map->segs[1].p_memsz;
+	__c6x_cache_sync(s, e);
+}
+
+
+attribute_hidden
+char *
+_dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
+{
+	ELF_RELOC *this_reloc;
+	char *strtab;
+	ElfW(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 *)(intptr_t)(rel_addr + reloc_entry);
+	symtab_index = ELF_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;
+
+	/* Address of GOT entry fix up */
+	got_addr = (char **) DL_RELOC_ADDR(tpnt->loadaddr, this_reloc->r_offset);
+
+	/* Get the address to be used to fill in the GOT entry.  */
+	new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt,
+				 ELF_RTYPE_CLASS_PLT, NULL);
+	if (unlikely(!new_addr)) {
+		_dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
+		_dl_exit(1);
+	}
+
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if (_dl_debug_bindings) {
+		_dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
+		if (_dl_debug_detail)
+			_dl_dprintf(_dl_debug_file,
+				    "\n\tpatched %x ==> %x @ %x\n",
+				    *got_addr, new_addr, got_addr);
+	}
+	if (!_dl_debug_nofixups) {
+		*got_addr = new_addr;
+	}
+#else
+	*got_addr = new_addr;
+#endif
+
+	return new_addr;
+}
+
+static int
+_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
+	  unsigned long rel_addr, unsigned long rel_size,
+	  int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
+			    ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
+{
+	unsigned int i;
+	char *strtab;
+	Elf32_Sym *symtab;
+	ELF_RELOC *rpnt;
+	int symtab_index;
+
+	/* Now parse the relocation information */
+	rpnt = (ELF_RELOC *)rel_addr;
+	rel_size = rel_size / sizeof(ELF_RELOC);
+
+	symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
+	strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
+
+	for (i = 0; i < rel_size; i++, rpnt++) {
+	        int res;
+
+		symtab_index = ELF32_R_SYM(rpnt->r_info);
+		debug_sym(symtab,strtab,symtab_index);
+		debug_reloc(symtab,strtab,rpnt);
+
+		res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
+
+		if (res==0) continue;
+
+		_dl_dprintf(2, "\n%s: ",_dl_progname);
+
+		if (symtab_index)
+			_dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
+
+		if (res <0) {
+		        int reloc_type = ELF32_R_TYPE(rpnt->r_info);
+#if defined (__SUPPORT_LD_DEBUG__)
+			_dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
+#else
+			_dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
+#endif
+			_dl_exit(-res);
+		} else if (res >0) {
+			_dl_dprintf(2, "can't resolve symbol\n");
+			return res;
+		}
+	}
+	_dl_c6x_flush_relocs(tpnt->loadaddr.map);
+	return 0;
+}
+
+static int
+_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
+	      ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
+{
+	int reloc_type;
+	int symtab_index;
+	char *symname;
+	unsigned long *reloc_addr;
+	unsigned long symbol_addr, sym_val;
+	long reloc_addend;
+	unsigned long old_val, new_val;
+
+	reloc_addr = (unsigned long *)(intptr_t)
+		DL_RELOC_ADDR (tpnt->loadaddr, rpnt->r_offset);
+
+	reloc_type   = ELF32_R_TYPE(rpnt->r_info);
+	reloc_addend = rpnt->r_addend;
+	symtab_index = ELF32_R_SYM(rpnt->r_info);
+	symbol_addr  = 0;
+	symname      = strtab + symtab[symtab_index].st_name;
+
+	if (ELF32_ST_BIND (symtab[symtab_index].st_info) == STB_LOCAL) {
+		symbol_addr = (unsigned long)
+			DL_RELOC_ADDR (tpnt->loadaddr, symtab[symtab_index].st_value);
+	} else {
+		symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name,
+							    scope, tpnt, elf_machine_type_class(reloc_type),
+							    NULL);
+		/*
+		 * We want to allow undefined references to weak symbols - this might
+		 * have been intentional.  We should not be linking local symbols
+		 * here, so all bases should be covered.
+		 */
+
+		if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
+			_dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
+				     _dl_progname, strtab + symtab[symtab_index].st_name);
+			_dl_exit (1);
+		}
+	}
+	old_val = *reloc_addr;
+	sym_val = symbol_addr + reloc_addend;
+
+	switch (reloc_type) {
+	case R_C6000_NONE:
+		break;
+	case R_C6000_ABS32:
+	case R_C6000_JUMP_SLOT:
+		new_val = sym_val;
+		*reloc_addr = sym_val;
+		break;
+	case R_C6000_ABS_L16:
+		new_val = (old_val & ~0x007fff80) | ((sym_val & 0xffff) << 7);
+		*reloc_addr = new_val;
+		break;
+	case R_C6000_ABS_H16:
+		new_val = (old_val & ~0x007fff80) | ((sym_val >> 9) & 0x007fff80);
+		*reloc_addr = new_val;
+		break;
+	case R_C6000_PCR_S21:
+		new_val = sym_val - (((unsigned long)reloc_addr) & ~31);
+		*reloc_addr = (old_val & ~0x0fffff80) | (((new_val >> 2) & 0x1fffff) << 7);
+		break;
+	case R_C6000_COPY:
+		if (symbol_addr) {
+#if defined (__SUPPORT_LD_DEBUG__)
+			if (_dl_debug_move)
+				_dl_dprintf(_dl_debug_file,
+					    "\n%s move %d bytes from %x to %x",
+					    symname, symtab[symtab_index].st_size,
+					    symbol_addr, reloc_addr);
+#endif
+			
+			_dl_memcpy((char *)reloc_addr,
+				   (char *)symbol_addr,
+				   symtab[symtab_index].st_size);
+		}
+		break;
+	default:
+		return -1; /*call _dl_exit(1) */
+	}
+#if defined (__SUPPORT_LD_DEBUG__)
+	if (_dl_debug_reloc && _dl_debug_detail && reloc_type != R_C6000_NONE) {
+		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", old_val, new_val, reloc_addr);
+	}
+#endif
+	return 0;
+}
+
+static int
+_dl_do_lazy_reloc (struct elf_resolve *tpnt,
+		   struct dyn_elf *scope attribute_unused,
+		   ELF_RELOC *rpnt, ElfW(Sym) *symtab attribute_unused,
+		   char *strtab attribute_unused)
+{
+	int reloc_type;
+	unsigned long *reloc_addr;
+	unsigned long old_val;
+
+	reloc_addr = (unsigned long *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset);
+	reloc_type = ELF_R_TYPE(rpnt->r_info);
+
+	old_val = *reloc_addr;
+
+	switch (reloc_type) {
+		case R_C6000_NONE:
+			break;
+		case R_C6000_JUMP_SLOT:
+			*reloc_addr = DL_RELOC_ADDR(tpnt->loadaddr, old_val);
+			break;
+		default:
+			return -1;
+	}
+
+#if defined (__SUPPORT_LD_DEBUG__)
+	if (_dl_debug_reloc && _dl_debug_detail)
+		_dl_dprintf(_dl_debug_file, "\n\tpatched: %x ==> %x @ %x\n",
+			    old_val, *reloc_addr, reloc_addr);
+#endif
+
+	return 0;
+}
+
+void
+_dl_parse_lazy_relocation_information
+(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size)
+{
+	_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc);
+}
+
+int
+_dl_parse_relocation_information
+(struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size)
+{
+	return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+}
+
+/* We don't have copy relocs.  */
+int
+_dl_parse_copy_information
+(struct dyn_elf *rpnt,
+ unsigned long rel_addr,
+ unsigned long rel_size)
+{
+	return 0;
+}
+
diff --git a/ldso/ldso/c6x/resolve.S b/ldso/ldso/c6x/resolve.S
new file mode 100644
index 0000000..ce3cbe7
--- /dev/null
+++ b/ldso/ldso/c6x/resolve.S
@@ -0,0 +1,68 @@
+;;
+;;  Copyright (C) 2010 Texas Instruments Incorporated
+;;  Mark Salter <msalter at redhat.com>
+;;
+;;  Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+;;
+
+;;      The function below is tail-called by resolver stubs when a
+;; 	lazily-bound function is called.  It must preserve all
+;; 	registers that could be used to pass arguments to the actual
+;; 	function.
+
+;; 	_dl_linux_resolver() figures out where the jump symbol is
+;; 	_really_ supposed to have jumped to and returns that to us.
+;; 	Once we have that, we prepare to tail-call the actual
+;; 	function, clean up after ourselves, restoring the original
+;; 	arguments, then jump to the fixed up address.  */
+
+; resolver stub - called from PLT to resolve target address and update GOT
+;
+;   B0        : reloc offset (bytes from DT_RELPLT)
+;   B1        : module pointer, loaded from GOT[1]
+;   DP        : caller's DP
+;   A4,B4, etc: callee's arguments
+;   B3        : return address
+
+	.text
+	.align 5
+	.global	_dl_linux_resolve
+_dl_linux_resolve:
+	stw .d2t2	B14, *B15--[2]
+	stdw .d2t1	A15:A14, *B15--
+	stdw .d2t2	B13:B12, *B15--
+	stdw .d2t1	A13:A12, *B15--
+	stdw .d2t2	B11:B10, *B15--
+	stdw .d2t1	A11:A10, *B15--
+	stdw .d2t2	B9:B8, *B15--
+	stdw .d2t1	A9:A8, *B15--
+	stdw .d2t2	B7:B6, *B15--
+	stdw .d2t1	A7:A6, *B15--
+	stdw .d2t2	B5:B4, *B15--
+	stdw .d2t1	A5:A4, *B15--
+	stdw .d2t2	B3:B2, *B15--
+	stdw .d2t1	A3:A2, *B15--
+
+	; call lookup routine
+	MV .S1X		B1, A4		; arg 1: module id
+||	MV .S2		B0,B4		; arg 2: reloc offset
+	CALLP .S2	_dl_linux_resolver, B3	; returns &f in A4
+	MV .S2X		A4,B0            ; &f
+
+	lddw .d2t1	*++B15, A3:A2
+	lddw .d2t2	*++B15, B3:B2
+	lddw .d2t1	*++B15, A5:A4
+	lddw .d2t2	*++B15, B5:B4
+	lddw .d2t1	*++B15, A7:A6
+	lddw .d2t2	*++B15, B7:B6
+	lddw .d2t1	*++B15, A9:A8
+	lddw .d2t2	*++B15, B9:B8
+	lddw .d2t1	*++B15, A11:A10
+	lddw .d2t2	*++B15, B11:B10
+	lddw .d2t1	*++B15, A13:A12
+	lddw .d2t2	*++B15, B13:B12
+	lddw .d2t1	*++B15, A15:A14
+	ldw .d2t2	*++B15[2], B14
+
+	B .S2		B0               ; tail-call f
+	NOP		5
diff --git a/libc/sysdeps/linux/c6x/Makefile b/libc/sysdeps/linux/c6x/Makefile
new file mode 100644
index 0000000..633c91f
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2005 Erik Andersen <andersen at uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../
+top_builddir=../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libc/sysdeps/linux/c6x/Makefile.arch b/libc/sysdeps/linux/c6x/Makefile.arch
new file mode 100644
index 0000000..3e8dace
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/Makefile.arch
@@ -0,0 +1,15 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2005 Erik Andersen <andersen at uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+CSRC := brk.c pread_write.c syscall.c prctl.c
+#CSRC :=
+
+SSRC := __longjmp.S bsd-_setjmp.S bsd-setjmp.S clone.S setjmp.S _vfork.S
+#SSRC :=
+
+# libc-nonshared-y += $(ARCH_OUT)/_syscall.os
+
diff --git a/libc/sysdeps/linux/c6x/__longjmp.S b/libc/sysdeps/linux/c6x/__longjmp.S
new file mode 100644
index 0000000..b9d9f9d
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/__longjmp.S
@@ -0,0 +1,47 @@
+ ;
+ ; Port of uClibc for TMS320C6000 DSP architecture
+ ; Copyright (C) 2004 Texas Instruments Incorporated
+ ; Author of TMS320C6000 port: Aurelien Jacquiot
+ ;
+ ; This program is free software; you can redistribute it and/or modify it
+ ; under the terms of the GNU Library General Public License as published by
+ ; the Free Software Foundation; either version 2 of the License, or (at your
+ ; option) any later version.
+ ;
+ ; This program 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 Library General Public License
+ ; for more details.
+ ;
+ ; You should have received a copy of the GNU Library General Public License
+ ; along with this program; if not, write to the Free Software Foundation,
+ ; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ;
+
+	.global __longjmp
+
+__longjmp:
+	LDW .D1T1    *+A4(48),A3	; return address
+	MV .D2X     A4,B6		; jmp_buf pointer
+||	MV .D1     A4,A6
+||	MV .S2     B4,B2		; val
+
+	LDW .D1T1    *+A6(0),A10
+||	LDW .D2T2    *+B6(4),B10
+|| [B2]	MV .S1X     B4,A4
+||[!B2]	MVK .L1    1,A4			;  return val or 1
+
+	LDW .D1T1    *+A6(8),A11
+||	LDW .D2T2    *+B6(12),B11
+	LDW .D1T1    *+A6(16),A12
+||	LDW .D2T2    *+B6(20),B12
+	LDW .D1T1    *+A6(24),A13
+||	LDW .D2T2    *+B6(28),B13
+	LDW .D1T1    *+A6(32),A14
+||	LDW .D2T2    *+B6(36),B14
+	LDW .D1T1    *+A6(40),A15
+||	LDW .D2T2    *+B6(44),B15
+||	B .S2X	A3
+	NOP    5
+
+libc_hidden_def(__longjmp)
diff --git a/libc/sysdeps/linux/c6x/_vfork.S b/libc/sysdeps/linux/c6x/_vfork.S
new file mode 100644
index 0000000..20cb6a5
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/_vfork.S
@@ -0,0 +1,55 @@
+ ;
+ ; Port of uClibc for TMS320C6000 DSP architecture
+ ; Copyright (C) 2004 Texas Instruments Incorporated
+ ; Author of TMS320C6000 port: Aurelien Jacquiot
+ ;
+ ; This program is free software; you can redistribute it and/or modify it
+ ; under the terms of the GNU Library General Public License as published by
+ ; the Free Software Foundation; either version 2 of the License, or (at your
+ ; option) any later version.
+ ;
+ ; This program 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 Library General Public License
+ ; for more details.
+ ;
+ ; You should have received a copy of the GNU Library General Public License
+ ; along with this program; if not, write to the Free Software Foundation,
+ ; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ;
+
+;	.import __errno_location
+	.global __vfork
+
+__vfork:
+	MVK .S2	190,B0          ; __NR_vfork
+#ifndef	_TMS320C6400_PLUS
+	MVC .S2     CSR,B2
+	CLR .S2     B2,0,0,B1
+	MVC .S2     B1,CSR
+	MVC .S2     IFR,B1
+	SET .S2     B1,6,6,B1
+	MVC .S2     B1,ISR
+	MVC .S2     B2,CSR
+	NOP
+#else
+	SWE
+#endif
+
+	MVK .S2	-4096,B4
+	CMPGTU .L2X	B4,A4,B2	; check error
+ [B2]	BNOP .S2	B3,5
+
+	NEG .S1	A4,A4
+	STW .D2T1	A4,*B15--[2]
+	STW .D2T2	B3,*+B15[1]
+	CALLP .S2	__errno_location,B3
+	LDW .D2T2	*+B15[1],B3
+	LDW .D2T1	*++B15[2],A5
+	NOP	3
+	BNOP .S2	B3,3
+	STW .D1T1	A5,*A4
+	MVK .L1	-1,A4
+
+weak_alias(__vfork,vfork)
+libc_hidden_weak(vfork)
diff --git a/libc/sysdeps/linux/c6x/bits/byteswap.h b/libc/sysdeps/linux/c6x/bits/byteswap.h
new file mode 100644
index 0000000..eff26d5
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/byteswap.h
@@ -0,0 +1,35 @@
+/*
+ * Port of uClibc for TMS320C6000 DSP architecture
+ * Copyright (C) 2004 Texas Instruments Incorporated
+ * Author of TMS320C6000 port: Aurelien Jacquiot
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 Library General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _ASM_BITS_BYTESWAP_H
+#define _ASM_BITS_BYTESWAP_H 1
+
+#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
+# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
+#endif
+
+#ifdef __GNUC__
+#define __bswap_non_constant_32(x) __builtin_bswap32(x)
+#endif
+
+#include <bits/byteswap-common.h>
+
+#endif
diff --git a/libc/sysdeps/linux/c6x/bits/elf-dsbt.h b/libc/sysdeps/linux/c6x/bits/elf-dsbt.h
new file mode 100644
index 0000000..ff8b24b
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/elf-dsbt.h
@@ -0,0 +1,123 @@
+/* Copyright (C) 2010 Texas Instruments Incorporated
+
+Borrowed heavily from frv arch:
+Copyright 2003, 2004 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.
+
+In addition to the permissions in the GNU Lesser General Public
+License, the Free Software Foundation gives you unlimited
+permission to link the compiled version of this file with other
+programs, and to distribute those programs without any restriction
+coming from the use of this file.  (The GNU Lesser General Public
+License restrictions do apply in other respects; for example, they
+cover modification of the file, and distribution when not linked
+into another program.)
+
+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
+Library 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; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef _BITS_ELF_DSBT_H
+#define _BITS_ELF_DSBT_H
+
+/* These data structures are described in the DSBT ABI.
+   The kernel passes a process a memory map of logical
+   load segments. For PIC code to work, all code segments
+   must be combined into a single mapping while maintaining
+   their relationship to one another. The same is true for
+   RW data segments.
+
+   Furthermore, 
+   segment there is an elf32_dsbt_loadseg entry.  A pointer to an
+   elf32_dsbt_loadmap is passed in GR8 at start-up, and a pointer to
+   an additional such map is passed in GR9 for the interpreter, when
+   there is one.  */
+
+#include <elf.h>
+
+/* This data structure represents a PT_LOAD segment.  */
+struct elf32_dsbt_loadseg
+{
+	/* Core address to which the segment is mapped.  */
+	Elf32_Addr addr;
+	/* VMA recorded in the program header.  */
+	Elf32_Addr p_vaddr;
+	/* Size of this segment in memory.  */
+	Elf32_Word p_memsz;
+};
+
+struct elf32_dsbt_loadmap {
+	/* Protocol version number, must be zero.  */
+	Elf32_Word version;
+
+	/* Pointer to DSBT */
+	unsigned   *dsbt_table;
+	unsigned   dsbt_size;
+	unsigned   dsbt_index;
+
+	/* number of segments */
+	Elf32_Word nsegs;
+
+	/* The actual memory map.  */
+	struct elf32_dsbt_loadseg segs[0];
+};
+
+struct elf32_dsbt_loadaddr {
+  struct elf32_dsbt_loadmap *map;
+};
+
+
+/* Map a pointer's VMA to its corresponding address according to the
+   load map.  */
+static __always_inline void *
+__reloc_pointer (void *p,
+		 const struct elf32_dsbt_loadmap *map)
+{
+  int c;
+
+#if 0
+  if (map->version != 0)
+    /* Crash.  */
+    ((void(*)())0)();
+#endif
+
+  /* No special provision is made for NULL.  We don't want NULL
+     addresses to go through relocation, so they shouldn't be in
+     .rofixup sections, and, if they're present in dynamic
+     relocations, they shall be mapped to the NULL address without
+     undergoing relocations.  */
+
+  for (c = 0; c < map->nsegs; c++)
+    {
+      unsigned long offset = p - (void*)map->segs[c].p_vaddr;
+      /* We only check for one-past-the-end for the second segment,
+	 assumed to be the data segment, because other cases are
+	 ambiguous in the absence of padding between segments, and
+	 rofixup already serves as padding between text and data.
+	 Unfortunately, unless we special-case the second segment,
+	 we fail to relocate the _end symbol.  */
+      if (offset < map->segs[c].p_memsz
+	  || (offset == map->segs[c].p_memsz && c == 1))
+	return (char*)map->segs[c].addr + offset;
+    }
+
+  /* We might want to crash instead.  */
+  return (void*)-1;
+}
+
+# define __RELOC_POINTER(ptr, loadaddr) \
+  (__reloc_pointer ((void*)(ptr), \
+		    (loadaddr).map))
+
+#endif /* _BITS_ELF_DSBT_H */
diff --git a/libc/sysdeps/linux/c6x/bits/endian.h b/libc/sysdeps/linux/c6x/bits/endian.h
new file mode 100644
index 0000000..7297f9e
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/endian.h
@@ -0,0 +1,11 @@
+/* c6x is little-endian by default.  */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#ifdef _BIG_ENDIAN
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
diff --git a/libc/sysdeps/linux/c6x/bits/fcntl.h b/libc/sysdeps/linux/c6x/bits/fcntl.h
new file mode 100644
index 0000000..6c0d564
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/fcntl.h
@@ -0,0 +1,235 @@
+/* O_*, F_*, FD_* bit values for Linux.
+   Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef	_FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+
+#include <sys/types.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	   0003
+#define O_RDONLY	     00
+#define O_WRONLY	     01
+#define O_RDWR		     02
+#define O_CREAT		   0100	/* not fcntl */
+#define O_EXCL		   0200	/* not fcntl */
+#define O_NOCTTY	   0400	/* not fcntl */
+#define O_TRUNC		  01000	/* not fcntl */
+#define O_APPEND	  02000
+#define O_NONBLOCK	  04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		 010000
+#define O_FSYNC		 O_SYNC
+#define O_ASYNC		 020000
+#define O_DIRECT	 040000
+
+#ifdef __USE_GNU
+# define O_LARGEFILE	0100000
+# define O_DIRECTORY	0200000	/* Must be a directory.	 */
+# define O_NOFOLLOW	0400000	/* don't follow links */
+# define O_NOATIME      01000000
+# define O_CLOEXEC	02000000/* set close on exec */
+#endif
+
+/* For now Linux has synchronisity options for data and read operations.
+   We define the symbols here but let them do the same as O_SYNC since
+   this is a superset.	*/
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC	O_SYNC	/* Synchronize data.  */
+# define O_RSYNC	O_SYNC	/* Synchronize read operations.	 */
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define O_LARGEFILE	0100000
+#endif
+
+/* Values for the second argument to `fcntl'.  */
+#define F_DUPFD		0	/* Duplicate file descriptor.  */
+#define F_GETFD		1	/* Get file descriptor flags.  */
+#define F_SETFD		2	/* Set file descriptor flags.  */
+#define F_GETFL		3	/* Get file status flags.  */
+#define F_SETFL		4	/* Set file status flags.  */
+#ifndef __USE_FILE_OFFSET64
+# define F_GETLK	5	/* Get record locking info.  */
+# define F_SETLK	6	/* Set record locking info (non-blocking).  */
+# define F_SETLKW	7	/* Set record locking info (blocking).	*/
+#else
+# define F_GETLK	F_GETLK64  /* Get record locking info.	*/
+# define F_SETLK	F_SETLK64  /* Set record locking info (non-blocking).*/
+# define F_SETLKW	F_SETLKW64 /* Set record locking info (blocking).  */
+#endif
+#define F_GETLK64	12	/* Get record locking info.  */
+#define F_SETLK64	13	/* Set record locking info (non-blocking).  */
+#define F_SETLKW64	14	/* Set record locking info (blocking).	*/
+
+#if defined __USE_BSD || defined __USE_XOPEN2K
+# define F_SETOWN	8	/* Get owner of socket (receiver of SIGIO).  */
+# define F_GETOWN	9	/* Set owner of socket (receiver of SIGIO).  */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETSIG	10	/* Set number of signal to be sent.  */
+# define F_GETSIG	11	/* Get number of signal to be sent.  */
+#endif
+
+#ifdef __USE_GNU
+# define F_SETLEASE	1024	/* Set a lease.	 */
+# define F_GETLEASE	1025	/* Enquire what lease is active.  */
+# define F_NOTIFY	1026	/* Request notfications on a directory.	 */
+#endif
+
+/* For F_[GET|SET]FL.  */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
+#define F_RDLCK		0	/* Read lock.  */
+#define F_WRLCK		1	/* Write lock.	*/
+#define F_UNLCK		2	/* Remove lock.	 */
+
+/* For old implementation of bsd flock().  */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+#ifdef __USE_BSD
+/* Operations for bsd flock(), also used by the kernel implementation.	*/
+# define LOCK_SH	1	/* shared lock */
+# define LOCK_EX	2	/* exclusive lock */
+# define LOCK_NB	4	/* or'd with one of the above to prevent
+				   blocking */
+# define LOCK_UN	8	/* remove lock */
+#endif
+
+#ifdef __USE_GNU
+# define LOCK_MAND	32	/* This is a mandatory flock:	*/
+# define LOCK_READ	64	/* ... which allows concurrent read operations.	 */
+# define LOCK_WRITE	128	/* ... which allows concurrent write operations.  */
+# define LOCK_RW	192	/* ... Which allows concurrent read & write operations.	 */
+#endif
+
+#ifdef __USE_GNU
+/* Types of directory notifications that may be requested with F_NOTIFY.  */
+# define DN_ACCESS	0x00000001	/* File accessed.  */
+# define DN_MODIFY	0x00000002	/* File modified.  */
+# define DN_CREATE	0x00000004	/* File created.  */
+# define DN_DELETE	0x00000008	/* File removed.  */
+# define DN_RENAME	0x00000010	/* File renamed.  */
+# define DN_ATTRIB	0x00000020	/* File changed attibutes.  */
+# define DN_MULTISHOT	0x80000000	/* Don't remove notifier.  */
+#endif
+
+struct flock
+  {
+    short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.	*/
+    short int l_whence;	/* Where `l_start' is relative to (like `lseek').  */
+#ifndef __USE_FILE_OFFSET64
+    __off_t l_start;	/* Offset where the lock begins.  */
+    __off_t l_len;	/* Size of the locked area; zero means until EOF.  */
+#else
+    __off64_t l_start;	/* Offset where the lock begins.  */
+    __off64_t l_len;	/* Size of the locked area; zero means until EOF.  */
+#endif
+    __pid_t l_pid;	/* Process holding the lock.  */
+  };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+  {
+    short int l_type;	/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.	*/
+    short int l_whence;	/* Where `l_start' is relative to (like `lseek').  */
+    __off64_t l_start;	/* Offset where the lock begins.  */
+    __off64_t l_len;	/* Size of the locked area; zero means until EOF.  */
+    __pid_t l_pid;	/* Process holding the lock.  */
+  };
+#endif
+
+/* Define some more compatibility macros to be backward compatible with
+   BSD systems which did not managed to hide these kernel macros.  */
+#ifdef	__USE_BSD
+# define FAPPEND	O_APPEND
+# define FFSYNC		O_FSYNC
+# define FASYNC		O_ASYNC
+# define FNONBLOCK	O_NONBLOCK
+# define FNDELAY	O_NDELAY
+#endif /* Use BSD.  */
+
+/* Advise to `posix_fadvise'.  */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL	0 /* No further special treatment.  */
+# define POSIX_FADV_RANDOM	1 /* Expect random page references.  */
+# define POSIX_FADV_SEQUENTIAL	2 /* Expect sequential page references.	 */
+# define POSIX_FADV_WILLNEED	3 /* Will need these pages.  */
+# define POSIX_FADV_DONTNEED	4 /* Don't need these pages.  */
+# define POSIX_FADV_NOREUSE	5 /* Data will be accessed once.  */
+#endif
+
+#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__
+/* Flags for SYNC_FILE_RANGE.  */
+# define SYNC_FILE_RANGE_WAIT_BEFORE	1 /* Wait upon writeout of all pages
+					     in the range before performing the
+					     write.  */
+# define SYNC_FILE_RANGE_WRITE		2 /* Initiate writeout of all those
+					     dirty pages in the range which are
+					     not presently under writeback.  */
+# define SYNC_FILE_RANGE_WAIT_AFTER	4 /* Wait upon writeout of all pages in
+					     the range after performing the
+					     write.  */
+
+/* Flags for SPLICE and VMSPLICE.  */
+# define SPLICE_F_MOVE		1	/* Move pages instead of copying.  */
+# define SPLICE_F_NONBLOCK	2	/* Don't block on the pipe splicing
+					   (but we may still block on the fd
+					   we splice from/to).  */
+# define SPLICE_F_MORE		4	/* Expect more data.  */
+# define SPLICE_F_GIFT		8	/* Pages passed in are a gift.  */
+#endif
+
+__BEGIN_DECLS
+
+#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__
+
+/* Provide kernel hint to read ahead.  */
+extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+    __THROW;
+
+
+/* Selective file content synch'ing.  */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+			    unsigned int __flags);
+
+/* Splice address range into a pipe.  */
+extern ssize_t vmsplice (int __fdout, const struct iovec *__iov,
+			 size_t __count, unsigned int __flags);
+
+/* Splice two files together.  */
+extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout,
+		       __off64_t *__offout, size_t __len,
+		       unsigned int __flags);
+
+/* In-kernel implementation of tee for pipe buffers.  */
+extern ssize_t tee (int __fdin, int __fdout, size_t __len,
+		    unsigned int __flags);
+
+#endif
+__END_DECLS
diff --git a/libc/sysdeps/linux/c6x/bits/kernel_stat.h b/libc/sysdeps/linux/c6x/bits/kernel_stat.h
new file mode 100644
index 0000000..9c0bfa6
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/kernel_stat.h
@@ -0,0 +1,52 @@
+#ifndef _BITS_STAT_STRUCT_H
+#define _BITS_STAT_STRUCT_H
+
+/* This file provides whatever this particular arch's kernel thinks
+ * struct kernel_stat should look like...  It turns out each arch has a
+ * different opinion on the subject... */
+
+struct kernel_stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+struct kernel_stat64 {
+	unsigned char	__pad0[6];
+	unsigned short	st_dev;
+	unsigned char	__pad1[2];
+#define _HAVE_STAT64___ST_INO
+	unsigned long	__st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+	unsigned char	__pad2[6];
+	unsigned short	st_rdev;
+	unsigned char	__pad3[2];
+	__off64_t	st_size;
+	unsigned long	st_blksize;
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	__off64_t	st_ino;
+};
+
+#endif	/*  _BITS_STAT_STRUCT_H */
+
diff --git a/libc/sysdeps/linux/c6x/bits/kernel_types.h b/libc/sysdeps/linux/c6x/bits/kernel_types.h
new file mode 100644
index 0000000..5dbd2c2
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/kernel_types.h
@@ -0,0 +1,46 @@
+/* Note that we use the exact same include guard #define names
+ * as asm/posix_types.h.  This will avoid gratuitous conflicts 
+ * with the posix_types.h kernel header, and will ensure that 
+ * our private content, and not the kernel header, will win.
+ *  -Erik
+ */
+#ifndef __ASM_GENERIC_POSIX_TYPES_H
+#define __ASM_GENERIC_POSIX_TYPES_H
+
+typedef unsigned short	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+typedef unsigned short	__kernel_old_dev_t;
+typedef long long	__kernel_loff_t;
+
+typedef struct {
+#ifdef __USE_ALL
+	int val[2];
+#else
+	int __val[2];
+#endif
+} __kernel_fsid_t;
+
+#endif /* __ASM_GENERIC_POSIX_TYPES_H */
diff --git a/libc/sysdeps/linux/c6x/bits/mathdef.h b/libc/sysdeps/linux/c6x/bits/mathdef.h
new file mode 100644
index 0000000..df12adf
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/mathdef.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 1997, 1998, 1999, 2000 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF	1
+
+typedef float  float_t;
+typedef double double_t;
+
+/* The values returned by `ilogb' for 0 and NaN respectively.  */
+# define FP_ILOGB0	(-2147483647 - 1)
+# define FP_ILOGBNAN	(2147483647)
+
+#endif	/* ISO C99 */
+
+#ifndef __NO_LONG_DOUBLE_MATH
+/* Signal that we do not really have a `long double'.  This disables the
+   declaration of all the `long double' function variants.  */
+# define __NO_LONG_DOUBLE_MATH	1
+#endif
diff --git a/libc/sysdeps/linux/c6x/bits/nan.h b/libc/sysdeps/linux/c6x/bits/nan.h
new file mode 100644
index 0000000..85225da
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/nan.h
@@ -0,0 +1,57 @@
+/* `NAN' constant for IEEE 754 machines.
+   Copyright (C) 1992,1996,1997,1999,2004,2006 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _MATH_H
+# error "Never use <bits/nan.h> directly; include <math.h> instead."
+#endif
+
+/* IEEE Not A Number.  */
+
+/*
+ * Copied from the common code and modified for TI tool wrapper.
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ */
+
+#if __GNUC_PREREQ(3,3)
+
+# define NAN	(__builtin_nanf (""))
+
+#elif defined __GNUC__ && ! defined __TI_TOOL_WRAPPER__
+
+# define NAN \
+  (__extension__							      \
+   ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; })  \
+    { __l: 0x7fc00000UL }).__d)
+
+#else
+
+# include <endian.h>
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  define __nan_bytes		{ 0x7f, 0xc0, 0, 0 }
+# endif
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#  define __nan_bytes		{ 0, 0, 0xc0, 0x7f }
+# endif
+
+static union { unsigned char __c[4]; float __d; } __nan_union
+    = { __nan_bytes };
+# define NAN	(__nan_union.__d)
+
+#endif	/* GCC.  */
diff --git a/libc/sysdeps/linux/c6x/bits/poll.h b/libc/sysdeps/linux/c6x/bits/poll.h
new file mode 100644
index 0000000..f7a7393
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/poll.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 1997, 2001 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _SYS_POLL_H
+# error "Never use <bits/poll.h> directly; include <sys/poll.h> instead."
+#endif
+
+/* Event types that can be polled for.  These bits may be set in `events'
+   to indicate the interesting event types; they will appear in `revents'
+   to indicate the status of the file descriptor.  */
+#define POLLIN		0x001		/* There is data to read.  */
+#define POLLPRI		0x002		/* There is urgent data to read.  */
+#define POLLOUT		0x004		/* Writing now will not block.  */
+
+#ifdef __USE_XOPEN
+/* These values are defined in XPG4.2.  */
+# define POLLRDNORM	0x040		/* Normal data may be read.  */
+# define POLLRDBAND	0x080		/* Priority data may be read.  */
+# define POLLWRNORM	POLLOUT		/* Writing now will not block.  */
+# define POLLWRBAND	0x100		/* Priority data may be written.  */
+#endif
+
+/* Event types always implicitly polled for.  These bits need not be set in
+   `events', but they will appear in `revents' to indicate the status of
+   the file descriptor.  */
+#define POLLERR		0x008		/* Error condition.  */
+#define POLLHUP		0x010		/* Hung up.  */
+#define POLLNVAL	0x020		/* Invalid polling request.  */
diff --git a/libc/sysdeps/linux/c6x/bits/resource.h b/libc/sysdeps/linux/c6x/bits/resource.h
new file mode 100644
index 0000000..57d1782
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/resource.h
@@ -0,0 +1,209 @@
+/* Bit values & structures for resource limits.  Linux/m68k version.
+   Copyright (C) 1994,1996,1997,1998,1999,2000,2001 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _SYS_RESOURCE_H
+# error "Never use <bits/resource.h> directly; include <sys/resource.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Transmute defines to enumerations.  The macro re-definitions are
+   necessary because some programs want to test for operating system
+   features with #ifdef RUSAGE_SELF.  In ISO C the reflexive
+   definition is a no-op.  */
+
+/* Kinds of resource limit.  */
+enum __rlimit_resource
+{
+  /* Per-process CPU limit, in seconds.  */
+  RLIMIT_CPU = 0,
+#define RLIMIT_CPU RLIMIT_CPU
+
+  /* Largest file that can be created, in bytes.  */
+  RLIMIT_FSIZE = 1,
+#define	RLIMIT_FSIZE RLIMIT_FSIZE
+
+  /* Maximum size of data segment, in bytes.  */
+  RLIMIT_DATA = 2,
+#define	RLIMIT_DATA RLIMIT_DATA
+
+  /* Maximum size of stack segment, in bytes.  */
+  RLIMIT_STACK = 3,
+#define	RLIMIT_STACK RLIMIT_STACK
+
+  /* Largest core file that can be created, in bytes.  */
+  RLIMIT_CORE = 4,
+#define	RLIMIT_CORE RLIMIT_CORE
+
+  /* Largest resident set size, in bytes.
+     This affects swapping; processes that are exceeding their
+     resident set size will be more likely to have physical memory
+     taken from them.  */
+  RLIMIT_RSS = 5,
+#define	RLIMIT_RSS RLIMIT_RSS
+
+  /* Number of open files.  */
+  RLIMIT_NOFILE = 7,
+  RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same.  */
+#define RLIMIT_NOFILE RLIMIT_NOFILE
+#define RLIMIT_OFILE RLIMIT_OFILE
+
+  /* Address space limit.  */
+  RLIMIT_AS = 9,
+#define RLIMIT_AS RLIMIT_AS
+
+  /* Number of processes.  */
+  RLIMIT_NPROC = 6,
+#define RLIMIT_NPROC RLIMIT_NPROC
+
+  /* Locked-in-memory address space.  */
+  RLIMIT_MEMLOCK = 8,
+#define RLIMIT_MEMLOCK RLIMIT_MEMLOCK
+
+  /* Maximum number of file locks.  */
+  RLIMIT_LOCKS = 10,
+#define RLIMIT_LOCKS RLIMIT_LOCKS
+
+  RLIMIT_NLIMITS = 11,
+  RLIM_NLIMITS = RLIMIT_NLIMITS
+#define RLIMIT_NLIMITS RLIMIT_NLIMITS
+#define RLIM_NLIMITS RLIM_NLIMITS
+};
+
+/* Value to indicate that there is no limit.  */
+#ifndef __USE_FILE_OFFSET64
+# define RLIM_INFINITY ((unsigned long)(~0UL))
+#else
+# define RLIM_INFINITY 0xffffffffffffffffuLL
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0xffffffffffffffffuLL
+#endif
+
+/* We can represent all limits.  */
+#define RLIM_SAVED_MAX	RLIM_INFINITY
+#define RLIM_SAVED_CUR	RLIM_INFINITY
+
+
+/* Type for resource quantity measurement.  */
+#ifndef __USE_FILE_OFFSET64
+typedef __rlim_t rlim_t;
+#else
+typedef __rlim64_t rlim_t;
+#endif
+#ifdef __USE_LARGEFILE64
+typedef __rlim64_t rlim64_t;
+#endif
+
+struct rlimit
+  {
+    /* The current (soft) limit.  */
+    rlim_t rlim_cur;
+    /* The hard limit.  */
+    rlim_t rlim_max;
+  };
+
+#ifdef __USE_LARGEFILE64
+struct rlimit64
+  {
+    /* The current (soft) limit.  */
+    rlim64_t rlim_cur;
+    /* The hard limit.  */
+    rlim64_t rlim_max;
+ };
+#endif
+
+/* Whose usage statistics do you want?  */
+enum __rusage_who
+{
+  /* The calling process.  */
+  RUSAGE_SELF = 0,
+#define RUSAGE_SELF RUSAGE_SELF
+
+  /* All of its terminated child processes.  */
+  RUSAGE_CHILDREN = -1,
+#define RUSAGE_CHILDREN RUSAGE_CHILDREN
+
+  /* Both.  */
+  RUSAGE_BOTH = -2
+#define RUSAGE_BOTH RUSAGE_BOTH
+};
+
+#define __need_timeval
+#include <bits/time.h>		/* For `struct timeval'.  */
+
+/* Structure which says how much of each resource has been used.  */
+struct rusage
+  {
+    /* Total amount of user time used.  */
+    struct timeval ru_utime;
+    /* Total amount of system time used.  */
+    struct timeval ru_stime;
+    /* Maximum resident set size (in kilobytes).  */
+    long ru_maxrss;
+    /* Amount of sharing of text segment memory
+       with other processes (kilobyte-seconds).  */
+    long ru_ixrss;
+    /* Amount of data segment memory used (kilobyte-seconds).  */
+    long ru_idrss;
+    /* Amount of stack memory used (kilobyte-seconds).  */
+    long ru_isrss;
+    /* Number of soft page faults (i.e. those serviced by reclaiming
+       a page from the list of pages awaiting reallocation.  */
+    long ru_minflt;
+    /* Number of hard page faults (i.e. those that required I/O).  */
+    long ru_majflt;
+    /* Number of times a process was swapped out of physical memory.  */
+    long ru_nswap;
+    /* Number of input operations via the file system.  Note: This
+       and `ru_oublock' do not include operations with the cache.  */
+    long ru_inblock;
+    /* Number of output operations via the file system.  */
+    long ru_oublock;
+    /* Number of IPC messages sent.  */
+    long ru_msgsnd;
+    /* Number of IPC messages received.  */
+    long ru_msgrcv;
+    /* Number of signals delivered.  */
+    long ru_nsignals;
+    /* Number of voluntary context switches, i.e. because the process
+       gave up the process before it had to (usually to wait for some
+       resource to be available).  */
+    long ru_nvcsw;
+    /* Number of involuntary context switches, i.e. a higher priority process
+       became runnable or the current process used up its time slice.  */
+    long ru_nivcsw;
+  };
+
+/* Priority limits.  */
+#define PRIO_MIN	-20	/* Minimum priority a process can have.  */
+#define PRIO_MAX	20	/* Maximum priority a process can have.  */
+
+/* The type of the WHICH argument to `getpriority' and `setpriority',
+   indicating what flavor of entity the WHO argument specifies.  */
+enum __priority_which
+{
+  PRIO_PROCESS = 0,		/* WHO is a process ID.  */
+#define PRIO_PROCESS PRIO_PROCESS
+  PRIO_PGRP = 1,		/* WHO is a process group ID.  */
+#define PRIO_PGRP PRIO_PGRP
+  PRIO_USER = 2			/* WHO is a user ID.  */
+#define PRIO_USER PRIO_USER
+};
diff --git a/libc/sysdeps/linux/c6x/bits/setjmp.h b/libc/sysdeps/linux/c6x/bits/setjmp.h
new file mode 100644
index 0000000..259e23b
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/setjmp.h
@@ -0,0 +1,39 @@
+/*
+ * Port of uClibc for TMS320C6000 DSP architecture 
+ * Copyright (C) 2004 Texas Instruments Incorporated
+ * Author of TMS320C6000 port: Aurelien Jacquiot 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 Library General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _SETJMP_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+typedef struct {
+	unsigned long __regs[12]; /* save A10,B10... A15,B15*/
+	unsigned long __pc;       /* the return address */
+} __jmp_buf[1];
+
+/* the stack pointer (B15) */
+#define JP_SP 11 
+
+/* Test if longjmp to JMPBUF would unwind the frame
+   containing a local variable at ADDRESS.  */
+#define _JMPBUF_UNWINDS(jmpbuf, address) \
+  ((void *) (address) < (void *) (jmpbuf)->__regs[JP_SP])
+
+
diff --git a/libc/sysdeps/linux/c6x/bits/sigcontextinfo.h b/libc/sysdeps/linux/c6x/bits/sigcontextinfo.h
new file mode 100644
index 0000000..b7e08cf
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/sigcontextinfo.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Schwab <schwab at issan.informatik.uni-dortmund.de>, 1998.
+
+   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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define SIGCONTEXT int _code, struct sigcontext *
+#define SIGCONTEXT_EXTRA_ARGS _code,
+#define GET_PC(ctx)	((void *) (ctx)->sc_pc)
+#define GET_FRAME(ctx)	((void *) __builtin_frame_address (1))
+#define GET_STACK(ctx)	((void *) (ctx)->sc_usp)
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+  (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/libc/sysdeps/linux/c6x/bits/stackinfo.h b/libc/sysdeps/linux/c6x/bits/stackinfo.h
new file mode 100644
index 0000000..9dbf06a
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/stackinfo.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 1999 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* This file contains a bit of information about the stack allocation
+   of the processor.  */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H	1
+
+/* On c6x the stack grows down.  */
+#define _STACK_GROWS_DOWN	1
+
+#endif	/* stackinfo.h */
diff --git a/libc/sysdeps/linux/c6x/bits/stat.h b/libc/sysdeps/linux/c6x/bits/stat.h
new file mode 100644
index 0000000..eba3124
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/stat.h
@@ -0,0 +1,174 @@
+/* Copyright (C) 1992,95,96,97,98,99,2000,2001 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+/* Versions of the `struct stat' data structure.  */
+#define _STAT_VER_LINUX_OLD	1
+#define _STAT_VER_KERNEL	1
+#define _STAT_VER_SVR4		2
+#define _STAT_VER_LINUX		3
+#define _STAT_VER		_STAT_VER_LINUX	/* The one defined below.  */
+
+/* Versions of the `xmknod' interface.  */
+#define _MKNOD_VER_LINUX	1
+#define _MKNOD_VER_SVR4		2
+#define _MKNOD_VER		_MKNOD_VER_LINUX /* The bits defined below.  */
+
+
+struct stat
+  {
+    __dev_t st_dev;			/* Device.  */
+    unsigned short int __pad1;
+#ifndef __USE_FILE_OFFSET64
+    __ino_t st_ino;			/* File serial number.	*/
+#else
+    __ino_t __st_ino;			/* 32bit file serial number.	*/
+#endif
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __dev_t st_rdev;			/* Device number, if device.  */
+    unsigned short int __pad2;
+#ifndef __USE_FILE_OFFSET64
+    __off_t st_size;			/* Size of file, in bytes.  */
+#else
+    __off64_t st_size;			/* Size of file, in bytes.  */
+#endif
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+
+#ifndef __USE_FILE_OFFSET64
+    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
+#else
+    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
+#endif
+#ifdef __USE_MISC
+    /* Nanosecond resolution timestamps are stored in a format
+       equivalent to 'struct timespec'.  This is the type used
+       whenever possible but the Unix namespace rules do not allow the
+       identifier 'timespec' to appear in the <sys/stat.h> header.
+       Therefore we have to handle the use of this header in strictly
+       standard-compliant sources special.  */
+    struct timespec st_atim;		/* Time of last access.  */
+    struct timespec st_mtim;		/* Time of last modification.  */
+    struct timespec st_ctim;		/* Time of last status change.  */
+# define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+    __time_t st_atime;			/* Time of last access.  */
+    unsigned long int st_atimensec;	/* Nscecs of last access.  */
+    __time_t st_mtime;			/* Time of last modification.  */
+    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
+    __time_t st_ctime;			/* Time of last status change.  */
+    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+#endif
+#ifndef __USE_FILE_OFFSET64
+    unsigned long __unused4;
+    unsigned long __unused5;
+#else
+    __ino64_t st_ino;			/* File serial number.	*/
+#endif
+  };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+  {
+    __dev_t st_dev;			/* Device.  */
+
+#if __WORDSIZE == 64
+    __ino64_t st_ino;		/* File serial number.  */
+    __nlink_t st_nlink;		/* Link count.  */
+    __mode_t st_mode;		/* File mode.  */
+#else
+    unsigned int __pad1;
+    __ino_t __st_ino;			/* 32bit file serial number.	*/
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+#endif
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __dev_t st_rdev;			/* Device number, if device.  */
+    unsigned short int __pad2;
+    __off64_t st_size;			/* Size of file, in bytes.  */
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+
+    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
+#ifdef __USE_MISC
+    /* Nanosecond resolution timestamps are stored in a format
+       equivalent to 'struct timespec'.  This is the type used
+       whenever possible but the Unix namespace rules do not allow the
+       identifier 'timespec' to appear in the <sys/stat.h> header.
+       Therefore we have to handle the use of this header in strictly
+       standard-compliant sources special.  */
+    struct timespec st_atim;		/* Time of last access.  */
+    struct timespec st_mtim;		/* Time of last modification.  */
+    struct timespec st_ctim;		/* Time of last status change.  */
+# define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+    __time_t st_atime;			/* Time of last access.  */
+    unsigned long int st_atimensec;	/* Nscecs of last access.  */
+    __time_t st_mtime;			/* Time of last modification.  */
+    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
+    __time_t st_ctime;			/* Time of last status change.  */
+    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+#endif
+#if __WORDSIZE == 64
+    long int __unused[3];
+#else
+    __ino64_t st_ino;			/* File serial number.		*/
+#endif
+  };
+#endif
+
+/* Tell code we have these members.  */
+#define	_STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+
+/* Encoding of the file mode.  */
+
+#define	__S_IFMT	0170000	/* These bits determine file type.  */
+
+/* File types.  */
+#define	__S_IFDIR	0040000	/* Directory.  */
+#define	__S_IFCHR	0020000	/* Character device.  */
+#define	__S_IFBLK	0060000	/* Block device.  */
+#define	__S_IFREG	0100000	/* Regular file.  */
+#define	__S_IFIFO	0010000	/* FIFO.  */
+#define	__S_IFLNK	0120000	/* Symbolic link.  */
+#define	__S_IFSOCK	0140000	/* Socket.  */
+
+/* POSIX.1b objects.  Note that these macros always evaluate to zero.  But
+   they do it by enforcing the correct use of the macros.  */
+#define __S_TYPEISMQ(buf)  ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits.  */
+
+#define	__S_ISUID	04000	/* Set user ID on execution.  */
+#define	__S_ISGID	02000	/* Set group ID on execution.  */
+#define	__S_ISVTX	01000	/* Save swapped text after use (sticky).  */
+#define	__S_IREAD	0400	/* Read by owner.  */
+#define	__S_IWRITE	0200	/* Write by owner.  */
+#define	__S_IEXEC	0100	/* Execute by owner.  */
diff --git a/libc/sysdeps/linux/c6x/bits/syscalls.h b/libc/sysdeps/linux/c6x/bits/syscalls.h
new file mode 100644
index 0000000..382ec51
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/syscalls.h
@@ -0,0 +1,182 @@
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <errno.h>
+
+#define SYS_ify(syscall_name)  (__NR_##syscall_name)
+
+#undef __SYSCALL_STRING
+# define __SYSCALL_STRING			\
+		"swe\n\t" \
+		"nop\n\t"
+
+# define __SYSCALL_RES_CHECK (__res < -255 || __res >= 0)
+
+#define __SYSCALL_CLOBBERS "cc", "memory"
+
+#define __SYSCALL_RETURN(type) \
+	if (__SYSCALL_RES_CHECK) \
+		return (type) __res; \
+	__set_errno (-__res); \
+	return (type) -1;
+
+#ifndef NOT_IN_libc
+#define DEBUG_SYSCALL(name) { \
+      char d[64];\
+      write( 2, d, snprintf( d, 64, "syscall %d error %d\n", __NR_##name, _inline_sys_result)); \
+}
+#else
+#define DEBUG_SYSCALL(name) do{} while(0)
+#endif
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...)				\
+  ({ unsigned int _inline_sys_result = INTERNAL_SYSCALL (name, , nr, args);	\
+     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_inline_sys_result, ), 0))	\
+       {								\
+	 __set_errno (INTERNAL_SYSCALL_ERRNO (_inline_sys_result, ));		\
+	 _inline_sys_result = (unsigned int) -1;				\
+       }								\
+     (int) _inline_sys_result; })
+
+#undef INLINE_SYSCALL_NOERR
+#define INLINE_SYSCALL_NOERR(name, nr, args...)				\
+  ({ unsigned int _inline_sys_result = INTERNAL_SYSCALL (name, , nr, args);	\
+     (int) _inline_sys_result; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+
+#define INTERNAL_SYSCALL( name, err, nr, args...) \
+    INTERNAL_SYSCALL_NCS( __NR_##name, err, nr, args )
+
+
+#define INTERNAL_SYSCALL_NCS(sys_num, err, nr, args...) \
+    ({                                                      \
+	register long __A4 __asm__("A4");		    \
+	register long __b0 __asm__("B0") = sys_num;	    \
+	LOAD_ARGS_##nr(args)				    \
+	__asm__ __volatile__(__SYSCALL_STRING		    \
+			     : "=a" (__A4)				\
+			     : "b" (__b0) ASM_ARGS_##nr			\
+			     : __SYSCALL_CLOBBERS );			\
+	(int)__A4;							\
+    })
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+  ((unsigned int) (val) >= 0xfffff001u)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err)	(-(val))
+
+#if 0
+# define CALL_ERRNO_LOCATION "call   __errno_location;"
+#define __CLONE_SYSCALL_STRING						\
+	"ta	0x10;"							\
+	"bcs	2f;"							\
+	" sub	%%o1, 1, %%o1;"						\
+	"and	%%A4, %%o1, %%A4;"					\
+	"1:"								\
+	".subsection 2;"						\
+	"2:"								\
+	"save	%%sp, -192, %%sp;"					\
+	CALL_ERRNO_LOCATION						\
+	" nop;"								\
+	"st	%%i0, [%%A4];"						\
+	"ba	1b;"							\
+	" restore %%g0, -1, %%A4;"					\
+	".previous;"
+
+#define INLINE_CLONE_SYSCALL(arg1,arg2,arg3,arg4,arg5)			\
+({									\
+	register long __A4 __asm__ ("A4") = (long)(arg1);		\
+	register long __B4 __asm__ ("B4") = (long)(arg2);		\
+	register long __A6 __asm__ ("A6") = (long)(arg3);		\
+	register long __B6 __asm__ ("B6") = (long)(arg4);		\
+	register long __A8 __asm__ ("A8") = (long)(arg5);		\
+	register long __g1 __asm__ ("g1") = __NR_clone;			\
+	__asm __volatile (__CLONE_SYSCALL_STRING :			\
+			  "=r" (__g1), "=r" (__A4), "=r" (__B4)	:	\
+			  "0" (__g1), "1" (__A4), "2" (__B4),		\
+			  "r" (__A6), "r" (__B6), "r" (__A8) :		\
+			  __SYSCALL_CLOBBERS);				\
+	__A4;								\
+})
+#endif
+
+#define LOAD_ARGS_0()
+#define ASM_ARGS_0
+#define LOAD_ARGS_1(A4) \
+    __A4 = (int)A4;     \
+    LOAD_ARGS_0()
+#define ASM_ARGS_1 ASM_ARGS_0, "a" (__A4)
+#define LOAD_ARGS_2(A4, B4)			\
+  register int __B4 __asm__ ("B4") = (int) (B4);	\
+  LOAD_ARGS_1 (A4)
+#define ASM_ARGS_2	ASM_ARGS_1, "b" (__B4)
+#define LOAD_ARGS_3(A4, B4, A6)			\
+  register int __A6 __asm__ ("A6") = (int) (A6);	\
+  LOAD_ARGS_2 (A4, B4)
+#define ASM_ARGS_3	ASM_ARGS_2, "a" (__A6)
+#define LOAD_ARGS_4(A4, B4, A6, B6)		\
+  register int __B6 __asm__ ("B6") = (int) (B6);	\
+  LOAD_ARGS_3 (A4, B4, A6)
+#define ASM_ARGS_4	ASM_ARGS_3, "b" (__B6)
+#define LOAD_ARGS_5(A4, B4, A6, B6, A8)		\
+  register int __A8 __asm__ ("A8") = (int) (A8);	\
+  LOAD_ARGS_4 (A4, B4, A6, B6)
+#define ASM_ARGS_5	ASM_ARGS_4, "a" (__A8)
+#define LOAD_ARGS_6(A4, B4, A6, B6, A8, B8)	\
+  register int __B8 __asm__ ("B8") = (int) (B8);	\
+  LOAD_ARGS_5 (A4, B4, A6, B6, A8)
+#define ASM_ARGS_6	ASM_ARGS_5, "b" (__B8)
+
+#ifndef _syscall0
+
+#define C_DECL_ARGS_0()			void
+#define C_DECL_ARGS_1(t, v)		t v
+#define C_DECL_ARGS_2(t, v, args...)	t v, C_DECL_ARGS_1(args)
+#define C_DECL_ARGS_3(t, v, args...)	t v, C_DECL_ARGS_2(args)
+#define C_DECL_ARGS_4(t, v, args...)	t v, C_DECL_ARGS_3(args)
+#define C_DECL_ARGS_5(t, v, args...)	t v, C_DECL_ARGS_4(args)
+#define C_DECL_ARGS_6(t, v, args...)	t v, C_DECL_ARGS_5(args)
+
+#define C_ARGS_0()
+#define C_ARGS_1(t, v)			v
+#define C_ARGS_2(t, v, args...)		v, C_ARGS_1(args)
+#define C_ARGS_3(t, v, args...)		v, C_ARGS_2(args)
+#define C_ARGS_4(t, v, args...)		v, C_ARGS_3(args)
+#define C_ARGS_5(t, v, args...)		v, C_ARGS_4(args)
+#define C_ARGS_6(t, v, args...)		v, C_ARGS_5(args)
+
+#define SYSCALL_FUNC(nargs, type, name, args...)			\
+type name(C_DECL_ARGS_##nargs(args)) {					\
+	return (type)INLINE_SYSCALL(name, nargs, C_ARGS_##nargs(args));	\
+}
+
+#define SYSCALL_NOERR_FUNC(nargs, type, name, args...)			\
+type name(C_DECL_ARGS_##nargs(args)) {					\
+	return (type)INLINE_SYSCALL_NOERR(name, nargs, C_ARGS_##nargs(args));	\
+}
+
+#define _syscall0(args...)		SYSCALL_FUNC(0, args)
+#define _syscall1(args...)		SYSCALL_FUNC(1, args)
+#define _syscall_noerr1(args...)	SYSCALL_NOERR_FUNC(1, args)
+#define _syscall2(args...)		SYSCALL_FUNC(2, args)
+#define _syscall3(args...)		SYSCALL_FUNC(3, args)
+#define _syscall4(args...)		SYSCALL_FUNC(4, args)
+#define _syscall5(args...)		SYSCALL_FUNC(5, args)
+#define _syscall6(args...)		SYSCALL_FUNC(6, args)
+
+#endif /* _syscall0 */
+
+#endif /* __ASSEMBLER__ */
+#endif /* _BITS_SYSCALLS_H */
+
diff --git a/libc/sysdeps/linux/c6x/bits/uClibc_arch_features.h b/libc/sysdeps/linux/c6x/bits/uClibc_arch_features.h
new file mode 100644
index 0000000..59e7de9
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/uClibc_arch_features.h
@@ -0,0 +1,48 @@
+/*
+ * Track misc arch-specific features that aren't config options
+ */
+
+#ifndef _BITS_UCLIBC_ARCH_FEATURES_H
+#define _BITS_UCLIBC_ARCH_FEATURES_H
+
+/* instruction used when calling abort() to kill yourself */
+/*#define __UCLIBC_ABORT_INSTRUCTION__ "asm instruction"*/
+#undef __UCLIBC_ABORT_INSTRUCTION__
+
+/* can your target use syscall6() for mmap ? */
+#define __UCLIBC_MMAP_HAS_6_ARGS__
+
+/* does your target use syscall4() for truncate64 ? (32bit arches only) */
+#undef __UCLIBC_TRUNCATE64_HAS_4_ARGS__
+
+/* does your target have a broken create_module() ? */
+#undef __UCLIBC_BROKEN_CREATE_MODULE__
+
+/* does your target have to worry about older [gs]etrlimit() ? */
+#undef __UCLIBC_HANDLE_OLDER_RLIMIT__
+
+/* does your target have an asm .set ? */
+#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__
+
+/* define if target doesn't like .global */
+#undef __UCLIBC_ASM_GLOBAL_DIRECTIVE__
+
+/* define if target supports .weak */
+#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__
+
+/* define if target supports .weakext */
+#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__
+
+/* needed probably only for ppc64 */
+#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__
+
+/* define if target supports CFI pseudo ops */
+#undef __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__
+
+/* define if target supports IEEE signed zero floats */
+#define __UCLIBC_HAVE_SIGNED_ZERO__
+
+/* only weird assemblers generally need this */
+#define __UCLIBC_ASM_LINE_SEP__ @
+
+#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */
diff --git a/libc/sysdeps/linux/c6x/bits/wordsize.h b/libc/sysdeps/linux/c6x/bits/wordsize.h
new file mode 100644
index 0000000..ba643b6
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bits/wordsize.h
@@ -0,0 +1,19 @@
+/* Copyright (C) 1999 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define __WORDSIZE	32
diff --git a/libc/sysdeps/linux/c6x/brk.c b/libc/sysdeps/linux/c6x/brk.c
new file mode 100644
index 0000000..7eb4863
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/brk.c
@@ -0,0 +1,54 @@
+/*
+ * Port of uClibc for TMS320C6000 DSP architecture
+ * Copyright (C) 2004 Texas Instruments Incorporated
+ * Author of TMS320C6000 port: Aurelien Jacquiot
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 Library General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+libc_hidden_proto(brk)
+
+/* This must be initialized data because commons can't have aliases.  */
+void * __curbrk attribute_hidden = 0;
+
+int brk (void *addr)
+{
+	void *newbrk;
+
+	__asm__ __volatile__ ( \
+		"mv .d1	%2, A4\n\t" \
+		"mvk .s2	%1, B0\n\t" \
+		"swe\n\t" \
+		"nop\n\t" \
+		"mv .d2	B0, %0" \
+		: "=b" (newbrk) \
+		: "i" (__NR_brk), \
+		  "a" (addr) \
+		: "memory", "cc", "B0", "A4"); \
+
+	__curbrk = newbrk;
+
+	if (newbrk < addr) {
+		__set_errno (ENOMEM);
+		return -1;
+	}
+	return 0;
+}
+libc_hidden_def(brk)
diff --git a/libc/sysdeps/linux/c6x/bsd-_setjmp.s b/libc/sysdeps/linux/c6x/bsd-_setjmp.s
new file mode 100644
index 0000000..566318a
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bsd-_setjmp.s
@@ -0,0 +1,48 @@
+ ;
+ ; Port of uClibc for TMS320C6000 DSP architecture 
+ ; Copyright (C) 2004 Texas Instruments Incorporated
+ ; Author of TMS320C6000 port: Aurelien Jacquiot 
+ ;
+ ; This program is free software; you can redistribute it and/or modify it
+ ; under the terms of the GNU Library General Public License as published by
+ ; the Free Software Foundation; either version 2 of the License, or (at your
+ ; option) any later version.
+ ;
+ ; This program 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 Library General Public License
+ ; for more details.
+ ;
+ ; You should have received a copy of the GNU Library General Public License
+ ; along with this program; if not, write to the Free Software Foundation,
+ ; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ;
+
+	.global _setjmp
+
+_setjmp:
+	MV .D2X	A4,B4		; jmp_buf address
+||	STW .D1T2	B3,*+A4(48)	; return address
+
+	STW .D1T1	A10,*+A4(0)
+||	STW .D2T2	B10,*+B4(4)
+||	ZERO .L1	A6
+	
+	STW .D1T1	A6,*+A4(52)	; no signal mask set
+||	B .S2	B3		; returns in 5 cycles
+
+	STW .D1T1	A11,*+A4(8)
+||	STW .D2T2	B11,*+B4(12)
+	STW .D1T1	A12,*+A4(16)
+||	STW .D2T2	B12,*+B4(20)
+	STW .D1T1	A13,*+A4(24)
+||	STW .D2T2	B13,*+B4(28)
+	STW .D1T1	A14,*+A4(32)
+||	STW .D2T2	B14,*+B4(36)
+	STW .D1T1	A15,*+A4(40)
+||	STW .D2T2	B15,*+B4(44)
+||	ZERO .L1	A4		; return values
+
+
+
+
diff --git a/libc/sysdeps/linux/c6x/bsd-setjmp.S b/libc/sysdeps/linux/c6x/bsd-setjmp.S
new file mode 100644
index 0000000..3ab597d
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/bsd-setjmp.S
@@ -0,0 +1,67 @@
+ ;
+ ; Port of uClibc for TMS320C6000 DSP architecture
+ ; Copyright (C) 2004 Texas Instruments Incorporated
+ ; Author of TMS320C6000 port: Aurelien Jacquiot
+ ;
+ ; This program is free software; you can redistribute it and/or modify it
+ ; under the terms of the GNU Library General Public License as published by
+ ; the Free Software Foundation; either version 2 of the License, or (at your
+ ; option) any later version.
+ ;
+ ; This program 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 Library General Public License
+ ; for more details.
+ ;
+ ; You should have received a copy of the GNU Library General Public License
+ ; along with this program; if not, write to the Free Software Foundation,
+ ; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ;
+
+	.global setjmp
+setjmp:
+#if 0
+.if 1 /* was: .if (CONFIG_UCLIBC_SHARED == 0) */
+
+	MVKL .S1	___curr_eh_stack_entry,A6
+||	SUB .D1X	A4,B15,A3
+	MVKH .S1	___curr_eh_stack_entry,A6
+||	CMPGT .L1	A3,4,A0		; A0 set if C++ exceptions case
+
+	LDW .D1T1	*A6,A2
+.else
+	MVKL .S2	(___curr_eh_stack_entry - $bss)/4,B6
+||	SUB .D1X	A4,B15,A3
+	MVKH .S2	(___curr_eh_stack_entry - $bss)/4,B6
+||	CMPGT .L1	A3,4,A0		; A0 set if C++ exceptions case
+
+	LDW .D2T1	*+B14[B6],A2
+.endif
+	NOP
+#else
+	MVK .S1		0, A0
+#endif
+
+	MVK .L2	1,B4		; indicate to ___sigjmp_save to save signal mask
+||	MV .D2X	A4,B6		; jmp_buf address
+||	STW .D1T2	B3,*+A4(48)	; return address
+
+	ADDAW .D1	A2,2,A2
+ [A0]	CMPEQ .L1	A4,A2,A0	; A0 set if C++ exceptions case
+
+	STW .D1T1	A10,*+A4(0)
+||	STW .D2T2	B10,*+B6(4)
+||[!A0]	B .S1		__sigjmp_save		; branch to ___sigjmp_save in 5 cycles
+||[A0]	B .S2		B3
+
+	STW .D1T1	A11,*+A4(8)
+||	STW .D2T2	B11,*+B6(12)
+	STW .D1T1	A12,*+A4(16)
+||	STW .D2T2	B12,*+B6(20)
+	STW .D1T1	A13,*+A4(24)
+||	STW .D2T2	B13,*+B6(28)
+	STW .D1T1	A14,*+A4(32)
+||	STW .D2T2	B14,*+B6(36)
+	STW .D1T1	A15,*+A4(40)
+||	STW .D2T2	B15,*+B6(44)
+||[A0]	ZERO .L1	A4		; returns 0 for the C++ case
diff --git a/libc/sysdeps/linux/c6x/clone.S b/libc/sysdeps/linux/c6x/clone.S
new file mode 100644
index 0000000..8d9da4b
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/clone.S
@@ -0,0 +1,97 @@
+ ;
+ ; Port of uClibc for TMS320C6000 DSP architecture
+ ; Copyright (C) 2004 Texas Instruments Incorporated
+ ; Author of TMS320C6000 port: Aurelien Jacquiot
+ ;
+ ; This program is free software; you can redistribute it and/or modify it
+ ; under the terms of the GNU Library General Public License as published by
+ ; the Free Software Foundation; either version 2 of the License, or (at your
+ ; option) any later version.
+ ;
+ ; This program 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 Library General Public License
+ ; for more details.
+ ;
+ ; You should have received a copy of the GNU Library General Public License
+ ; along with this program; if not, write to the Free Software Foundation,
+ ; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ;
+
+	; int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg);
+
+#include <asm/errno.h>
+#include <sys/syscall.h>
+
+	.global __clone
+	.global	clone
+	.global	__errno_location
+
+ ;Currently supports only
+ ;int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
+ ;
+ ;Requires update for supporting
+ ; int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+ ;	    int *parent_tidptr, struct user_desc *newtls, int *child_pidptr)
+
+__clone:
+	; index 1 points to the forth argument and is to be moved to B6
+	LDW .D2T2	*+B15[1],B5
+	NOP     4
+	OR .D2X	B4,A4,B2	; sanity check arguments, no NULL function or stack pointers
+||	MV .S2	B4,B9
+||	MV .D1	A4,A9		; backup fn and child_stack pointers
+
+  [!B2]	B .S2	__syscall_error
+||[!B2] MVK .S1	EINVAL,A4
+	NOP	4
+
+	MV .D1	A6,A4		; get flags as arg0, arg1 is the new stack
+||	AND .D2	~7,B4,B4
+
+	; do the system call
+||	MVK .S2	120,B0		; __NR_clone
+||	MV .L2  B5,B6
+0:
+#ifndef	_TMS320C6400_PLUS
+  	MVC .S2     CSR,B2
+	CLR .S2     B2,0,0,B1
+	MVC .S2     B1,CSR
+	MVC .S2     IFR,B1
+	SET .S2     B1,6,6,B1
+	MVC .S2     B1,ISR
+	MVC .S2     B2,CSR
+	NOP
+#else
+	SWE
+#endif
+
+	MV .D2	B9,B4		; restore child stack
+
+||	CMPEQ .L1	0,A4,A2
+||	CMPLT .L2X	A4,0,B2
+
+   [B2]	B .S2	__syscall_error	; if syscall < 0, it is an error
+	NOP	5
+   [A2] B .S2X	A9		; branch to function
+|| [A2] MV .D1X	B6,A4		; set arg (B6 is preserved by syscall)
+  [!A2] B .S2	B3		; otherwise (syscall result > 0) returns directly
+   [A2]	ADDKPC .S2	__return_thread,B3, 4
+
+__return_thread:
+	b	.s2	HIDDEN_JUMPTARGET(_exit)
+	nop	5
+
+__syscall_error:
+	NEG .S1	A4,A4
+	STW .D2T1	A4,*B15--[2]
+	STW .D2T2	B3,*+B15[1]
+	CALLP .S2	__errno_location,B3
+	LDW .D2T2	*+B15[1],B3
+	LDW .D2T1	*++B15[2],A5
+	NOP	3
+	BNOP .S2	B3,3
+	STW .D1T1	A5,*A4
+	MVK .L1	-1,A4
+
+.set clone, __clone
diff --git a/libc/sysdeps/linux/c6x/crt1.S b/libc/sysdeps/linux/c6x/crt1.S
new file mode 100644
index 0000000..810f395
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/crt1.S
@@ -0,0 +1,67 @@
+;
+; Port of uClibc for TMS320C6000 DSP architecture
+; 
+; Copyright (C) 2010 Texas Instruments Incorporated
+; Mark Salter <msalter at redhat.com>
+;
+; This program is free software; you can redistribute it and/or modify it
+; under the terms of the GNU Library General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or (at your
+; option) any later version.
+;
+; This program 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 Library General Public License
+; for more details.
+;
+; You should have received a copy of the GNU Library General Public License
+; along with this program; if not, write to the Free Software Foundation,
+; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+;
+
+       .text
+
+	;; On entry, the dynamic linker
+	;;
+	;;	0(sp)			pad0
+	;;	4(sp)			pad1
+	;;	8(sp)			argc
+	;;	12(sp)			argv[0]
+	;;	...
+	;;	(4*(argc+3))(sp)	NULL
+	;;	(4*(argc+4))(sp)	envp[0]
+	;;	...
+	;;				NULL
+
+	;; Register values are unspecified, except:
+	;;
+	;;	A4  --> pointer to rtld fini rountine
+	;;	B14 --> pointer to application DSBT table
+
+	.global	_start
+_start:
+	.global _c_int00
+_c_int00:
+	;; Things to do:
+	;;
+	;; 	* call __uClibc_main(
+	;; 		int (*main)(int, char **, char **),	A4
+	;; 		int argc,				B4
+	;;		char **argv,			   	A6
+	;; 		void (*app_init)(void),		   	B6
+	;; 		void (*app_fini)(void),		   	A8
+	;;		void (*rtld_fini)(void),		B8
+	;; 		void *stack_end)			A10
+
+	MV .D2X	A4,B8		; rtld_fini
+
+	LDW .D2T1	*+B14($GOT(main)), A4
+	LDW .D2T2	*+B14($GOT(_init)), B6
+	B .S2		__uClibc_main
+||	LDW .D2T1	*+B14($GOT(_fini)), A8
+
+	LDW .D2T2	*+B15(8),B4	; argc
+	ADDAW .D1X	B15,3,A6	; **argv
+	MV .D1X		B15,A10		; stack_end
+||	ZERO .L1	A15		; clear FP
+	NOP		2
diff --git a/libc/sysdeps/linux/c6x/crti.S b/libc/sysdeps/linux/c6x/crti.S
new file mode 100644
index 0000000..e689a04
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/crti.S
@@ -0,0 +1,17 @@
+/*
+ * This file just supplies function prologues for the .init and .fini
+ * sections.  It is linked in before crtbegin.o.
+ */
+
+	.section .init
+	.globl  _init
+	.type   _init, at function
+_init:
+	add	.l2	-8, B15, B15
+	stw	.d2t2	B3,*+B15(4)
+	.section .fini
+	.globl  _fini
+	.type   _fini, at function
+_fini:
+	add	.l2	-8, B15, B15
+	stw	.d2t2	B3,*+B15(4)
diff --git a/libc/sysdeps/linux/c6x/crtn.S b/libc/sysdeps/linux/c6x/crtn.S
new file mode 100644
index 0000000..37e799d
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/crtn.S
@@ -0,0 +1,19 @@
+/*
+ * This file supplies function epilogues for the .init and .fini sections.
+ * It is linked in after all other files.
+ */
+
+	.section .init
+	ldw .d2t2	*+B15(4), B3
+	add .d2		B15, 8, B15
+	nop		3
+	ret .s2		B3
+	nop		5
+
+	.section .fini
+	ldw .d2t2	*+B15(4), B3
+	add .d2		B15, 8, B15
+	nop		3
+	ret .s2		B3
+	nop		5
+
diff --git a/libc/sysdeps/linux/c6x/prctl.c b/libc/sysdeps/linux/c6x/prctl.c
new file mode 100644
index 0000000..fcf1f9d
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/prctl.c
@@ -0,0 +1,43 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * prctl() for uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <stdarg.h>
+/* psm: including sys/prctl.h would depend on kernel headers */
+
+#ifdef __NR_prctl
+extern int prctl (int __option, ...);
+int prctl (int __option, ...)
+{
+	register long no __asm__("B0");
+	register long a __asm__("A4");
+	register long b __asm__("B4");
+	register long c __asm__("A6");
+	register long d __asm__("B6");
+	register long e __asm__("A8");
+	int __res;
+	va_list ap;
+
+	va_start( ap, __option);
+	a = __option;
+	b = va_arg( ap, long);
+	c = va_arg( ap, long);
+	d = va_arg( ap, long);
+	e = va_arg( ap, long);
+	va_end( ap );
+
+	no = __NR_prctl;
+
+	__asm__ __volatile__ ("SWE" : "=a" (a) : "a" (a), "b" (b), "a" (c), "b" (d), "a" (e), "b" (no)
+			      : "memory", "cc");
+
+	__res = a;
+	__SYSCALL_RETURN (int);
+}
+#endif
diff --git a/libc/sysdeps/linux/c6x/pread_write.c b/libc/sysdeps/linux/c6x/pread_write.c
new file mode 100644
index 0000000..f985b43
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/pread_write.c
@@ -0,0 +1,103 @@
+/* vi: set sw=4 ts=4:
+ *
+ * Copyright (C) 2002 by Erik Andersen <andersen at uclibc.org>
+ * Based in part on the files
+ *		./sysdeps/unix/sysv/linux/pwrite.c,
+ *		./sysdeps/unix/sysv/linux/pread.c,
+ *		sysdeps/posix/pread.c
+ *		sysdeps/posix/pwrite.c
+ * from GNU libc 2.2.5, but reworked considerably...
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 Library General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _LARGEFILE64_SOURCE
+#include <features.h>
+#undef __OPTIMIZE__
+/* We absolutely do _NOT_ want interfaces silently
+ *  *  * renamed under us or very bad things will happen... */
+#ifdef __USE_FILE_OFFSET64
+# undef __USE_FILE_OFFSET64
+#endif
+
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <stdint.h>
+
+extern __typeof(pread) __libc_pread;
+extern __typeof(pwrite) __libc_pwrite;
+#ifdef __UCLIBC_HAS_LFS__
+extern __typeof(pread64) __libc_pread64;
+extern __typeof(pwrite64) __libc_pwrite64;
+#endif
+
+#ifdef __NR_pread64             /* Newer kernels renamed but it's the same.  */
+# ifdef __NR_pread
+#  error "__NR_pread and __NR_pread64 both defined???"
+# endif
+# define __NR_pread __NR_pread64
+#endif
+
+#define __NR___syscall_pread __NR_pread
+static inline _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
+		size_t, count, off_t, offset_hi, off_t, offset_lo);
+
+ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
+{
+	return(__syscall_pread(fd,buf,count,offset,offset >> 31));
+}
+weak_alias (__libc_pread, pread)
+
+#if defined __UCLIBC_HAS_LFS__
+ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
+{
+    uint32_t low = offset & 0xffffffff;
+    uint32_t high = offset >> 32;
+	return(__syscall_pread(fd, buf, count, low, high));
+}
+weak_alias (__libc_pread64, pread64)
+#endif /* __UCLIBC_HAS_LFS__  */
+
+
+#ifdef __NR_pwrite64            /* Newer kernels renamed but it's the same.  */
+# ifdef __NR_pwrite
+#  error "__NR_pwrite and __NR_pwrite64 both defined???"
+# endif
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+#define __NR___syscall_pwrite __NR_pwrite
+static inline _syscall5(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
+		size_t, count, off_t, offset_hi, off_t, offset_lo);
+
+ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+	return(__syscall_pwrite(fd,buf,count,offset,offset >> 31));
+}
+weak_alias (__libc_pwrite, pwrite)
+
+#if defined __UCLIBC_HAS_LFS__
+ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
+{
+    uint32_t low = offset & 0xffffffff;
+    uint32_t high = offset >> 32;
+	return(__syscall_pwrite(fd, buf, count, low, high));
+}
+weak_alias (__libc_pwrite64, pwrite64)
+#endif /* __UCLIBC_HAS_LFS__  */
+
diff --git a/libc/sysdeps/linux/c6x/setjmp.s b/libc/sysdeps/linux/c6x/setjmp.s
new file mode 100644
index 0000000..28a4f03
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/setjmp.s
@@ -0,0 +1,43 @@
+ ;
+ ; Port of uClibc for TMS320C6000 DSP architecture
+ ; Copyright (C) 2004 Texas Instruments Incorporated
+ ; Author of TMS320C6000 port: Aurelien Jacquiot
+ ;
+ ; This program is free software; you can redistribute it and/or modify it
+ ; under the terms of the GNU Library General Public License as published by
+ ; the Free Software Foundation; either version 2 of the License, or (at your
+ ; option) any later version.
+ ;
+ ; This program 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 Library General Public License
+ ; for more details.
+ ;
+ ; You should have received a copy of the GNU Library General Public License
+ ; along with this program; if not, write to the Free Software Foundation,
+ ; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ;
+
+	.global __sigsetjmp
+;	.ref	__sigjmp_save
+
+__sigsetjmp:
+        MV .D2X	A4,B6		; jmp_buf address
+||	STW .D1T2	B3,*+A4(48)	; return address
+
+        STW .D1T1	A10,*+A4(0)
+||	STW .D2T2	B10,*+B6(4)
+||	B .S2		__sigjmp_save	; branch to ___sigjmp_save in 5 cycles
+
+        STW .D1T1	A11,*+A4(8)
+||	STW .D2T2	B11,*+B6(12)
+        STW .D1T1	A12,*+A4(16)
+||	STW .D2T2	B12,*+B6(20)
+        STW .D1T1	A13,*+A4(24)
+||	STW .D2T2	B13,*+B6(28)
+        STW .D1T1	A14,*+A4(32)
+||	STW .D2T2	B14,*+B6(36)
+        STW .D1T1	A15,*+A4(40)
+||	STW .D2T2	B15,*+B6(44)
+
+
diff --git a/libc/sysdeps/linux/c6x/sigaction.c b/libc/sysdeps/linux/c6x/sigaction.c
new file mode 100644
index 0000000..1865998
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/sigaction.c
@@ -0,0 +1,115 @@
+/*
+   Copyright (C) 2010 Texas Instruments Incorporated
+   Adapted from i386 version by Mark Salter <msalter at redhat.com>
+
+   Copyright (C) 1997, 1998, 1999, 2000 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Totally hacked up for uClibc by Erik Andersen <andersen at codepoet.org>
+   */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <bits/kernel_sigaction.h>
+
+#define SA_RESTORER	0x04000000
+
+extern __typeof(sigaction) __libc_sigaction;
+
+extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden;
+extern void restore(void) __asm__ ("__restore") attribute_hidden;
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+   If OACT is not NULL, put the old action for SIG in *OACT.  */
+int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+{
+    int result;
+    struct kernel_sigaction kact, koact;
+
+#ifdef SIGCANCEL
+    if (sig == SIGCANCEL) {
+	__set_errno (EINVAL);
+	return -1;
+    }
+#endif
+
+    if (act) {
+	kact.k_sa_handler = act->sa_handler;
+	memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
+	kact.sa_flags = act->sa_flags;
+
+	kact.sa_flags = act->sa_flags | SA_RESTORER;
+	kact.sa_restorer = ((act->sa_flags & SA_SIGINFO)
+		? &restore_rt : &restore);
+    }
+
+    /* XXX The size argument hopefully will have to be changed to the
+       real size of the user-level sigset_t.  */
+    result = __syscall_rt_sigaction(sig, act ? __ptrvalue (&kact) : NULL,
+	    oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
+
+    if (oact && result >= 0) {
+	oact->sa_handler = koact.k_sa_handler;
+	memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (oact->sa_mask));
+	oact->sa_flags = koact.sa_flags;
+	oact->sa_restorer = koact.sa_restorer;
+    }
+    return result;
+}
+
+#ifndef LIBC_SIGACTION
+weak_alias(__libc_sigaction,sigaction)
+libc_hidden_weak(sigaction)
+#endif
+
+/* NOTE: Please think twice before making any changes to the bits of
+   code below.  GDB needs some intimate knowledge about it to
+   recognize them as signal trampolines, and make backtraces through
+   signal handlers work right.  Important are both the names
+   (__restore and __restore_rt) and the exact instruction sequence.
+   If you ever feel the need to make any changes, please notify the
+   appropriate GDB maintainer.  */
+
+#define RESTORE(name, syscall) RESTORE2 (name, syscall)
+#define RESTORE2(name, syscall) \
+__asm__						\
+  (						\
+   "    .text\n"				\
+   "    .global " #name "\n"			\
+   "__" #name ":\n"				\
+   "	MVK " #syscall ",B0\n"			\
+   "	SWE\n"					\
+   "	NOP\n"					\
+   "	NOP\n"					\
+   "	NOP\n"					\
+   "	NOP\n"					\
+   "	NOP\n"					\
+   "	NOP\n"					\
+   );
+
+#ifdef __NR_rt_sigaction
+/* The return code for realtime-signals.  */
+RESTORE (restore_rt, __NR_rt_sigreturn)
+#endif
+
+#ifdef __NR_sigreturn
+/* For the boring old signals.  */
+RESTORE (restore, __NR_sigreturn)
+#endif
diff --git a/libc/sysdeps/linux/c6x/sys/procfs.h b/libc/sysdeps/linux/c6x/sys/procfs.h
new file mode 100644
index 0000000..41c2d08
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/sys/procfs.h
@@ -0,0 +1,122 @@
+/* Copyright (C) 1996, 1997, 1999, 2000, 2001 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H	1
+
+/* This is somewhat modelled after the file of the same name on SVR4
+   systems.  It provides a definition of the core file format for ELF
+   used on Linux.  It doesn't have anything to do with the /proc file
+   system, even though Linux has one.
+
+   Anyway, the whole purpose of this file is for GDB and GDB only.
+   Don't read too much into it.  Don't use it for anything other than
+   GDB unless you know what you are doing.  */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+/* Type for a general-purpose register.  */
+typedef unsigned long elf_greg_t;
+
+/* And the whole bunch of them.  We could have used `struct
+   user_regs_struct' directly in the typedef, but tradition says that
+   the register set is an array, which does have some peculiar
+   semantics, so leave it that way.  */
+#define ELF_NGREG 20
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* Signal info.  */
+struct elf_siginfo
+  {
+    int si_signo;			/* Signal number.  */
+    int si_code;			/* Extra code.  */
+    int si_errno;			/* Errno.  */
+  };
+
+
+/* Definitions to generate Intel SVR4-like core files.  These mostly
+   have the same names as the SVR4 types with "elf_" tacked on the
+   front to prevent clashes with Linux definitions, and the typedef
+   forms have been avoided.  This is mostly like the SVR4 structure,
+   but more Linuxy, with things that Linux does not support and which
+   GDB doesn't really use excluded.  */
+
+struct elf_prstatus
+  {
+    struct elf_siginfo pr_info;		/* Info associated with signal.  */
+    short int pr_cursig;		/* Current signal.  */
+    unsigned long int pr_sigpend;	/* Set of pending signals.  */
+    unsigned long int pr_sighold;	/* Set of held signals.  */
+    __pid_t pr_pid;
+    __pid_t pr_ppid;
+    __pid_t pr_pgrp;
+    __pid_t pr_sid;
+    struct timeval pr_utime;		/* User time.  */
+    struct timeval pr_stime;		/* System time.  */
+    struct timeval pr_cutime;		/* Cumulative user time.  */
+    struct timeval pr_cstime;		/* Cumulative system time.  */
+    elf_gregset_t pr_reg;		/* GP registers.  */
+    int pr_fpvalid;			/* True if math copro being used.  */
+  };
+
+
+#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
+
+struct elf_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long int pr_flag;		/* Flags.  */
+    unsigned short int pr_uid;
+    unsigned short int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+
+/* The rest of this file provides the types for emulation of the
+   Solaris <proc_service.h> interfaces that should be implemented by
+   users of libthread_db.  */
+
+/* Addresses.  */
+typedef void *psaddr_t;
+
+/* Register sets.  Linux has different names.  */
+typedef elf_gregset_t prgregset_t;
+typedef elf_gregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+   therefore have only one PID type.  */
+typedef __pid_t lwpid_t;
+
+/* Process status and info.  In the end we do provide typedefs for them.  */
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif	/* sys/procfs.h */
diff --git a/libc/sysdeps/linux/c6x/sys/reg.h b/libc/sysdeps/linux/c6x/sys/reg.h
new file mode 100644
index 0000000..46857ba
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/sys/reg.h
@@ -0,0 +1,26 @@
+/*
+ * Port of uClibc for TMS320C6000 DSP architecture 
+ * Copyright (C) 2004 Texas Instruments Incorporated
+ * Author of TMS320C6000 port: Aurelien Jacquiot 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 Library General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _SYS_REG_H
+#define _SYS_REG_H	1
+
+#include <asm/ptrace.h>
+
+#endif /* _SYS_REG_H */
diff --git a/libc/sysdeps/linux/c6x/sys/ucontext.h b/libc/sysdeps/linux/c6x/sys/ucontext.h
new file mode 100644
index 0000000..9a3922a
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/sys/ucontext.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 1997, 1999, 2001 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H	1
+
+#include <features.h>
+#include <signal.h>
+#include <bits/sigcontext.h>
+
+/* A machine context is exactly a sigcontext.  */
+typedef struct sigcontext mcontext_t;
+
+/* Userlevel context.  */
+typedef struct ucontext
+{
+	unsigned long    uc_flags;
+	struct ucontext *uc_link;
+	stack_t          uc_stack;
+	mcontext_t       uc_mcontext;
+	__sigset_t       uc_sigmask;
+} ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/linux/c6x/sys/user.h b/libc/sysdeps/linux/c6x/sys/user.h
new file mode 100644
index 0000000..8c0a99d
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/sys/user.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2010 Texas Instruments Incorporated
+   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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H	1
+
+/* The whole purpose of this file is for GDB and GDB only.  Don't read
+   too much into it.  Don't use it for anything other than GDB unless
+   you know what you are doing.  */
+
+/* Left blank as a placeholder for now */
+
+#endif  /* sys/user.h */
diff --git a/libc/sysdeps/linux/c6x/syscall.c b/libc/sysdeps/linux/c6x/syscall.c
new file mode 100644
index 0000000..ea947b2
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/syscall.c
@@ -0,0 +1,49 @@
+/*
+ *  syscall.c
+ *
+ *  Port on Texas Instruments TMS320C6x architecture
+ *
+ *  Copyright (C) 2006, 2010 Texas Instruments Incorporated
+ *  Author: Thomas Charleux (thomas.charleux at jaluna.com)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <features.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+long int syscall (long int __sysno, ...)
+{
+	register long no __asm__("B0");
+	register long a __asm__("A4");
+	register long b __asm__("B4");
+	register long c __asm__("A6");
+	register long d __asm__("B6");
+	register long e __asm__("A8");
+	register long f __asm__("B8");
+	long __res;
+	va_list ap;
+
+	va_start( ap, __sysno);
+	a = va_arg( ap, long);
+	b = va_arg( ap, long);
+	c = va_arg( ap, long);
+	d = va_arg( ap, long);
+	e = va_arg( ap, long);
+	f = va_arg( ap, long);
+	va_end( ap );
+
+	no = __sysno;
+
+	__asm__ __volatile__ ("SWE" : "=a" (a) : "a" (a), "b" (b), "a" (c), "b" (d), "a" (e), "b" (f), "b" (no)
+			      : "memory", "cc");
+
+	__res = a;
+	__SYSCALL_RETURN (long);
+}
diff --git a/libc/sysdeps/linux/c6x/vfork.c b/libc/sysdeps/linux/c6x/vfork.c
new file mode 100644
index 0000000..f19dcd4
--- /dev/null
+++ b/libc/sysdeps/linux/c6x/vfork.c
@@ -0,0 +1,26 @@
+/*
+ * Port of uClibc for TMS320C6000 DSP architecture
+ * Copyright (C) 2005 Texas Instruments Incorporated
+ * Author of TMS320C6000 port: Aurelien Jacquiot
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 Library General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <features.h>
+__asm__(" .text\n"
+            "vfork: \n"
+            " MVKL .S1 ___libc_vfork,A0\n"
+            " MVKH .S1 ___libc_vfork,A0\n"
+            " BNOP .S2X A0,5\n");
diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in
index 302fa64..fd55333 100644
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -50,6 +50,7 @@ CSRC-$(UCLIBC_HAS_EPOLL) += epoll.c
 CSRC-$(UCLIBC_HAS_XATTR) += xattr.c
 CSRC-$(UCLIBC_HAS_PROFILING) += noophooks.c #pcprofile.c
 CSRC-$(UCLIBC_SV4_DEPRECATED) += ustat.c
+CSRC- += $(if $(findstring =c6x=,=$(TARGET_ARCH)=),vfork.c)
 CSRC- += $(if $(findstring =sh=,=$(TARGET_ARCH)=),longjmp.c vfork.c)
 CSRC- += $(if $(findstring =sparc=,=$(TARGET_ARCH)=),vfork.c)
 CSRC- += $(if $(findstring =i386=,=$(TARGET_ARCH)=),vfork.c)
diff --git a/libpthread/linuxthreads.old/sysdeps/c6x/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/c6x/pt-machine.h
new file mode 100644
index 0000000..cabd4e3
--- /dev/null
+++ b/libpthread/linuxthreads.old/sysdeps/c6x/pt-machine.h
@@ -0,0 +1,64 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   C6x version.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Aurelien Jacquiot <aurelien.jacquiot at jaluna.com>.
+
+   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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline
+#endif
+
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Spinlock implementation; required.  */
+static inline long int
+testandset (int *spinlock)
+{
+	register unsigned int ret = 1;
+	int dummy;
+	__asm__ __volatile__ ("mvc .s2 CSR, %0\n\tand .s2 -2, %0, %0\n\tmvc .s2 %0, CSR\n"
+			      : "=b" (dummy));
+	
+	if (*spinlock == 0) {
+		*spinlock = 1;
+		ret = 0;
+	}
+	__asm__ __volatile__ ("mvc .s2 CSR, %0\n\tor .s2 1, %0, %0\n\tmvc .s2 %0, CSR\n"
+			      : "=b" (dummy));
+	return ret;
+}
+
+#define WRITE_MEMORY_BARRIER()
+#define READ_MEMORY_BARRIER()
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  get_stack_pointer()
+static inline char * get_stack_pointer(void)
+{
+	char *sp;
+  	__asm__ __volatile__ ("mv .d2 B15, %0" : "=b" (sp));
+	return sp;
+}
+
+#define THREAD_STACK_OFFSET 8
+
+#endif /* pt-machine.h */
-- 
1.7.3.4



More information about the uClibc mailing list