summaryrefslogtreecommitdiff
path: root/ldso/ldso/c6x/dl-sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/c6x/dl-sysdep.h')
-rw-r--r--ldso/ldso/c6x/dl-sysdep.h209
1 files changed, 209 insertions, 0 deletions
diff --git a/ldso/ldso/c6x/dl-sysdep.h b/ldso/ldso/c6x/dl-sysdep.h
new file mode 100644
index 000000000..8f1b122d3
--- /dev/null
+++ b/ldso/ldso/c6x/dl-sysdep.h
@@ -0,0 +1,209 @@
+/* Copyright (C) 2010 Texas Instruments Incorporated
+ * Contributed by Mark Salter <msalter@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)