aboutsummaryrefslogtreecommitdiff
path: root/src/core/dsp/ocl_load
diff options
context:
space:
mode:
authorGil Pitney <gil.pitney@linaro.org>2014-10-28 18:00:42 -0700
committerGil Pitney <gil.pitney@linaro.org>2014-10-28 18:00:42 -0700
commit61b2c94d9e64758e55730be6a3fc9006c171db85 (patch)
treef564f09ebf93ba293dfa225bd374df6f1f37aa01 /src/core/dsp/ocl_load
Initial Commit: Based on TI OpenCL v0.8, originally based on clover.shamrock_v0.8
This is a continuation of the clover OpenCL project: http://people.freedesktop.org/~steckdenis/clover based on the contributions from Texas Instruments for Keystone II DSP device: git.ti.com/opencl and adding contributions from Linaro for ARM CPU-only support. See README.txt for more info, and build instructions. Signed-off-by: Gil Pitney <gil.pitney@linaro.org>
Diffstat (limited to 'src/core/dsp/ocl_load')
-rw-r--r--src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_dynamic.c200
-rw-r--r--src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_dynamic.h53
-rw-r--r--src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_elf32.h160
-rw-r--r--src/core/dsp/ocl_load/C60_DLOAD_REL/c60_reloc.c1101
-rw-r--r--src/core/dsp/ocl_load/C60_DLOAD_REL/c60_reloc.h30
-rw-r--r--src/core/dsp/ocl_load/C60_DLOAD_REL/test_c60_reloc.cpp825
-rw-r--r--src/core/dsp/ocl_load/C60_DLOAD_REL/test_c60_reloc.h101
-rw-r--r--src/core/dsp/ocl_load/CMakeLists.txt26
-rw-r--r--src/core/dsp/ocl_load/DLOAD/ArrayList.c122
-rw-r--r--src/core/dsp/ocl_load/DLOAD/ArrayList.h92
-rw-r--r--src/core/dsp/ocl_load/DLOAD/Queue.h194
-rw-r--r--src/core/dsp/ocl_load/DLOAD/Stack.h155
-rw-r--r--src/core/dsp/ocl_load/DLOAD/dload.c3534
-rw-r--r--src/core/dsp/ocl_load/DLOAD/dload.h334
-rw-r--r--src/core/dsp/ocl_load/DLOAD/dload_endian.c151
-rw-r--r--src/core/dsp/ocl_load/DLOAD/dload_endian.h58
-rw-r--r--src/core/dsp/ocl_load/DLOAD/elf32.c652
-rw-r--r--src/core/dsp/ocl_load/DLOAD/elf32.h756
-rw-r--r--src/core/dsp/ocl_load/DLOAD/relocate.h64
-rw-r--r--src/core/dsp/ocl_load/DLOAD/symtab.h72
-rw-r--r--src/core/dsp/ocl_load/DLOAD/util.h89
-rw-r--r--src/core/dsp/ocl_load/DLOAD/version.h63
-rw-r--r--src/core/dsp/ocl_load/DLOAD/virtual_targets.h90
-rw-r--r--src/core/dsp/ocl_load/DLOAD_API/api_version_change.log33
-rw-r--r--src/core/dsp/ocl_load/DLOAD_API/dload_api.h700
-rw-r--r--src/core/dsp/ocl_load/DLOAD_SYM/symtab.c417
-rw-r--r--src/core/dsp/ocl_load/README8
-rw-r--r--src/core/dsp/ocl_load/Stack.h182
-rw-r--r--src/core/dsp/ocl_load/ocl_load.c139
29 files changed, 10401 insertions, 0 deletions
diff --git a/src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_dynamic.c b/src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_dynamic.c
new file mode 100644
index 0000000..545ba92
--- /dev/null
+++ b/src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_dynamic.c
@@ -0,0 +1,200 @@
+/*
+* c60_dynamic.c
+*
+* C6x-specific dynamic loader functionality
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifdef C60_TARGET
+#include "c60_elf32.h"
+#include <inttypes.h>
+#include "dload.h"
+
+/*****************************************************************************/
+/* c60_process_dynamic_tag() */
+/* */
+/* Process C6x specific dynamic tags. */
+/*****************************************************************************/
+BOOL DLDYN_c60_process_dynamic_tag(DLIMP_Dynamic_Module* dyn_module, int i)
+{
+ switch (dyn_module->dyntab[i].d_tag)
+ {
+ /*------------------------------------------------------------------*/
+ /* DT_C6000_GSYM_OFFSET: Dynamic symbol table is partitioned into */
+ /* local and global symbols. This tag has the */
+ /* offset into the dynamic symbol table where */
+ /* the global symbol table starts. */
+ /*------------------------------------------------------------------*/
+ case DT_C6000_GSYM_OFFSET:
+ dyn_module->gsymtab_offset = dyn_module->dyntab[i].d_un.d_val;
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Found global symbol table: %d\n",
+ dyn_module->gsymtab_offset);
+#endif
+ return TRUE;
+
+ /*------------------------------------------------------------------*/
+ /* DT_C6000_GSTR_OFFSET: Contains the offset into the dynamic */
+ /* string table where the global symbol names */
+ /* start. */
+ /*------------------------------------------------------------------*/
+ case DT_C6000_GSTR_OFFSET:
+ dyn_module->gstrtab_offset = dyn_module->dyntab[i].d_un.d_val;
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Found global string table: %d\n",
+ dyn_module->gstrtab_offset);
+#endif
+ return TRUE;
+
+ /*------------------------------------------------------------------*/
+ /* DT_C6000_DSBT_BASE: Contains address of DSBT in executable or */
+ /* shared object. */
+ /* We store the tag's location in the dynamic */
+ /* module object so that we can update it */
+ /* easily after the sections have been */
+ /* allocated (tag value is relocated). */
+ /*------------------------------------------------------------------*/
+ case DT_C6000_DSBT_BASE:
+ dyn_module->dsbt_base_tagidx = i;
+ return TRUE;
+
+ /*------------------------------------------------------------------*/
+ /* DT_C6000_DSBT_INDEX: Contains specific request for a DSBT */
+ /* index. If this object module doesn't get */
+ /* the index it requested, then the load will */
+ /* fail (object module has already assumed */
+ /* that it got the DSBT index it asks for; */
+ /* references to the DSBT index will not have */
+ /* relocation entries associated with them). */
+ /*------------------------------------------------------------------*/
+ case DT_C6000_DSBT_INDEX:
+ dyn_module->dsbt_index = dyn_module->dyntab[i].d_un.d_val;
+ return TRUE;
+
+ /*------------------------------------------------------------------*/
+ /* DT_C6000_DSBT_SIZE: Contains the size of the DSBT allocated for */
+ /* this object module. It must be big enough */
+ /* to hold the content of the master DSBT. */
+ /*------------------------------------------------------------------*/
+ case DT_C6000_DSBT_SIZE:
+ dyn_module->dsbt_size = dyn_module->dyntab[i].d_un.d_val;
+ return TRUE;
+
+ }
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLDYN_c60_relocate_dynamic_tag_info() */
+/* */
+/* Update any target specific dynamic tag values that are associated with */
+/* a section address. Return TRUE if the tag value is successfully */
+/* updated or if the tag is not associated with a section address, and */
+/* FALSE if we can't find the sectoin associated with the tag or if the */
+/* tag type is not recognized. */
+/* */
+/*****************************************************************************/
+BOOL DLDYN_c60_relocate_dynamic_tag_info(DLIMP_Dynamic_Module *dyn_module,
+ int32_t i)
+{
+ switch (dyn_module->dyntab[i].d_tag)
+ {
+ /*---------------------------------------------------------------------*/
+ /* These tags do not point to sections. */
+ /*---------------------------------------------------------------------*/
+ case DT_C6000_GSYM_OFFSET:
+ case DT_C6000_GSTR_OFFSET:
+ case DT_C6000_DSBT_INDEX:
+ case DT_C6000_DSBT_SIZE:
+ return TRUE;
+
+ /*---------------------------------------------------------------------*/
+ /* DT_C6000_DSBT_BASE: This tag value provides the virtual address of */
+ /* the .dsbt section. We will go find the program */
+ /* header entry associated with the DSBT section */
+ /* and update this tag with the section's run */
+ /* address. */
+ /*---------------------------------------------------------------------*/
+ case DT_C6000_DSBT_BASE:
+ return DLIMP_update_dyntag_section_address(dyn_module, i);
+ }
+
+ DLIF_error(DLET_MISC, "Invalid dynamic tag encountered, %d\n",
+ (int)dyn_module->dyntab[i].d_tag);
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* c60_process_eiosabi() */
+/* */
+/* Process the EI_OSABI value. Verify that the OSABI is supported and set */
+/* any variables which depend on the OSABI. */
+/*****************************************************************************/
+BOOL DLDYN_c60_process_eiosabi(DLIMP_Dynamic_Module* dyn_module)
+{
+ uint8_t osabi = dyn_module->fhdr.e_ident[EI_OSABI];
+
+ if (dyn_module->relocatable)
+ {
+ /*-------------------------------------------------------------------*/
+ /* ELFOSABI_C6000_ELFABI - C6x Baremetal ABI */
+ /*-------------------------------------------------------------------*/
+ if (osabi == ELFOSABI_C6000_ELFABI)
+ return TRUE;
+
+#if 0
+ /*-------------------------------------------------------------------*/
+ /* ELFOSABI_C6000_LINUX - C6x Linux ABI */
+ /* presently unsupported */
+ /*-------------------------------------------------------------------*/
+ if (osabi == ELFOSABI_C6000_LINUX)
+ return TRUE;
+#endif
+ }
+ else
+ {
+ /*-------------------------------------------------------------------*/
+ /* Static executables should have an OSABI of NONE. */
+ /*-------------------------------------------------------------------*/
+ if (osabi == ELFOSABI_NONE)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#endif
diff --git a/src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_dynamic.h b/src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_dynamic.h
new file mode 100644
index 0000000..da99604
--- /dev/null
+++ b/src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_dynamic.h
@@ -0,0 +1,53 @@
+/*
+* c60_dynamic.h
+*
+* Interface into C6x-specific dynamic loader functionality
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef DLOAD_C60_H
+#define DLOAD_C60_H
+
+#include "dload.h"
+
+BOOL DLDYN_c60_process_dynamic_tag(DLIMP_Dynamic_Module* dyn_module, int i);
+BOOL DLDYN_c60_process_eiosabi(DLIMP_Dynamic_Module* dyn_module);
+BOOL DLDYN_c60_relocate_dynamic_tag_info(DLIMP_Dynamic_Module *dyn_module, int32_t i);
+
+#define T_INTSZ 32
+#define T_CHARSZ 8
+#define MEM_INC 8
+#define PTR_SZ 32
+
+#endif
diff --git a/src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_elf32.h b/src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_elf32.h
new file mode 100644
index 0000000..418db17
--- /dev/null
+++ b/src/core/dsp/ocl_load/C60_DLOAD_DYN/c60_elf32.h
@@ -0,0 +1,160 @@
+/*
+* c60_elf32.h
+*
+* C6x-specific data structures for 32-bit ELF object format files.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef C60_ELF32_H
+#define C60_ELF32_H
+
+#include "elf32.h"
+
+/*---------------------------------------------------------------------------*/
+/* C6x specific EI_OSABI values */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ ELFOSABI_C6000_ELFABI = 64, /* C6X Baremetal OSABI */
+ ELFOSABI_C6000_LINUX = 65 /* C6X Linux OSABI */
+};
+
+/*---------------------------------------------------------------------------*/
+/* File Header Flags (value of "e_flags") */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ EF_C6000_REL = 0x01 /* Contains static relocations. A ET_EXEC or */
+ /* ET_DYN file w/ this flag set can be */
+ /* treated as ET_REL during static linking. */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Segment Types (value of "p_type") */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ PT_C6000_PHATTRS = 0x70000000 /* Extended Program Header Attributes*/
+};
+
+/*---------------------------------------------------------------------------*/
+/* C6x specific section types */
+/*---------------------------------------------------------------------------*/
+enum
+{
+
+ /*------------------------------------------------------------------------*/
+ /* Section types defined by the C6x ELFABI. */
+ /* Note: ABI defined section type should be named SHT_C6000_xxx */
+ /*------------------------------------------------------------------------*/
+ SHT_C6000_UNWIND = 0x70000001, /* Exception Index Table */
+ SHT_C6000_PREEMPTMAP = 0x70000002, /* Pre-emption Map */
+
+ SHT_C6000_ATTRIBUTES = 0x70000003, /* Obj File Compatability Attributes */
+
+ /*------------------------------------------------------------------------*/
+ /* The following section types are not part of C6x ABI. As per the ABI, */
+ /* the processor specific values not defined in the ABI are reserved for */
+ /* future use. Here we reserve the range 0x7F000000 through 0x7FFFFFFFF */
+ /* for the TI specific processor section types. */
+ /* Note: TI specific section type should be named SHT_TI_xxx */
+ /*------------------------------------------------------------------------*/
+ SHT_TI_ICODE = 0x7F000000, /* ICODE representation */
+ SHT_TI_XREF = 0x7F000001, /* Symbol cross reference */
+ SHT_TI_HANDLER = 0x7F000002, /* Handler function table */
+ SHT_TI_INITINFO = 0x7F000003, /* Info for C auto-init of variables */
+ SHT_TI_PHATTRS = 0x7F000004 /* Extended Program Header Attributes*/
+};
+
+/*****************************************************************************/
+/* C6x-Specific Dynamic Array Tags (C6x ELF ABI Section ??? - AEGUPD) */
+/* NOTE: */
+/* As per GABI a tag whose value is even number indicates a dynamic tag */
+/* that uses d_ptr. Odd number indicates the use of d_val or doesn't use */
+/* neither d_val nor d_ptr. */
+/*****************************************************************************/
+enum
+{
+ /*------------------------------------------------------------------------*/
+ /* OSABI specific tags: */
+ /* From 0x6000000D thru 0x6FFFF000 */
+ /*------------------------------------------------------------------------*/
+ DT_C6000_GSYM_OFFSET = 0x6000000D, /* d_val -- OSABI Specific -- */
+ DT_C6000_GSTR_OFFSET = 0x6000000F, /* d_val -- OSABI Specific -- */
+
+ /*------------------------------------------------------------------------*/
+ /* Processor specific tags: */
+ /* From 0x70000000 thru 0x7FFFFFFF */
+ /*------------------------------------------------------------------------*/
+ DT_C6000_DSBT_BASE = 0x70000000, /* d_ptr -- Platform Specific -- */
+ DT_C6000_DSBT_SIZE = 0x70000001, /* d_val -- Platform Specific -- */
+ DT_C6000_PREEMPTMAP = 0x70000002, /* d_ptr -- Platform Specific -- */
+ DT_C6000_DSBT_INDEX = 0x70000003 /* d_val -- Platform Specific -- */
+};
+
+/*---------------------------------------------------------------------------*/
+/* C6x Dynamic Relocation Types */
+/*---------------------------------------------------------------------------*/
+typedef enum
+{
+ R_C6000_NONE = 0,
+ R_C6000_ABS32 = 1,
+ R_C6000_ABS16 = 2,
+ R_C6000_ABS8 = 3,
+ R_C6000_PCR_S21 = 4,
+ R_C6000_PCR_S12 = 5,
+ R_C6000_PCR_S10 = 6,
+ R_C6000_PCR_S7 = 7,
+ R_C6000_ABS_S16 = 8,
+ R_C6000_ABS_L16 = 9,
+ R_C6000_ABS_H16 = 10,
+ R_C6000_SBR_U15_B = 11,
+ R_C6000_SBR_U15_H = 12,
+ R_C6000_SBR_U15_W = 13,
+ R_C6000_SBR_S16 = 14,
+ R_C6000_SBR_L16_B = 15,
+ R_C6000_SBR_L16_H = 16,
+ R_C6000_SBR_L16_W = 17,
+ R_C6000_SBR_H16_B = 18,
+ R_C6000_SBR_H16_H = 19,
+ R_C6000_SBR_H16_W = 20,
+ R_C6000_SBR_GOT_U15_W = 21,
+ R_C6000_SBR_GOT_L16_W = 22,
+ R_C6000_SBR_GOT_H16_W = 23,
+ R_C6000_DSBT_INDEX = 24,
+ R_C6000_PREL31 = 25,
+ R_C6000_COPY = 26
+}C60_RELOC_TYPE;
+
+#endif /* C60_ELF32_H */
diff --git a/src/core/dsp/ocl_load/C60_DLOAD_REL/c60_reloc.c b/src/core/dsp/ocl_load/C60_DLOAD_REL/c60_reloc.c
new file mode 100644
index 0000000..3c79e35
--- /dev/null
+++ b/src/core/dsp/ocl_load/C60_DLOAD_REL/c60_reloc.c
@@ -0,0 +1,1101 @@
+/*
+* c60_reloc.c
+*
+* Process C6x-specific dynamic relocations for core dynamic loader.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#include <limits.h>
+#include "relocate.h"
+#include "symtab.h"
+#include "c60_elf32.h"
+#include "dload_api.h"
+#include "util.h"
+#include "dload_endian.h"
+#include "c60_reloc.h"
+
+#define MASK(n,s) (((1 << n) - 1) << s)
+
+/*---------------------------------------------------------------------------*/
+/* C6x Relocations Supported */
+/* */
+/* See the C6000 ELF ABI Specification for more details. */
+/* */
+/* R_C6000_ABS32 | .field X,32 */
+/* R_C6000_ABS16 | .field X,16 */
+/* R_C6000_ABS8 | .field X,8 */
+/* R_C6000_PCR_S21 | B foo */
+/* CALLP foo, B3 */
+/* R_C6000_PCR_S12 | BNOP foo */
+/* R_C6000_PCR_S10 | BPOS foo, A10 */
+/* BDEC foo, A1 */
+/* R_C6000_PCR_S7 | ADDKPC foo, B3, 4 */
+/* R_C6000_ABS_S16 | MVK sym, A0 */
+/* R_C6000_ABS_L16 | MVKL sym, A0 */
+/* MVKLH sym, A0 */
+/* R_C6000_ABS_H16 | MVKH sym, A0 */
+/* R_C6000_SBR_U15_B | LDB *+B14(sym), A1 */
+/* ADDAB B14, sym, A1 */
+/* R_C6000_SBR_U15_H | LDH *+B14(sym), A1 */
+/* ADDAH B14, sym, A1 */
+/* R_C6000_SBR_U15_W | LDW *+B14(sym), A1 */
+/* ADDAW B14, sym, A1 */
+/* R_C6000_SBR_S16 | MVK sym-$bss, A0 */
+/* R_C6000_SBR_L16_B | MVKL (sym-$bss), A0 */
+/* R_C6000_SBR_L16_H | MVKL (sym-$bss)/2,A0 */
+/* R_C6000_SBR_L16_W | MVKL (sym-$bss)/4,A0 */
+/* R_C6000_SBR_H16_B | MVKH (sym-$bss), A0 */
+/* R_C6000_SBR_H16_H | MVKH (sym-$bss)/2,A0 */
+/* R_C6000_SBR_H16_W | MVKH (sym-$bss)/4,A0 */
+/* R_C6000_SBR_GOT_U15_W | LDW *+B14[GOT(sym)],A0 */
+/* R_C6000_SBR_GOT_L16_W | MVKL $DPR_GOT(sym), A0 */
+/* R_C6000_SBR_GOT_H16_W | MVKH $DPR_GOT(sym), A0 */
+/* R_C6000_DSBT_INDEX | LDW *+B14[$DSBT_index()], DP */
+/* */
+/*---------------------------------------------------------------------------*/
+
+/*****************************************************************************/
+/* WRITE_RELOC_R() - Perform a relocation into a buffered segment. */
+/*****************************************************************************/
+static void write_reloc_r(uint8_t* buffered_segment,
+ uint32_t segment_offset,
+ int r_type, uint32_t r)
+{
+ uint32_t* rel_field_ptr = (uint32_t*)(buffered_segment + segment_offset);
+
+#if LOADER_DEBUG
+ /*------------------------------------------------------------------------*/
+ /* Print some details about the relocation we are about to process. */
+ /*------------------------------------------------------------------------*/
+ if(debugging_on)
+ {
+ DLIF_trace("RWRT: segment_offset: %d\n", segment_offset);
+ DLIF_trace("RWRT: buffered_segment: 0x%x\n",
+ (uint32_t)buffered_segment);
+ DLIF_trace("RWRT: rel_field_ptr: 0x%x\n", (uint32_t)rel_field_ptr);
+ DLIF_trace("RWRT: result: 0x%x\n", r);
+ }
+#endif
+
+
+ /*------------------------------------------------------------------------*/
+ /* Given the relocation type, carry out relocation into a 4 byte packet */
+ /* within the buffered segment. */
+ /*------------------------------------------------------------------------*/
+ switch(r_type)
+ {
+ case R_C6000_ABS32:
+ *rel_field_ptr = r;
+ break;
+ case R_C6000_PREL31:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(30,0)) | r;
+ break;
+ case R_C6000_ABS16:
+ *((uint16_t*)(buffered_segment + segment_offset)) = r;
+ break;
+ case R_C6000_ABS8:
+ *((uint8_t*)(buffered_segment + segment_offset)) = r;
+ break;
+ case R_C6000_PCR_S21:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(21,7)) | (r << 7);
+ break;
+ case R_C6000_PCR_S12:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(12,16)) | (r << 16);
+ break;
+ case R_C6000_PCR_S10:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(10,13)) | (r << 13);
+ break;
+ case R_C6000_PCR_S7:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(7,16)) | (r << 16);
+ break;
+
+ case R_C6000_ABS_S16:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(16,7)) | (r << 7);
+ break;
+ case R_C6000_ABS_L16:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(16,7)) | (r << 7);
+ break;
+ case R_C6000_ABS_H16:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(16,7)) | (r << 7);
+ break;
+
+ case R_C6000_SBR_U15_B:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(15,8)) | (r << 8);
+ break;
+ case R_C6000_SBR_U15_H:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(15,8)) | (r << 8);
+ break;
+ case R_C6000_SBR_U15_W:
+ case R_C6000_DSBT_INDEX:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(15,8)) | (r << 8);
+ break;
+
+ case R_C6000_SBR_S16:
+ case R_C6000_SBR_L16_B:
+ case R_C6000_SBR_L16_H:
+ case R_C6000_SBR_L16_W:
+ case R_C6000_SBR_H16_B:
+ case R_C6000_SBR_H16_H:
+ case R_C6000_SBR_H16_W:
+ *rel_field_ptr = (*rel_field_ptr & ~MASK(16,7)) | (r << 7);
+ break;
+
+ /*---------------------------------------------------------------------*/
+ /* Linux "import-as-own" copy relocations are not yet supported. */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_COPY:
+
+ default:
+ DLIF_error(DLET_RELOC,
+ "write_reloc_r called with invalid relocation type!\n");
+ }
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("reloc_field 0x%x\n", *rel_field_ptr);
+#endif
+}
+
+/*****************************************************************************/
+/* PACK_RESULT() - Pack the result of a relocation calculation for storage */
+/* in the relocation field. */
+/*****************************************************************************/
+static int32_t pack_result(int32_t unpacked_result, int r_type)
+{
+ switch(r_type)
+ {
+ case R_C6000_ABS32:
+ case R_C6000_ABS16:
+ case R_C6000_ABS8:
+ case R_C6000_ABS_S16:
+ case R_C6000_ABS_L16:
+ case R_C6000_SBR_U15_B:
+ case R_C6000_SBR_S16:
+ case R_C6000_SBR_L16_B:
+ return unpacked_result;
+
+ case R_C6000_SBR_U15_H:
+ case R_C6000_SBR_L16_H:
+ case R_C6000_PREL31:
+ return unpacked_result >> 1;
+
+ case R_C6000_PCR_S21:
+ case R_C6000_PCR_S12:
+ case R_C6000_PCR_S10:
+ case R_C6000_PCR_S7:
+ case R_C6000_SBR_U15_W:
+ case R_C6000_SBR_L16_W:
+ case R_C6000_DSBT_INDEX:
+ return unpacked_result >> 2;
+
+ case R_C6000_ABS_H16:
+ case R_C6000_SBR_H16_B:
+ return unpacked_result >> 16;
+
+ case R_C6000_SBR_H16_H:
+ return unpacked_result >> 17;
+
+ case R_C6000_SBR_H16_W:
+ return unpacked_result >> 18;
+
+ /*---------------------------------------------------------------------*/
+ /* Linux "import-as-own" copy relocations are not yet supported. */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_COPY:
+
+ default:
+ DLIF_error(DLET_RELOC,
+ "pack_result called with invalid relocation type!\n");
+ return 0;
+ }
+}
+
+/*****************************************************************************/
+/* MASK_RESULT() - Mask the result of a relocation calculation so that it */
+/* fits the size of the relocation type's field. */
+/*****************************************************************************/
+static int32_t mask_result(int32_t unmasked_result, int r_type)
+{
+ switch(r_type)
+ {
+ case R_C6000_ABS8:
+ return unmasked_result & 0xFF;
+
+ case R_C6000_ABS32:
+ return unmasked_result;
+
+ case R_C6000_ABS16:
+ case R_C6000_ABS_S16:
+ case R_C6000_ABS_L16:
+ case R_C6000_ABS_H16:
+ case R_C6000_SBR_S16:
+ case R_C6000_SBR_L16_B:
+ case R_C6000_SBR_L16_H:
+ case R_C6000_SBR_L16_W:
+ case R_C6000_SBR_H16_B:
+ case R_C6000_SBR_H16_H:
+ case R_C6000_SBR_H16_W:
+ return unmasked_result & 0xFFFF;
+
+ case R_C6000_PCR_S21:
+ return unmasked_result & 0x1FFFFF;
+
+ case R_C6000_PCR_S12:
+ return unmasked_result & 0xFFF;
+
+ case R_C6000_PCR_S10:
+ return unmasked_result & 0x3FF;
+
+ case R_C6000_PCR_S7:
+ return unmasked_result & 0x7F;
+
+ case R_C6000_SBR_U15_B:
+ case R_C6000_SBR_U15_H:
+ case R_C6000_SBR_U15_W:
+ case R_C6000_DSBT_INDEX:
+ return unmasked_result & 0x7FFF;
+
+ case R_C6000_PREL31:
+ return unmasked_result & 0x7FFFFFFF;
+
+ /*---------------------------------------------------------------------*/
+ /* Linux "import-as-own" copy relocations are not yet supported. */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_COPY:
+
+ default:
+ DLIF_error(DLET_RELOC,
+ "mask_result called with invalid relocation type!\n");
+ return 0;
+ }
+}
+
+/*****************************************************************************/
+/* REL_OVERFLOW() */
+/* */
+/* Check relocation value against the range associated with a given */
+/* relocation type field size and signedness. */
+/* */
+/*****************************************************************************/
+static BOOL rel_overflow(C60_RELOC_TYPE r_type, int32_t reloc_value)
+{
+ /*------------------------------------------------------------------------*/
+ /* Select appropriate range check based on relocation type. */
+ /*------------------------------------------------------------------------*/
+ switch(r_type)
+ {
+ case R_C6000_ABS16: return ((reloc_value > 65535) ||
+ (reloc_value < -32768));
+ case R_C6000_ABS8: return ((reloc_value > 255) ||
+ (reloc_value < -128));
+ case R_C6000_PCR_S21: return ((reloc_value >= 0x400000) ||
+ (reloc_value < -0x400000));
+ case R_C6000_PCR_S12: return ((reloc_value >= 0x2000) ||
+ (reloc_value < -0x2000));
+ case R_C6000_PCR_S10: return ((reloc_value >= 0x800) ||
+ (reloc_value < -0x800));
+ case R_C6000_PCR_S7: return ((reloc_value >= 0x100) ||
+ (reloc_value < -0x100));
+ case R_C6000_SBR_S16:
+ case R_C6000_ABS_S16: return ((reloc_value >= 0x8000) ||
+ (reloc_value < -0x8000));
+ case R_C6000_SBR_U15_B: return (((uint32_t)reloc_value) >= 0x8000);
+ case R_C6000_SBR_U15_H: return (((uint32_t)reloc_value) >= 0xFFFF);
+ case R_C6000_DSBT_INDEX:
+ case R_C6000_SBR_U15_W: return (((uint32_t)reloc_value) >= 0x1FFFD);
+
+
+ /*---------------------------------------------------------------------*/
+ /* Some relocation types suppress overflow checking at link-time. */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_ABS_L16:
+ case R_C6000_ABS_H16:
+ case R_C6000_SBR_L16_B:
+ case R_C6000_SBR_L16_H:
+ case R_C6000_SBR_L16_W:
+ case R_C6000_SBR_H16_B:
+ case R_C6000_SBR_H16_H:
+ case R_C6000_SBR_H16_W:
+ return 0;
+
+ /*---------------------------------------------------------------------*/
+ /* 32-bit relocation field values are not checked for overflow. */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_ABS32:
+ case R_C6000_PREL31:
+ return 0;
+
+ /*---------------------------------------------------------------------*/
+ /* If relocation type did not appear in the above switch, then we */
+ /* didn't expect to see it. */
+ /*---------------------------------------------------------------------*/
+ default:
+ DLIF_error(DLET_RELOC,
+ "rel_overflow called with invalid relocation type!\n");
+ }
+
+ return 1;
+}
+
+#if LOADER_DEBUG || LOADER_PROFILE
+extern int DLREL_relocations;
+extern time_t DLREL_total_reloc_time;
+#endif
+
+/*****************************************************************************/
+/* RELOC_DO() - Process a single relocation entry. */
+/*****************************************************************************/
+static void reloc_do(C60_RELOC_TYPE r_type,
+ uint32_t segment_vaddr,
+ uint8_t *segment_buffer,
+ uint32_t addend,
+ uint32_t symval,
+ uint32_t spc,
+ int wrong_endian,
+ uint32_t base_pointer,
+ int32_t dsbt_index)
+{
+ int32_t reloc_value = 0;
+
+#if LOADER_DEBUG || LOADER_PROFILE
+ /*------------------------------------------------------------------------*/
+ /* In debug mode, keep a count of the number of relocations processed. */
+ /* In profile mode, start the clock on a given relocation. */
+ /*------------------------------------------------------------------------*/
+ int start_time = 0;
+ if (debugging_on || profiling_on)
+ {
+ DLREL_relocations++;
+ if (profiling_on) start_time = clock();
+ }
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* Calculate the relocation value according to the rules associated with */
+ /* the given relocation type. */
+ /*------------------------------------------------------------------------*/
+ switch(r_type)
+ {
+ /*---------------------------------------------------------------------*/
+ /* Straight-Up Address relocations (address references). */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_ABS32:
+ case R_C6000_ABS16:
+ case R_C6000_ABS8:
+ case R_C6000_ABS_S16:
+ case R_C6000_ABS_L16:
+ case R_C6000_ABS_H16:
+ reloc_value = symval + addend;
+ break;
+
+ /*---------------------------------------------------------------------*/
+ /* PC-Relative relocations (calls and branches). */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_PCR_S21:
+ case R_C6000_PCR_S12:
+ case R_C6000_PCR_S10:
+ case R_C6000_PCR_S7:
+ {
+ /*------------------------------------------------------------------*/
+ /* Add SPC to segment address to get the PC. Mask for exec-packet */
+ /* boundary. */
+ /*------------------------------------------------------------------*/
+ int32_t opnd_p = (spc + segment_vaddr) & 0xffffffe0;
+ reloc_value = symval + addend - opnd_p;
+ break;
+ }
+
+ /*---------------------------------------------------------------------*/
+ /* "Place"-relative relocations (TDEH). */
+ /*---------------------------------------------------------------------*/
+ /* These relocations occur in data and refer to a label that occurs */
+ /* at some signed 32-bit offset from the place where the relocation */
+ /* occurs. */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_PREL31:
+ {
+ /*------------------------------------------------------------------*/
+ /* Compute location of relocation entry and subtract it from the */
+ /* address of the location being referenced (it is computed very */
+ /* much like a PC-relative relocation, but it occurs in data and */
+ /* is called a "place"-relative relocation). */
+ /*------------------------------------------------------------------*/
+ /* If this is an Elf32_Rel type relocation, then addend is assumed */
+ /* to have been scaled when it was unpacked (field << 1). */
+ /*------------------------------------------------------------------*/
+ /* For Elf32_Rela type relocations the addend is assumed to be a */
+ /* signed 32-bit integer value. */
+ /*------------------------------------------------------------------*/
+ /* Offset is not fetch-packet relative; doesn't need to be masked. */
+ /*------------------------------------------------------------------*/
+ int32_t opnd_p = (spc + segment_vaddr);
+ reloc_value = symval + addend - opnd_p;
+ break;
+ }
+
+ /*---------------------------------------------------------------------*/
+ /* Static-Base Relative relocations (near-DP). */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_SBR_U15_B:
+ case R_C6000_SBR_U15_H:
+ case R_C6000_SBR_U15_W:
+ case R_C6000_SBR_S16:
+ case R_C6000_SBR_L16_B:
+ case R_C6000_SBR_L16_H:
+ case R_C6000_SBR_L16_W:
+ case R_C6000_SBR_H16_B:
+ case R_C6000_SBR_H16_H:
+ case R_C6000_SBR_H16_W:
+ reloc_value = symval + addend - base_pointer;
+ break;
+
+ /*---------------------------------------------------------------------*/
+ /* R_C6000_DSBT_INDEX - uses value assigned by the dynamic loader to */
+ /* be the DSBT index for this module as a scaled offset when */
+ /* referencing the DSBT. The DSBT base address is in symval and the */
+ /* static base is in base_pointer. DP-relative offset to slot in */
+ /* DSBT is the offset of the DSBT relative to the DP plus the */
+ /* scaled DSBT index into the DSBT. */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_DSBT_INDEX:
+ reloc_value = ((symval + addend) - base_pointer) + (dsbt_index << 2);
+ break;
+
+ /*---------------------------------------------------------------------*/
+ /* Linux "import-as-own" copy relocation: after DSO initialization, */
+ /* copy the named object from the DSO into the executable's BSS */
+ /*---------------------------------------------------------------------*/
+ /* Linux "import-as-own" copy relocations are not yet supported. */
+ /*---------------------------------------------------------------------*/
+ case R_C6000_COPY:
+
+ /*---------------------------------------------------------------------*/
+ /* Unrecognized relocation type. */
+ /*---------------------------------------------------------------------*/
+ default:
+ DLIF_error(DLET_RELOC,
+ "reloc_do called with invalid relocation type!\n");
+ break;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Overflow checking. Is relocation value out of range for the size and */
+ /* type of the current relocation? */
+ /*------------------------------------------------------------------------*/
+ if (rel_overflow(r_type, reloc_value))
+ DLIF_error(DLET_RELOC, "relocation overflow!\n");
+
+ /*------------------------------------------------------------------------*/
+ /* Move relocation value to appropriate offset for relocation field's */
+ /* location. */
+ /*------------------------------------------------------------------------*/
+ reloc_value = pack_result(reloc_value, r_type);
+
+ /*------------------------------------------------------------------------*/
+ /* Mask packed result to the size of the relocation field. */
+ /*------------------------------------------------------------------------*/
+ reloc_value = mask_result(reloc_value, r_type);
+
+ /*------------------------------------------------------------------------*/
+ /* If necessary, Swap endianness of data at relocation address. */
+ /*------------------------------------------------------------------------*/
+ if (wrong_endian)
+ DLIMP_change_endian32((int32_t*)(segment_buffer + spc));
+
+ /*------------------------------------------------------------------------*/
+ /* Write the relocated 4-byte packet back to the segment buffer. */
+ /*------------------------------------------------------------------------*/
+ write_reloc_r(segment_buffer, spc, r_type, reloc_value);
+
+ /*------------------------------------------------------------------------*/
+ /* Change endianness of segment address back to original. */
+ /*------------------------------------------------------------------------*/
+ if (wrong_endian)
+ DLIMP_change_endian32((int32_t*)(segment_buffer + spc));
+
+#if LOADER_DEBUG || LOADER_PROFILE
+ /*------------------------------------------------------------------------*/
+ /* In profile mode, add elapsed time for this relocation to total time */
+ /* spent doing relocations. */
+ /*------------------------------------------------------------------------*/
+ if (profiling_on)
+ DLREL_total_reloc_time += (clock() - start_time);
+ if (debugging_on)
+ DLIF_trace("reloc_value = 0x%x\n", reloc_value);
+#endif
+}
+
+/*****************************************************************************/
+/* REL_UNPACK_ADDEND() */
+/* */
+/* Unpack addend value from the relocation field. */
+/* */
+/*****************************************************************************/
+static void rel_unpack_addend(C60_RELOC_TYPE r_type,
+ uint8_t *address,
+ uint32_t *addend)
+{
+ /*------------------------------------------------------------------------*/
+ /* C6000 does not support Elf32_Rel type relocations in the dynamic */
+ /* loader core. We will emit an internal error and abort until this */
+ /* support is added. I abort here because this is necessarily a target- */
+ /* specific part of the relocation infrastructure. */
+ /*------------------------------------------------------------------------*/
+ *addend = 0;
+
+ DLIF_error(DLET_RELOC,
+ "Internal Error: unpacking addend values from the relocation "
+ "field is not supported in the C6000 dynamic loader at this "
+ "time; aborting\n");
+ DLIF_exit(1);
+}
+
+/*****************************************************************************/
+/* REL_SWAP_ENDIAN() */
+/* */
+/* Return TRUE if we should change the endianness of a relocation field. */
+/* */
+/*****************************************************************************/
+static BOOL rel_swap_endian(DLIMP_Dynamic_Module *dyn_module,
+ C60_RELOC_TYPE r_type)
+{
+ if (dyn_module->wrong_endian) return TRUE;
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* REL_CHANGE_ENDIAN() */
+/* */
+/* Change the endianness of the relocation field at the specified address */
+/* in the segment's data. */
+/* */
+/*****************************************************************************/
+static void rel_change_endian(C60_RELOC_TYPE r_type, uint8_t *address)
+{
+ /*------------------------------------------------------------------------*/
+ /* On C6000, all instructions are 32-bits wide. */
+ /*------------------------------------------------------------------------*/
+ DLIMP_change_endian32((int32_t *)address);
+}
+
+/*****************************************************************************/
+/* READ_REL_TABLE() */
+/* */
+/* Read in an Elf32_Rel type relocation table. This function allocates */
+/* host memory for the table. */
+/* */
+/*****************************************************************************/
+static void read_rel_table(struct Elf32_Rel **rel_table,
+ int32_t table_offset,
+ uint32_t relnum, uint32_t relent,
+ LOADER_FILE_DESC *fd, BOOL wrong_endian)
+{
+ if (relnum == 0) { *rel_table = NULL; return; }
+
+ *rel_table = (struct Elf32_Rel *)DLIF_malloc(relnum * relent);
+ DLIF_fseek(fd, table_offset, LOADER_SEEK_SET);
+ DLIF_fread(*rel_table, relnum, relent, fd);
+
+ if (wrong_endian)
+ {
+ int i;
+ for (i = 0; i < relnum; i++)
+ DLIMP_change_rel_endian(*rel_table + i);
+ }
+}
+
+/*****************************************************************************/
+/* PROCESS_REL_TABLE() */
+/* */
+/* Process table of Elf32_Rel type relocations. */
+/* */
+/*****************************************************************************/
+static void process_rel_table(DLOAD_HANDLE handle,
+ DLIMP_Loaded_Segment* seg,
+ struct Elf32_Rel *rel_table,
+ uint32_t relnum,
+ int32_t *start_relidx,
+ uint32_t ti_static_base,
+ DLIMP_Dynamic_Module* dyn_module)
+{
+ Elf32_Addr seg_start_addr = seg->input_vaddr;
+ Elf32_Addr seg_end_addr = seg_start_addr + seg->phdr.p_memsz;
+ BOOL found = FALSE;
+ int32_t relidx = *start_relidx;
+
+ /*------------------------------------------------------------------------*/
+ /* If the given start reloc index is out of range, then start from the */
+ /* beginning of the given table. */
+ /*------------------------------------------------------------------------*/
+ if (relidx >= relnum) relidx = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Spin through Elf32_Rel type relocation table. */
+ /*------------------------------------------------------------------------*/
+ for ( ; relidx < relnum; relidx++)
+ {
+ /*---------------------------------------------------------------------*/
+ /* If the relocation offset falls within the segment, process it. */
+ /*---------------------------------------------------------------------*/
+ if (rel_table[relidx].r_offset >= seg_start_addr &&
+ rel_table[relidx].r_offset < seg_end_addr)
+ {
+ Elf32_Addr r_symval = 0;
+ C60_RELOC_TYPE r_type =
+ (C60_RELOC_TYPE)ELF32_R_TYPE(rel_table[relidx].r_info);
+ int32_t r_symid = ELF32_R_SYM(rel_table[relidx].r_info);
+
+ uint8_t *reloc_address = NULL;
+ uint32_t pc = 0;
+ uint32_t addend = 0;
+
+ BOOL change_endian = FALSE;
+
+ found = TRUE;
+
+ /*------------------------------------------------------------------*/
+ /* If symbol definition is not found, don't do the relocation. */
+ /* An error is generated by the lookup function. */
+ /*------------------------------------------------------------------*/
+ if (!DLSYM_canonical_lookup(handle, r_symid, dyn_module, &r_symval))
+ continue;
+
+ /*------------------------------------------------------------------*/
+ /* Addend value is stored in the relocation field. */
+ /* We'll need to unpack it from the data for the segment that is */
+ /* currently being relocated. */
+ /*------------------------------------------------------------------*/
+ pc = rel_table[relidx].r_offset - seg->input_vaddr;
+ reloc_address = (uint8_t *)seg->host_address + pc;
+
+ change_endian = rel_swap_endian(dyn_module, r_type);
+ if (change_endian)
+ rel_change_endian(r_type, reloc_address);
+
+ rel_unpack_addend(
+ (C60_RELOC_TYPE)ELF32_R_TYPE(rel_table[relidx].r_info),
+ reloc_address, &addend);
+
+ /*------------------------------------------------------------------*/
+ /* Perform actual relocation. This is a really wide function */
+ /* interface and could do with some encapsulation. */
+ /*------------------------------------------------------------------*/
+ reloc_do(r_type,
+ seg->phdr.p_vaddr,
+ seg->host_address,
+ addend,
+ r_symval,
+ pc,
+ dyn_module->wrong_endian,
+ ti_static_base,
+ dyn_module->dsbt_index);
+
+ }
+
+ else if (found)
+ break;
+ }
+}
+
+/*****************************************************************************/
+/* READ_RELA_TABLE() */
+/* */
+/* Read in an Elf32_Rela type relocation table. This function allocates */
+/* host memory for the table. */
+/* */
+/*****************************************************************************/
+static void read_rela_table(struct Elf32_Rela **rela_table,
+ int32_t table_offset,
+ uint32_t relanum, uint32_t relaent,
+ LOADER_FILE_DESC *fd, BOOL wrong_endian)
+{
+ if (relanum == 0) { *rela_table = NULL; return; }
+ *rela_table = (struct Elf32_Rela *)DLIF_malloc(relanum * relaent);
+ DLIF_fseek(fd, table_offset, LOADER_SEEK_SET);
+ DLIF_fread(*rela_table, relanum, relaent, fd);
+
+ if (wrong_endian)
+ {
+ int i;
+ for (i = 0; i < relanum; i++)
+ DLIMP_change_rela_endian(*rela_table + i);
+ }
+}
+
+/*****************************************************************************/
+/* PROCESS_RELA_TABLE() */
+/* */
+/* Process a table of Elf32_Rela type relocations. */
+/* */
+/*****************************************************************************/
+static void process_rela_table(DLOAD_HANDLE handle,
+ DLIMP_Loaded_Segment *seg,
+ struct Elf32_Rela *rela_table,
+ uint32_t relanum,
+ int32_t *start_relidx,
+ uint32_t ti_static_base,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ Elf32_Addr seg_start_addr = seg->input_vaddr;
+ Elf32_Addr seg_end_addr = seg_start_addr + seg->phdr.p_memsz;
+ BOOL found = FALSE;
+ int32_t relidx = *start_relidx;
+
+ /*-----------------------------------------------------------------------*/
+ /* If the given start reloc index is out of range, then start from */
+ /* the beginning of the given table. */
+ /*-----------------------------------------------------------------------*/
+ if (relidx > relanum) relidx = 0;
+
+ /*-----------------------------------------------------------------------*/
+ /* Spin through RELA relocation table. */
+ /*-----------------------------------------------------------------------*/
+ for ( ; relidx < relanum; relidx++)
+ {
+ /*-------------------------------------------------------------------*/
+ /* If the relocation offset falls within the segment, process it. */
+ /*-------------------------------------------------------------------*/
+ if (rela_table[relidx].r_offset >= seg_start_addr &&
+ rela_table[relidx].r_offset < seg_end_addr)
+ {
+ Elf32_Addr r_symval;
+ C60_RELOC_TYPE r_type =
+ (C60_RELOC_TYPE)ELF32_R_TYPE(rela_table[relidx].r_info);
+ int32_t r_symid = ELF32_R_SYM(rela_table[relidx].r_info);
+
+ found = TRUE;
+
+ /*---------------------------------------------------------------*/
+ /* If symbol definition is not found, don't do the relocation. */
+ /* An error is generated by the lookup function. */
+ /*---------------------------------------------------------------*/
+ if (!DLSYM_canonical_lookup(handle, r_symid, dyn_module, &r_symval))
+ continue;
+
+ /*---------------------------------------------------------------*/
+ /* Perform actual relocation. This is a really wide function */
+ /* interface and could do with some encapsulation. */
+ /*---------------------------------------------------------------*/
+ reloc_do(r_type,
+ seg->phdr.p_vaddr,
+ seg->host_address,
+ rela_table[relidx].r_addend,
+ r_symval,
+ rela_table[relidx].r_offset - seg->input_vaddr,
+ dyn_module->wrong_endian,
+ ti_static_base,
+ dyn_module->dsbt_index);
+ }
+
+ else if (found)
+ break;
+ }
+}
+
+/*****************************************************************************/
+/* PROCESS_GOT_RELOCS() */
+/* */
+/* Process all GOT relocations. It is possible to have both Elf32_Rel */
+/* and Elf32_Rela type relocations in the same file, so we handle tham */
+/* both. */
+/* */
+/*****************************************************************************/
+static void process_got_relocs(DLOAD_HANDLE handle,
+ struct Elf32_Rel* rel_table, uint32_t relnum,
+ struct Elf32_Rela* rela_table, uint32_t relanum,
+ DLIMP_Dynamic_Module* dyn_module)
+{
+ DLIMP_Loaded_Segment *seg =
+ (DLIMP_Loaded_Segment*)(dyn_module->loaded_module->loaded_segments.buf);
+ uint32_t num_segs = dyn_module->loaded_module->loaded_segments.size;
+ int32_t rel_relidx = 0;
+ int32_t rela_relidx = 0;
+ uint32_t seg_idx = 0;
+ uint32_t ti_static_base = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Get the value of the static base (__TI_STATIC_BASE) which will be */
+ /* passed into the relocation table processing functions. */
+ /*------------------------------------------------------------------------*/
+ if (!DLSYM_lookup_local_symtab("__TI_STATIC_BASE", dyn_module->symtab,
+ dyn_module->symnum, &ti_static_base))
+ DLIF_error(DLET_RELOC, "Could not resolve value of __TI_STATIC_BASE\n");
+
+ /*------------------------------------------------------------------------*/
+ /* Process relocations segment by segment. */
+ /*------------------------------------------------------------------------*/
+ for (seg_idx = 0; seg_idx < num_segs; seg_idx++)
+ {
+ /*---------------------------------------------------------------------*/
+ /* Relocations should not occur in uninitialized segments. */
+ /*---------------------------------------------------------------------*/
+ if (!seg[seg_idx].phdr.p_filesz) continue;
+
+ if (rela_table)
+ process_rela_table(handle, (seg + seg_idx),
+ rela_table, relanum, &rela_relidx,
+ ti_static_base, dyn_module);
+
+ if (rel_table)
+ process_rel_table(handle, (seg + seg_idx),
+ rel_table, relnum, &rel_relidx,
+ ti_static_base, dyn_module);
+ }
+}
+
+/*****************************************************************************/
+/* PROCESS_PLTGOT_RELOCS() */
+/* */
+/* Process all PLTGOT relocation entries. The PLTGOT relocation table */
+/* can be either Elf32_Rel or Elf32_Rela type. All PLTGOT relocations */
+/* ar guaranteed to belong to the same segment. */
+/* */
+/*****************************************************************************/
+static void process_pltgot_relocs(DLOAD_HANDLE handle,
+ void* plt_reloc_table,
+ int reltype,
+ uint32_t pltnum,
+ DLIMP_Dynamic_Module* dyn_module)
+{
+ Elf32_Addr r_offset = (reltype == DT_REL) ?
+ ((struct Elf32_Rel *)plt_reloc_table)->r_offset :
+ ((struct Elf32_Rela *)plt_reloc_table)->r_offset;
+
+ DLIMP_Loaded_Segment* seg =
+ (DLIMP_Loaded_Segment*)(dyn_module->loaded_module->loaded_segments.buf);
+
+ uint32_t num_segs = dyn_module->loaded_module->loaded_segments.size;
+ int32_t plt_relidx = 0;
+ uint32_t seg_idx = 0;
+ uint32_t ti_static_base = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Get the value of the static base (__TI_STATIC_BASE) which will be */
+ /* passed into the relocation table processing functions. */
+ /*------------------------------------------------------------------------*/
+ if (!DLSYM_lookup_local_symtab("__TI_STATIC_BASE", dyn_module->symtab,
+ dyn_module->symnum, &ti_static_base))
+ DLIF_error(DLET_RELOC, "Could not resolve value of __TI_STATIC_BASE\n");
+
+ /*------------------------------------------------------------------------*/
+ /* For each segment s, check if the relocation falls within s. If so, */
+ /* then all other relocations are guaranteed to fall with s. Process */
+ /* all relocations and then return. */
+ /*------------------------------------------------------------------------*/
+ for (seg_idx = 0; seg_idx < num_segs; seg_idx++)
+ {
+ Elf32_Addr seg_start_addr = seg[seg_idx].input_vaddr;
+ Elf32_Addr seg_end_addr = seg_start_addr + seg[seg_idx].phdr.p_memsz;
+
+ /*---------------------------------------------------------------------*/
+ /* Relocations should not occur in uninitialized segments. */
+ /*---------------------------------------------------------------------*/
+ if(!seg[seg_idx].phdr.p_filesz) continue;
+
+ if (r_offset >= seg_start_addr &&
+ r_offset < seg_end_addr)
+ {
+ if (reltype == DT_REL)
+ process_rel_table(handle, (seg + seg_idx),
+ (struct Elf32_Rel *)plt_reloc_table,
+ pltnum, &plt_relidx,
+ ti_static_base, dyn_module);
+ else
+ process_rela_table(handle, (seg + seg_idx),
+ (struct Elf32_Rela *)plt_reloc_table,
+ pltnum, &plt_relidx,
+ ti_static_base, dyn_module);
+
+ break;
+ }
+ }
+}
+
+/*****************************************************************************/
+/* RELOCATE() - Perform RELA and REL type relocations for given ELF object */
+/* file that we are in the process of loading and relocating. */
+/*****************************************************************************/
+void DLREL_c60_relocate(DLOAD_HANDLE handle,
+ LOADER_FILE_DESC *fd, DLIMP_Dynamic_Module *dyn_module)
+{
+ struct Elf32_Dyn *dyn_nugget = dyn_module->dyntab;
+ struct Elf32_Rela *rela_table = NULL;
+ struct Elf32_Rel *rel_table = NULL;
+ struct Elf32_Rela *rela_plt_table = NULL;
+ struct Elf32_Rel *rel_plt_table = NULL;
+
+ /*------------------------------------------------------------------------*/
+ /* Read the size of the relocation table (DT_RELASZ) and the size per */
+ /* relocation (DT_RELAENT) from the dynamic segment. */
+ /*------------------------------------------------------------------------*/
+ uint32_t relasz = DLIMP_get_first_dyntag(DT_RELASZ, dyn_nugget);
+ uint32_t relaent = DLIMP_get_first_dyntag(DT_RELAENT, dyn_nugget);
+ uint32_t relanum = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Read the size of the relocation table (DT_RELSZ) and the size per */
+ /* relocation (DT_RELENT) from the dynamic segment. */
+ /*------------------------------------------------------------------------*/
+ uint32_t relsz = DLIMP_get_first_dyntag(DT_RELSZ, dyn_nugget);
+ uint32_t relent = DLIMP_get_first_dyntag(DT_RELENT, dyn_nugget);
+ uint32_t relnum = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Read the size of the relocation table (DT_PLTRELSZ) and the type of */
+ /* of the PLTGOT relocation table (DT_PLTREL): one of DT_REL or DT_RELA */
+ /*------------------------------------------------------------------------*/
+ uint32_t pltrelsz = DLIMP_get_first_dyntag(DT_PLTRELSZ, dyn_nugget);
+ int pltreltyp = DLIMP_get_first_dyntag(DT_PLTREL, dyn_nugget);
+ uint32_t pltnum = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Find/record DSBT index associated with this module. */
+ /*------------------------------------------------------------------------*/
+ if (is_dsbt_module(dyn_module) &&
+ (dyn_module->dsbt_index == DSBT_INDEX_INVALID))
+ dyn_module->dsbt_index =
+ DLIF_get_dsbt_index(dyn_module->loaded_module->file_handle);
+
+ /*------------------------------------------------------------------------*/
+ /* Read the PLTGOT relocation table from the file */
+ /* The PLTGOT table is a subsection at the end of either the DT_REL or */
+ /* DT_RELA table. The size of the table it belongs to DT_REL(A)SZ */
+ /* includes the size of the PLTGOT table. So it must be adjusted so that */
+ /* the GOT relocation tables only contain actual GOT relocations. */
+ /*------------------------------------------------------------------------*/
+ if (pltrelsz != INT_MAX && pltrelsz != 0)
+ {
+ if (pltreltyp == DT_REL)
+ {
+ pltnum = pltrelsz/relent;
+ relsz -= pltrelsz;
+ read_rel_table((&rel_plt_table),
+ DLIMP_get_first_dyntag(DT_JMPREL, dyn_nugget),
+ pltnum, relent, fd, dyn_module->wrong_endian);
+ }
+
+ else if (pltreltyp == DT_RELA)
+ {
+ pltnum = pltrelsz/relaent;
+ relasz -= pltrelsz;
+ read_rela_table((&rela_plt_table),
+ DLIMP_get_first_dyntag(DT_JMPREL, dyn_nugget),
+ pltnum, relaent, fd, dyn_module->wrong_endian);
+ }
+
+ else
+ {
+ DLIF_error(DLET_RELOC,
+ "DT_PLTREL is invalid: must be either %d or %d\n",
+ DT_REL, DT_RELA);
+ }
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Read the DT_RELA GOT relocation table from the file */
+ /*------------------------------------------------------------------------*/
+ if (relasz != INT_MAX && relasz != 0)
+ {
+ relanum = relasz/relaent;
+ read_rela_table(&rela_table, DLIMP_get_first_dyntag(DT_RELA, dyn_nugget),
+ relanum, relaent, fd, dyn_module->wrong_endian);
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Read the DT_REL GOT relocation table from the file */
+ /*------------------------------------------------------------------------*/
+ if (relsz != INT_MAX && relsz != 0)
+ {
+ relnum = relsz/relent;
+ read_rel_table(&rel_table, DLIMP_get_first_dyntag(DT_REL, dyn_nugget),
+ relnum, relent, fd, dyn_module->wrong_endian);
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Process the PLTGOT relocations */
+ /*------------------------------------------------------------------------*/
+ if (rela_plt_table)
+ process_pltgot_relocs(handle, rela_plt_table, pltreltyp, pltnum,
+ dyn_module);
+
+ if (rel_plt_table)
+ process_pltgot_relocs(handle, rel_plt_table, pltreltyp, pltnum,
+ dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Process the GOT relocations */
+ /*------------------------------------------------------------------------*/
+ if (rel_table || rela_table)
+ process_got_relocs(handle, rel_table, relnum, rela_table, relanum,
+ dyn_module);
+
+ /*-------------------------------------------------------------------------*/
+ /* Free memory used for ELF relocation table copies. */
+ /*-------------------------------------------------------------------------*/
+ if (rela_table) DLIF_free(rela_table);
+ if (rel_table) DLIF_free(rel_table);
+ if (rela_plt_table) DLIF_free(rela_plt_table);
+ if (rel_plt_table) DLIF_free(rel_plt_table);
+}
+
+/*****************************************************************************/
+/* UNIT TESTING INTERFACE */
+/*****************************************************************************/
+#ifdef UNIT_TEST
+void unit_c60_reloc_do(C60_RELOC_TYPE r_type,
+ uint8_t *address_space,
+ uint32_t addend, uint32_t symval, uint32_t pc,
+ uint32_t static_base, int wrong_endian,
+ int32_t dsbt_index)
+{
+ reloc_do(r_type, (uint32_t)address_space, address_space,
+ addend, symval, pc, FALSE, static_base, dsbt_index);
+}
+
+#if 0 /* RELA TYPE RELOCATIONS HAVE ADDEND IN RELOCATION ENTRY */
+void unit_c60_rel_unpack_addend(C60_RELOC_TYPE r_type,
+ uint8_t* address,
+ uint32_t* addend)
+{
+ rel_unpack_addend(r_type, address, addend);
+}
+#endif
+
+BOOL unit_c60_rel_overflow(C60_RELOC_TYPE r_type, int32_t reloc_value)
+{
+ return rel_overflow(r_type, reloc_value);
+}
+#endif
+
diff --git a/src/core/dsp/ocl_load/C60_DLOAD_REL/c60_reloc.h b/src/core/dsp/ocl_load/C60_DLOAD_REL/c60_reloc.h
new file mode 100644
index 0000000..8ccd60e
--- /dev/null
+++ b/src/core/dsp/ocl_load/C60_DLOAD_REL/c60_reloc.h
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated - http://www.ti.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments Incorporated nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+void DLREL_c60_relocate(DLOAD_HANDLE handle, LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module);
diff --git a/src/core/dsp/ocl_load/C60_DLOAD_REL/test_c60_reloc.cpp b/src/core/dsp/ocl_load/C60_DLOAD_REL/test_c60_reloc.cpp
new file mode 100644
index 0000000..acde023
--- /dev/null
+++ b/src/core/dsp/ocl_load/C60_DLOAD_REL/test_c60_reloc.cpp
@@ -0,0 +1,825 @@
+/*
+* test_c60_reloc.cpp
+*
+* C6x Relocation Unit Tests.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#include "test_c60_reloc.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/*****************************************************************************/
+/* C60_TestRelocDo */
+/* */
+/* Tests the C60 version of reloc_do. In cases where multiple relocation */
+/* types are implemented in the same way, only one type is tested. For */
+/* instance, R_C6000_xxx, R_C6000_yyy, and R_C6000_zzz are implemented in */
+/* the exact same way and, therefore, only R_C6000_xxx is tested. */
+/* */
+/* Each test follows the same flow: */
+/* 1. A valid instruction is constructed for the relocation type being */
+/* tested. */
+/* 2. Addend, symbol value, and pc are then created. */
+/* (NOTE: static base is not needed, and so 0 is passed. Also, same */
+/* endianness is assumed.) */
+/* 3. reloc_do() is called */
+/* 4. The result is checked. */
+/* 5. Repeat if variations should be considered. */
+/* */
+/*****************************************************************************/
+//void C60_TestRelocDo::test_R_C6000_NONE() { }
+
+void C60_TestRelocDo::test_R_C6000_ABS32()
+{
+ uint32_t address_space = 0x0;
+ uint32_t addend = 0x4;
+ uint32_t symval = 0x2001000;
+ uint32_t pc = 0x0;
+
+ unit_c60_reloc_do(R_C6000_ABS32,
+ (uint8_t*) &address_space,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(address_space, 0x2001004);
+}
+
+void C60_TestRelocDo::test_R_C6000_ABS16()
+{
+ uint16_t address_space = 0x0;
+ uint32_t addend = 0x4;
+ uint32_t symval = 0xFFE;
+ uint32_t pc = 0x0;
+
+ unit_c60_reloc_do(R_C6000_ABS16,
+ (uint8_t*) &address_space,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(address_space, 0x1002);
+}
+
+void C60_TestRelocDo::test_R_C6000_ABS8()
+{
+ uint8_t address_space = 0x0;
+ uint32_t addend = 0x4;
+ uint32_t symval = 0xE;
+ uint32_t pc = 0x0;
+
+ unit_c60_reloc_do(R_C6000_ABS8,
+ &address_space,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(address_space, 0x12);
+}
+
+/*---------------------------------------------------------------------------*/
+/* PC-Relative Relocation Tests */
+/* */
+/* Our relocation handler assumes that the address of 'opcode' is where the */
+/* relocation is. Therefore, when creating a PCR test case, we will compute */
+/* a value for symval and pc in terms of &opcode. */
+/* */
+/*---------------------------------------------------------------------------*/
+void C60_TestRelocDo::test_R_C6000_PCR_S21()
+{
+ uint32_t opcode = 0x00000010;
+ uint32_t addend = 0x4;
+ uint32_t symval = ((uint32_t)&opcode & 0xffffffe0) + 0x50000;
+ uint32_t pc = 0x0;
+
+ /* Test #1 -- destination is forward from PC */
+ /* PCR21 offset = 0x14001 */
+ unit_c60_reloc_do(R_C6000_PCR_S21,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x00a00090);
+
+ /* Test #2 -- symval definition implies offset is negative */
+ /* PCR21 offset = 0x1d4001 (signed - negative) */
+ opcode = 0x00000010;
+ symval = ((uint32_t)&opcode & 0xffffffe0) - 0xb0000;
+ unit_c60_reloc_do(R_C6000_PCR_S21,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x0ea00090);
+}
+
+void C60_TestRelocDo::test_R_C6000_PCR_S12()
+{
+ uint32_t opcode = 0x00002120; /* BNOP */
+ uint32_t addend = 0x4;
+ uint32_t symval = ((uint32_t)&opcode & 0xffffffe0) + 0x500;
+ uint32_t pc = 0x0;
+
+ /* Test #1 -- destination is forward from PC */
+ /* PCR12 offset = 0x141 */
+ unit_c60_reloc_do(R_C6000_PCR_S12,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x01412120);
+
+ /* Test #2 -- symval definition implies offset is negative */
+ /* PCR12 offset = 0xd41 (signed - negative) */
+ opcode = 0x00002120;
+ symval = ((uint32_t)&opcode & 0xffffffe0) - 0xb00;
+ unit_c60_reloc_do(R_C6000_PCR_S12,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x0d412120);
+}
+
+void C60_TestRelocDo::test_R_C6000_PCR_S10()
+{
+ uint32_t opcode = 0x01001020; /* BDEC */
+ uint32_t addend = 0x4;
+ uint32_t symval = ((uint32_t)&opcode & 0xffffffe0) + 0x50;
+ uint32_t pc = 0x0;
+
+ /* Test #1 -- destination is forward from PC */
+ /* PCR10 offset = 0x15 */
+ unit_c60_reloc_do(R_C6000_PCR_S10,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x0102b020);
+
+ /* Test #2 -- symval definition implies offset is negative */
+ /* PCR10 offset = 0x355 (signed - negative) */
+ opcode = 0x01001020;
+ symval = ((uint32_t)&opcode & 0xffffffe0) - 0xb0;
+ unit_c60_reloc_do(R_C6000_PCR_S10,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x017ab020);
+}
+
+void C60_TestRelocDo::test_R_C6000_PCR_S7()
+{
+ uint32_t opcode = 0x03006160; /* ADDKPC */
+ uint32_t addend = 0x4;
+ uint32_t symval = ((uint32_t)&opcode & 0xffffffe0) + 0x50;
+ uint32_t pc = 0x0;
+
+ /* Test #1 -- destination is forward from PC */
+ /* PCR7 offset = 0x15 */
+ unit_c60_reloc_do(R_C6000_PCR_S7,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x03156160);
+
+ /* Test #2 -- symval definition implies offset is negative */
+ /* PCR7 offset = 0x75 (signed - negative) */
+ opcode = 0x03006160;
+ symval = ((uint32_t)&opcode & 0xffffffe0) - 0x30;
+ unit_c60_reloc_do(R_C6000_PCR_S7,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x03756160);
+}
+
+void C60_TestRelocDo::test_R_C6000_ABS_S16()
+{
+ uint32_t opcode = 0x03000028; /* MVK */
+ uint32_t addend = 0x4;
+ uint32_t symval = 0xFFE;
+ uint32_t pc = 0x0;
+
+ unit_c60_reloc_do(R_C6000_ABS_S16,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x03080128);
+}
+
+void C60_TestRelocDo::test_R_C6000_ABS_L16()
+{
+ uint32_t opcode = 0x03000028; /* MVKL */
+ uint32_t addend = 0x4;
+ uint32_t symval = 0x04560FFE;
+ uint32_t pc = 0x0;
+
+ unit_c60_reloc_do(R_C6000_ABS_L16,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x03080128);
+}
+
+void C60_TestRelocDo::test_R_C6000_ABS_H16()
+{
+ uint32_t opcode = 0x03000068; /* MVKH */
+ uint32_t addend = 0x4;
+ uint32_t symval = 0x04560FFE;
+ uint32_t pc = 0x0;
+
+ unit_c60_reloc_do(R_C6000_ABS_H16,
+ (uint8_t*) &opcode,
+ addend, symval, pc, 0, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x03022b68);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_U15_B()
+{
+ uint32_t opcode = 0x0300002c; /* LDB */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x1357);
+ uint32_t pc = 0x0;
+
+ /* unsigned 15-bit SBR offset = 0x1357 */
+ /* encoded in bits 22 - 8 */
+ unit_c60_reloc_do(R_C6000_SBR_U15_B,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x0313572c);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_U15_H()
+{
+ uint32_t opcode = 0x0300004c; /* LDH */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x2246);
+ uint32_t pc = 0x0;
+
+ /* unsigned 16-bit SBR offset = 0x2246 */
+ /* scaled 15-bit SBR offset = 0x1123 */
+ /* encoded in bits 22 - 8 */
+ unit_c60_reloc_do(R_C6000_SBR_U15_H,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x0311234c);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_U15_W()
+{
+ uint32_t opcode = 0x0300006c; /* LDW */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x448c);
+ uint32_t pc = 0x0;
+
+ /* unsigned 17-bit SBR offset = 0x448c */
+ /* scaled 15-bit SBR offset = 0x1123 */
+ /* encoded in bits 22 - 8 */
+ unit_c60_reloc_do(R_C6000_SBR_U15_W,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x0311236c);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_S16()
+{
+ uint32_t opcode = 0x03000028; /* MVK */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x1357);
+ uint32_t pc = 0x0;
+
+ /* Test #1 positive signed 16-bit offset */
+ /* 16-bit SBR offset = 0x1357 */
+ /* encoded in bits 22-7 of opcode */
+ unit_c60_reloc_do(R_C6000_SBR_S16,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x0309aba8);
+
+ /* Test #2 negative signed 16-bit offset */
+ /* 16-bit SBR offset = 0xeca9 (-0x1357) */
+ /* encoded in bits 22-7 of opcode */
+ symval = (static_base - 0x1357);
+ unit_c60_reloc_do(R_C6000_SBR_S16,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x037654a8);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_L16_B()
+{
+ uint32_t opcode = 0x03000028; /* MVKL */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x11123);
+ uint32_t pc = 0x0;
+
+ /* 16-bit SBR offset = 0x1123 */
+ /* encoded in bits 22-7 of opcode */
+ unit_c60_reloc_do(R_C6000_SBR_L16_B,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x030891a8);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_L16_H()
+{
+ uint32_t opcode = 0x03000028; /* MVKL */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x12246);
+ uint32_t pc = 0x0;
+
+ /* 17-bit SBR offset = 0x12246 */
+ /* scaled SBR offset = 0x9123 */
+ /* encoded in bits 22-7 of opcode */
+ unit_c60_reloc_do(R_C6000_SBR_L16_H,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x034891a8);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_L16_W()
+{
+ uint32_t opcode = 0x03000028; /* MVKL */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x1448c);
+ uint32_t pc = 0x0;
+
+ /* 18-bit SBR offset = 0x1448c */
+ /* scaled SBR offset = 0x5123 */
+ /* encoded in bits 22-7 of opcode */
+ unit_c60_reloc_do(R_C6000_SBR_L16_W,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x032891a8);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_H16_B()
+{
+ uint32_t opcode = 0x03000068; /* MVKH */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x357448c);
+ uint32_t pc = 0x0;
+
+ /* total SBR offset = 0x357448c */
+ /* upper 16-bits of SBR offset = 0x357 */
+ /* encoded in bits 22-7 of opcode */
+ unit_c60_reloc_do(R_C6000_SBR_H16_B,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x0301abe8);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_H16_H()
+{
+ uint32_t opcode = 0x03000068; /* MVKH */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x357448c);
+ uint32_t pc = 0x0;
+
+ /* total SBR offset = 0x357448c */
+ /* scaled SBR offset = 0x1aba246 */
+ /* upper 16-bits of scaled SBR offset = 0x1ab */
+ /* encoded in bits 22-7 of opcode */
+ unit_c60_reloc_do(R_C6000_SBR_H16_H,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x0300d5e8);
+}
+
+void C60_TestRelocDo::test_R_C6000_SBR_H16_W()
+{
+ uint32_t opcode = 0x03000068; /* MVKH */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = (static_base + 0x357448c);
+ uint32_t pc = 0x0;
+
+ /* total SBR offset = 0x357448c */
+ /* scaled SBR offset = 0x0d5d123 */
+ /* upper 16-bits of scaled SBR offset = 0x0d5 */
+ /* encoded in bits 22-7 of opcode */
+ unit_c60_reloc_do(R_C6000_SBR_H16_W,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 0);
+
+ TS_ASSERT_EQUALS(opcode, 0x03006ae8);
+}
+
+/* The DSBT table is accessed via DP-relative addressing with */
+/* an LDW instruction, but the DSBT_INDEX is really an index */
+/* into the DSBT table, the index is scaled to a 4-word offset. */
+void C60_TestRelocDo::test_R_C6000_DSBT_INDEX()
+{
+ uint32_t opcode = 0x0300006c; /* LDW */
+ uint32_t addend = 0x0;
+ uint32_t static_base = 0x04000000;
+ uint32_t symval = static_base;
+ uint32_t pc = 0x0;
+
+ unit_c60_reloc_do(R_C6000_DSBT_INDEX,
+ (uint8_t*) &opcode,
+ addend, symval, pc, static_base, 0, 3);
+
+ TS_ASSERT_EQUALS(opcode, 0x0300036c);
+}
+
+/*****************************************************************************/
+/* C60_TestRelUnpackAddend */
+/* */
+/* Tests the C60 rel_unpack_addend function. */
+/* */
+/* In cases where the addends are unpacked in the same way, only one is */
+/* tested. */
+/* */
+/* All tests follow the same flow: */
+/* */
+/* 1. Create a valid instruction for the relocation type, where the addend */
+/* is packed in the instruction. */
+/* 2. Call rel_unpack_addend(). */
+/* 3. Check that the addend is correct. */
+/* */
+/* Relocations may be tested multiple times to handle variations, such as */
+/* positive/negative addends, extra bits depending on the encoding, etc. */
+/* */
+/* NOTE!! C60 ONLY SUPPORTS RELA TYPE RELOCATIONS, SO ADDEND FIELD IS STORED */
+/* IN RELOCATION ENTRY ITSELF. */
+/*****************************************************************************/
+#if 0
+void C60_TestRelUnpackAddend::test_R_C6000_ABS32()
+{
+ uint32_t address_space=0xFEDCBA9;
+ uint32_t addend;
+
+ unit_c60_rel_unpack_addend(R_C6000_ABS32,
+ (uint8_t*)&address_space,
+ &addend);
+
+ TS_ASSERT_EQUALS(addend, address_space);
+}
+
+void C60_TestRelUnpackAddend::test_R_C6000_ABS16()
+{
+ uint16_t address_space=0x7FFF;
+ uint32_t addend;
+
+ unit_c60_rel_unpack_addend(R_C6000_ABS16,
+ (uint8_t*)&address_space,
+ &addend);
+
+ TS_ASSERT_EQUALS(addend, 0x7FFF);
+
+ address_space = 0x8000;
+
+ unit_c60_rel_unpack_addend(R_C6000_ABS16,
+ (uint8_t*)&address_space,
+ &addend);
+
+ TS_ASSERT_EQUALS(addend, 0xFFFF8000);
+}
+#endif
+
+
+/*****************************************************************************/
+/* C60_TestRelOverflow */
+/* */
+/* Test the C60 rel_overflow function. */
+/* */
+/* In each case, we test the upper and lower bounds of each relocation type. */
+/* Only relocation types where the overflow is checked in rel_overflow are */
+/* considered. In most cases four tests are performed to test the upper and */
+/* lower bounds (1 pass and 1 fail for each). */
+/* */
+/* NOTE!! HAVEN'T REFACTORED OVERFLOW CHECK OUT OF RELOCATION HANDLERS FOR */
+/* C60, SO OVERFLOW SHOULD BE TESTED AS PART OF THE RELOC DO(???) */
+/* */
+/*****************************************************************************/
+void C60_TestRelOverflow::test_R_C6000_ABS16()
+{
+ int32_t reloc_val = 0xFFFF;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x10000;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+
+ reloc_val = -0x8000;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = -0x8001;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_ABS8()
+{
+ int32_t reloc_val = 0xFF;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS8, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x100;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS8, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+
+ reloc_val = -0x80;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS8, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = -0x81;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS8, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_PCR_S21()
+{
+ int32_t reloc_val = 0x3FFFFC;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S21, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x400000;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S21, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+
+ reloc_val = -0x400000;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S21, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = -0x400001;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S21, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_PCR_S12()
+{
+ int32_t reloc_val = 0x1FFC;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S12, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x2000;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S12, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+
+ reloc_val = -0x2000;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S12, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = -0x2001;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S12, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_PCR_S10()
+{
+ int32_t reloc_val = 0x7FC;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S10, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x800;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S10, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+
+ reloc_val = -0x800;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S10, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = -0x801;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S10, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_PCR_S7()
+{
+ int32_t reloc_val = 0xFC;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S7, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x100;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S7, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+
+ reloc_val = -0x100;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S7, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = -0x101;
+
+ rval = unit_c60_rel_overflow(R_C6000_PCR_S7, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_SBR_S16()
+{
+ int32_t reloc_val = 0x7FFF;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_S16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x8000;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_S16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+
+ reloc_val = -0x8000;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_S16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = -0x8001;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_S16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_ABS_S16()
+{
+ int32_t reloc_val = 0x7FFF;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS_S16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x8000;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS_S16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+
+ reloc_val = -0x8000;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS_S16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = -0x8001;
+
+ rval = unit_c60_rel_overflow(R_C6000_ABS_S16, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_SBR_U15_B()
+{
+ uint32_t reloc_val = 0x7FFF;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_U15_B, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x8000;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_U15_B, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_SBR_U15_H()
+{
+ uint32_t reloc_val = 0xFFFE;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_U15_H, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0xFFFF;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_U15_H, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_SBR_U15_W()
+{
+ uint32_t reloc_val = 0x1FFFC;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_U15_W, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x1FFFD;
+
+ rval = unit_c60_rel_overflow(R_C6000_SBR_U15_W, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
+void C60_TestRelOverflow::test_R_C6000_DSBT_INDEX()
+{
+ uint32_t reloc_val = 0x1FFFC;
+ int rval;
+
+ rval = unit_c60_rel_overflow(R_C6000_DSBT_INDEX, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 0);
+
+ reloc_val = 0x1FFFD;
+
+ rval = unit_c60_rel_overflow(R_C6000_DSBT_INDEX, reloc_val);
+
+ TS_ASSERT_EQUALS(rval, 1);
+}
+
diff --git a/src/core/dsp/ocl_load/C60_DLOAD_REL/test_c60_reloc.h b/src/core/dsp/ocl_load/C60_DLOAD_REL/test_c60_reloc.h
new file mode 100644
index 0000000..67a437d
--- /dev/null
+++ b/src/core/dsp/ocl_load/C60_DLOAD_REL/test_c60_reloc.h
@@ -0,0 +1,101 @@
+/*
+* test_c60_reloc.h
+*
+* Specification of C6x-specific relocation handler unit tests.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef _TEST_C60_RELOC_H_
+#define _TEST_C60_RELOC_H_
+#include "c60_elf32.h"
+#include <cxxtest/TestSuite.h>
+
+extern "C"
+{
+extern void unit_c60_reloc_do(C60_RELOC_TYPE r_type, uint8_t* address,
+ uint32_t addend, uint32_t symval, uint32_t pc,
+ uint32_t base_pointer, int wrong_endian, int32_t dsbt_index);
+
+extern void unit_c60_rel_unpack_addend(C60_RELOC_TYPE r_type,
+ uint8_t* address,
+ uint32_t* addend);
+
+extern int unit_c60_rel_overflow(C60_RELOC_TYPE r_type, int32_t reloc_value);
+
+}
+
+class C60_TestRelocDo : public CxxTest::TestSuite
+{
+ public:
+ void test_R_C6000_ABS32();
+ void test_R_C6000_ABS16();
+ void test_R_C6000_ABS8();
+ void test_R_C6000_PCR_S21();
+ void test_R_C6000_PCR_S12();
+ void test_R_C6000_PCR_S10();
+ void test_R_C6000_PCR_S7();
+ void test_R_C6000_ABS_S16();
+ void test_R_C6000_ABS_L16();
+ void test_R_C6000_ABS_H16();
+ void test_R_C6000_SBR_U15_B();
+ void test_R_C6000_SBR_U15_H();
+ void test_R_C6000_SBR_U15_W();
+ void test_R_C6000_SBR_S16();
+ void test_R_C6000_SBR_L16_B();
+ void test_R_C6000_SBR_L16_H();
+ void test_R_C6000_SBR_L16_W();
+ void test_R_C6000_SBR_H16_B();
+ void test_R_C6000_SBR_H16_H();
+ void test_R_C6000_SBR_H16_W();
+ void test_R_C6000_DSBT_INDEX();
+};
+
+class C60_TestRelOverflow : public CxxTest::TestSuite
+{
+ public:
+ void test_R_C6000_ABS16();
+ void test_R_C6000_ABS8();
+ void test_R_C6000_PCR_S21();
+ void test_R_C6000_PCR_S12();
+ void test_R_C6000_PCR_S10();
+ void test_R_C6000_PCR_S7();
+ void test_R_C6000_SBR_S16();
+ void test_R_C6000_ABS_S16();
+ void test_R_C6000_SBR_U15_B();
+ void test_R_C6000_SBR_U15_H();
+ void test_R_C6000_SBR_U15_W();
+ void test_R_C6000_DSBT_INDEX();
+};
+
+#endif /* _TEST_C60_RELOC_H_ */
diff --git a/src/core/dsp/ocl_load/CMakeLists.txt b/src/core/dsp/ocl_load/CMakeLists.txt
new file mode 100644
index 0000000..a459542
--- /dev/null
+++ b/src/core/dsp/ocl_load/CMakeLists.txt
@@ -0,0 +1,26 @@
+include_directories (.
+ C60_DLOAD_REL
+ C60_DLOAD_DYN
+ DLOAD_SYM
+ DLOAD
+ DLOAD_API
+ DLWRAPPER
+ )
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -DC60_TARGET -DLOADER_DEBUG -g -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast")
+
+set(OCL_LOAD_SRC_FILES
+ ocl_load.c
+ C60_DLOAD_REL/c60_reloc.c
+ C60_DLOAD_DYN/c60_dynamic.c
+ DLOAD_SYM/symtab.c
+ DLOAD/ArrayList.c
+ DLOAD/dload.c
+ DLOAD/elf32.c
+ DLOAD/dload_endian.c
+)
+
+add_library(oclload STATIC ${OCL_LOAD_SRC_FILES})
+
+SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
+
diff --git a/src/core/dsp/ocl_load/DLOAD/ArrayList.c b/src/core/dsp/ocl_load/DLOAD/ArrayList.c
new file mode 100644
index 0000000..4452bfc
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/ArrayList.c
@@ -0,0 +1,122 @@
+/*
+* ArrayList.c
+*
+* Array_List is a C implementation of a C++ vector class.
+*
+* This class emulates a resizable array along the lines of a C++
+* vector or Java ArrayList class in C, and uses the convention
+* of passing a pointer to the current "object" as the first
+* argument.
+*
+* Usage is defined as follows:
+*
+* Array_List obj;
+* AL_initialize(&obj, sizeof(type_name));
+*
+* ...
+*
+* type_name *ptr = (type_name*)(obj.buf);
+* for(i = 0; i < AL_size(&obj); i++)
+* do_something_to(ptr[i]);
+* type_name to_append = ...;
+* AL_append(&obj, &to_append);
+*
+* ...
+*
+* AL_destroy(&obj);
+*
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#include <inttypes.h>
+#include <string.h>
+#include "ArrayList.h"
+#include "dload_api.h"
+
+/*****************************************************************************/
+/* AL_INITIALIZE() - Initialize a newly created Array_List object. */
+/*****************************************************************************/
+void AL_initialize(Array_List* obj, int32_t type_size, int32_t num_elem)
+{
+ if (num_elem == 0) num_elem = 1;
+ obj->buf = DLIF_malloc(type_size * num_elem);
+ obj->type_size = type_size;
+ obj->size = 0;
+ obj->buffer_size = num_elem;
+}
+
+/*****************************************************************************/
+/* AL_APPEND() - Append an element to the end of an Array_List. */
+/*****************************************************************************/
+void AL_append(Array_List* obj, void* to_append)
+{
+ /*------------------------------------------------------------------------*/
+ /* If there is already space in the specified buffer for the new data, */
+ /* just append it to the end of the data that is already in the buffer. */
+ /*------------------------------------------------------------------------*/
+ if (obj->size < obj->buffer_size)
+ memcpy(((uint8_t*)obj->buf) + obj->type_size * ((obj->size)++), to_append,
+ obj->type_size);
+
+ /*------------------------------------------------------------------------*/
+ /* Grow the buffer if we need more space to add the new data to it. */
+ /*------------------------------------------------------------------------*/
+ else
+ {
+ void* old_buffer = obj->buf;
+ obj->buffer_size *= 2;
+ obj->buf = DLIF_malloc(obj->buffer_size*obj->type_size);
+ memcpy(obj->buf,old_buffer,obj->size*obj->type_size);
+ DLIF_free(old_buffer);
+ memcpy(((uint8_t*)obj->buf) + obj->type_size *((obj->size)++), to_append,
+ obj->type_size);
+ }
+}
+
+/*****************************************************************************/
+/* AL_SIZE() - Get the number of elements in an Array_List. */
+/*****************************************************************************/
+int32_t AL_size(Array_List* obj)
+{
+ return obj->size;
+}
+
+/*****************************************************************************/
+/* AL_DESTROY() - Free up memory associated with an Array_List that is no */
+/* longer in use. */
+/*****************************************************************************/
+void AL_destroy(Array_List* obj)
+{
+ DLIF_free(obj->buf);
+}
diff --git a/src/core/dsp/ocl_load/DLOAD/ArrayList.h b/src/core/dsp/ocl_load/DLOAD/ArrayList.h
new file mode 100644
index 0000000..2c03788
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/ArrayList.h
@@ -0,0 +1,92 @@
+/*
+* ArrayList.h
+*
+* This implementation of ArrayList is a replacement for the C++
+* vector class in C.
+*
+* This class emulates a resizable array along the lines of a C++
+* vector or Java ArrayList class in C, and uses the convention
+* of passing a pointer to the current "object" as the first
+* argument.
+*
+* Usage is defined as follows:
+*
+* Array_List obj;
+* AL_initialize(&obj, sizeof(type_name));
+*
+* ...
+*
+* type_name *ptr = (type_name*)(obj.buf);
+* for(i = 0; i < AL_size(&obj); i++)
+* do_something_to(ptr[i]);
+* type_name to_append = ...;
+* AL_append(&obj, &to_append);
+*
+* ...
+*
+* AL_destroy(&obj);
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef ARRAYLIST_H
+#define ARRAYLIST_H
+
+#include <inttypes.h>
+
+/**********************************************************************/
+/* Array_List - structure type specification. */
+/**********************************************************************/
+typedef struct
+{
+ void *buf;
+ int32_t type_size;
+ int32_t size;
+ int32_t buffer_size;
+} Array_List;
+
+/*--------------------------------------------------------------------*/
+/* Array_List Member Functions: */
+/* */
+/* AL_initialize() - Initialize a newly created Array_List object. */
+/* AL_append() - Append an element to the end of an Array_List. */
+/* AL_size() - Get number of elements in an Array_List. */
+/* AL_destroy() - Free memory associated with an Array_List that is */
+/* no longer in use. */
+/*--------------------------------------------------------------------*/
+void AL_initialize(Array_List* obj, int32_t type_size, int32_t num_elem);
+void AL_append(Array_List* obj, void* to_append);
+int32_t AL_size(Array_List* obj);
+void AL_destroy(Array_List* obj);
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD/Queue.h b/src/core/dsp/ocl_load/DLOAD/Queue.h
new file mode 100644
index 0000000..3f85c16
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/Queue.h
@@ -0,0 +1,194 @@
+/*
+* Queue.h
+*
+* Interface to Linked List
+* ------------------------
+*
+* This is an implementation of a type-independent linked list class for C.
+* It's basically a template class, but uses macros instead so that it can
+* be compiled with a C-only compiler.
+*
+* To define a linked list class:
+* #include "Queue.h"
+* TYPE_QUEUE_DEFINITION(object_type,Class_Identifier)
+*
+* In a separate C file:
+* #include "Queue.h"
+* TYPE_QUEUE_DEFINITION(object_type,Class_Identifier)
+* TYPE_QUEUE_IMPLEMENTATION(object_type,Class_Identifier)
+*
+* Now, to create a list:
+* Class_Identifier_Queue name;
+* Get it initialized to zero everywhere somehow, maybe like this:
+* Class_Identifier_initialize_queue(&name);
+*
+* To add to the list:
+* Class_Identifier_enqueue(&name, object);
+*
+* To iterate over the list:
+* Class_Identifier_Queue_Node *it = name.front;
+* while(it) { do_something_to_(it->value); it = it->next; }
+*
+* To delete from the list:
+* If it's the first node:
+* Class_Identifier_dequeue(&name);
+* If it's not:
+* predecessor_node->next_ptr = deleted_node->next_ptr;
+* name.size--;
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#include <inttypes.h>
+#include "dload_api.h"
+
+/*****************************************************************************/
+/* TYPE_QUEUE_DEFINITION() - Define structure specifications for a linked */
+/* list of t_name objects. */
+/*****************************************************************************/
+#define TYPE_QUEUE_DEFINITION(t, t_name) \
+struct t_name##_Queue_Node_ \
+{ \
+ t value; \
+ struct t_name##_Queue_Node_* next_ptr; \
+}; \
+typedef struct t_name##_Queue_Node_ t_name##_Queue_Node; \
+ \
+typedef struct \
+{ \
+ t_name##_Queue_Node* front_ptr; \
+ t_name##_Queue_Node* back_ptr; \
+ int32_t size; \
+} t_name##_Queue; \
+ \
+extern void t_name##_initialize_queue(t_name##_Queue* queue); \
+extern void t_name##_enqueue(t_name##_Queue* queue, t to_enqueue); \
+extern t t_name##_dequeue(t_name##_Queue* queue); \
+extern void t_name##_remove(t_name##_Queue* queue, t to_remove);
+
+/*****************************************************************************/
+/* TYPE_QUEUE_INITIALIZER() - Define the initializer to initialize Queues. */
+/*****************************************************************************/
+#define TYPE_QUEUE_INITIALIZER {NULL, NULL, 0}
+
+
+/*****************************************************************************/
+/* TYPE_QUEUE_IMPLEMENTATION() - Define member functions of new linked list */
+/* "class" of t_name objects. */
+/* */
+/* <type>_initialize_queue() - clears the queue */
+/* <type>_enqueue() - adds a <t> type object to the end of the queue */
+/* <type>_dequeue() - remove a <t> type object from the front of the queue */
+/* and provide access to it to the caller */
+/* <type>_remove() - find and remove a <t> type object from the queue */
+/*****************************************************************************/
+#define TYPE_QUEUE_IMPLEMENTATION(t, t_name) \
+void t_name##_initialize_queue (t_name##_Queue* queue) \
+{ \
+ queue->front_ptr = queue->back_ptr = NULL; \
+ queue->size = 0; \
+} \
+void t_name##_enqueue(t_name##_Queue* queue, t to_enqueue) \
+{ \
+ queue->size++; \
+ \
+ if(!queue->back_ptr) \
+ queue->back_ptr = queue->front_ptr = \
+ (t_name##_Queue_Node*) \
+ (DLIF_malloc(sizeof(t_name##_Queue_Node))); \
+ else \
+ { \
+ queue->back_ptr->next_ptr = \
+ (t_name##_Queue_Node*)(DLIF_malloc( \
+ sizeof(t_name##_Queue_Node))); \
+ queue->back_ptr = queue->back_ptr->next_ptr; \
+ } \
+ \
+ queue->back_ptr->value = to_enqueue; \
+ queue->back_ptr->next_ptr = NULL; \
+} \
+ \
+t t_name##_dequeue(t_name##_Queue* queue) \
+{ \
+ t to_ret; \
+ t_name##_Queue_Node* next_ptr = NULL; \
+ \
+ if (!queue->size) return (t) NULL; \
+ \
+ next_ptr = queue->front_ptr->next_ptr; \
+ queue->size--; \
+ to_ret = queue->front_ptr->value; \
+ DLIF_free((void*)(queue->front_ptr)); \
+ \
+ if(!queue->size) \
+ queue->front_ptr = queue->back_ptr = NULL; \
+ else \
+ queue->front_ptr = next_ptr; \
+ \
+ return to_ret; \
+} \
+ \
+void t_name##_remove(t_name##_Queue* queue, t to_remove) \
+{ \
+ t_name##_Queue_Node* prev_ptr = NULL; \
+ t_name##_Queue_Node* curr_ptr = queue->front_ptr; \
+ t_name##_Queue_Node* next_ptr = NULL; \
+ \
+ for (; curr_ptr; curr_ptr = next_ptr) \
+ { \
+ next_ptr = curr_ptr->next_ptr; \
+ if (curr_ptr->value == to_remove) break; \
+ prev_ptr = curr_ptr; \
+ } \
+ \
+ if (curr_ptr) \
+ { \
+ if (prev_ptr) prev_ptr->next_ptr = next_ptr; \
+ queue->size--; \
+ DLIF_free((void*)(curr_ptr)); \
+ } \
+ \
+ if (!queue->size) \
+ queue->front_ptr = queue->back_ptr = NULL; \
+ else \
+ { \
+ if (!prev_ptr) queue->front_ptr = next_ptr; \
+ if (!next_ptr) queue->back_ptr = prev_ptr; \
+ } \
+}
+
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD/Stack.h b/src/core/dsp/ocl_load/DLOAD/Stack.h
new file mode 100644
index 0000000..d36f5e0
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/Stack.h
@@ -0,0 +1,155 @@
+/*
+* Stack.h
+*
+* Interface to Stack
+* ------------------
+*
+* This is an implementation of a type-independent stack implemented as
+* a signly linked list class for C. It's basically a template class, but
+* uses macros instead, so that it can be compiled with a C-only compiler.
+*
+* To define a Stack class:
+* #include "Stack.h"
+* TYPE_STACK_DEFINITION(object_type,Class_Identifier)
+*
+* In a separate C file:
+* #include "Stack.h"
+* TYPE_STACK_DEFINITION(object_type,Class_Identifier)
+* TYPE_STACK_IMPLEMENTATION(object_type,Class_Identifier)
+*
+* Now, to create a stack:
+* struct Class_Identifier_Stack name;
+* Get it initialized to zero everywhere somehow, maybe like this:
+* initialize_stack_Class_Identifier(&name);
+*
+* To add to the stack:
+* push_Class_Identifier(&name, object);
+*
+* To access the top of the stack:
+* Class_Identifier_Stack_Node *tos = name.top_ptr;
+* do_something_to_(tos->value);
+*
+* To delete from the stack:
+* if (name.size > 0) pop_Class_Identifier(&name);
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef STACK_H
+#define STACK_H
+
+#include <inttypes.h>
+#include "dload_api.h"
+
+/*****************************************************************************/
+/* TYPE_STACK_DEFINITION() - Define structure specifications for a last-in, */
+/* first-out linked list of t_name objects. */
+/*****************************************************************************/
+#define TYPE_STACK_DEFINITION(t, t_name) \
+struct t_name##_Stack_Node_ \
+{ \
+ t value; \
+ struct t_name##_Stack_Node_* next_ptr; \
+}; \
+typedef struct t_name##_Stack_Node_ t_name##_Stack_Node; \
+ \
+typedef struct \
+{ \
+ t_name##_Stack_Node* top_ptr; \
+ t_name##_Stack_Node* bottom_ptr; \
+ int size; \
+} t_name##_Stack; \
+ \
+extern void t_name##_initialize_stack(t_name##_Stack* stack); \
+extern void t_name##_push(t_name##_Stack* stack, t to_push); \
+extern t t_name##_pop(t_name##_Stack* stack);
+
+/*****************************************************************************/
+/* TYPE_STACK_DEFINITION() - Define the initializer to initalize Stacks. */
+/*****************************************************************************/
+#define TYPE_STACK_INITIALIZER {NULL, NULL, 0 }
+
+/*****************************************************************************/
+/* TYPE_STACK_IMPLEMENTATION() - Define member functions of new LIFO linked */
+/* list "class" of t_name objects. */
+/* */
+/* <type>_initialize_stack() - clears the stack */
+/* <type>_push() - pushes a <t> type object to the top of the stack */
+/* <type>_pop() - pop a <t> type object from the top of the stack */
+/* and provide access to it to the caller */
+/*****************************************************************************/
+#define TYPE_STACK_IMPLEMENTATION(t, t_name) \
+void t_name##_initialize_stack (t_name##_Stack* stack) \
+{ \
+ stack->top_ptr = stack->bottom_ptr = NULL; \
+ stack->size = 0; \
+} \
+void t_name##_push(t_name##_Stack* stack, t to_push) \
+{ \
+ stack->size++; \
+ \
+ if(!stack->top_ptr) \
+ { \
+ stack->bottom_ptr = stack->top_ptr = \
+ (t_name##_Stack_Node*)(DLIF_malloc(sizeof(t_name##_Stack_Node))); \
+ stack->top_ptr->next_ptr = NULL; \
+ } \
+ else \
+ { \
+ t_name##_Stack_Node* next_ptr = stack->top_ptr; \
+ stack->top_ptr = \
+ (t_name##_Stack_Node*)(DLIF_malloc(sizeof(t_name##_Stack_Node))); \
+ stack->top_ptr->next_ptr = next_ptr; \
+ } \
+ \
+ stack->top_ptr->value = to_push; \
+} \
+ \
+t t_name##_pop(t_name##_Stack* stack) \
+{ \
+ t to_ret; \
+ t_name##_Stack_Node* next_ptr = stack->top_ptr->next_ptr; \
+ \
+ stack->size--; \
+ to_ret = stack->top_ptr->value; \
+ DLIF_free((void*)(stack->top_ptr)); \
+ \
+ if(!stack->size) \
+ stack->top_ptr = stack->bottom_ptr = NULL; \
+ else \
+ stack->top_ptr = next_ptr; \
+ \
+ return to_ret; \
+}
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD/dload.c b/src/core/dsp/ocl_load/DLOAD/dload.c
new file mode 100644
index 0000000..e5924d8
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/dload.c
@@ -0,0 +1,3534 @@
+/*
+* dload.c
+*
+* Core Dynamic Loader Reference Implementation
+*
+* This implementation of the core dynamic loader is platform independent,
+* but it is object file format dependent. In particular, this
+* implementation supports ELF object file format.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#include <limits.h>
+#include <inttypes.h>
+#include <string.h>
+#include <time.h>
+
+#include "ArrayList.h"
+#include "Queue.h"
+#include "Stack.h"
+
+#include "symtab.h"
+#include "dload_endian.h"
+#include "elf32.h"
+#include "dload.h"
+#include "relocate.h"
+#include "dload_api.h"
+
+#ifdef ARM_TARGET
+#include "arm_dynamic.h"
+#endif
+
+#ifdef C60_TARGET
+#include "c60_dynamic.h"
+#endif
+
+#include "virtual_targets.h"
+
+/*---------------------------------------------------------------------------*/
+/* These globals are used only to test the reference client implementation. */
+/*---------------------------------------------------------------------------*/
+int global_argc;
+char **global_argv;
+
+/*---------------------------------------------------------------------------*/
+/* Contains filenames (type const char*) the system is in the process of */
+/* loading. Used to detect cycles in incorrectly compiled ELF binaries. */
+/*---------------------------------------------------------------------------*/
+Array_List DLIMP_module_dependency_list;
+
+/*---------------------------------------------------------------------------*/
+/* Contains objects (type DLIMP_Loaded_Module) that the system has loaded into */
+/* target memory. */
+/*---------------------------------------------------------------------------*/
+TYPE_QUEUE_IMPLEMENTATION(DLIMP_Loaded_Module*, loaded_module_ptr)
+loaded_module_ptr_Queue DLIMP_loaded_objects = TYPE_QUEUE_INITIALIZER;
+
+/*---------------------------------------------------------------------------*/
+/* Dependency Graph Queue - FIFO queue of dynamic modules that are loaded */
+/* when client asks to load a dynamic executable or library. Note that */
+/* dependents that have already been loaded with another module will not */
+/* appear on this queue. */
+/*---------------------------------------------------------------------------*/
+TYPE_STACK_IMPLEMENTATION(DLIMP_Dynamic_Module*, dynamic_module_ptr)
+dynamic_module_ptr_Stack DLIMP_dependency_stack = TYPE_STACK_INITIALIZER;
+
+/*---------------------------------------------------------------------------*/
+/* Current virtual target set after reading the file headers. This is used */
+/* to access target specific functions. */
+/*---------------------------------------------------------------------------*/
+VIRTUAL_TARGET *cur_target = NULL;
+
+/*---------------------------------------------------------------------------*/
+/* Support for profiling performance of dynamic loader core. */
+/*---------------------------------------------------------------------------*/
+#if LOADER_DEBUG
+static clock_t cycle0 = 0;
+static clock_t cycle_end = 0;
+#define profile_start_clock() (cycle0 = clock())
+#define profile_stop_clock() (cycle_end = clock())
+#define profile_cycle_count() (cycle_end - cycle0)
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* The dynamic loader will now create a table TI_init_table to store */
+/* pre-init and init data. This is done because pre-init and */
+/* init functions could reference as-yet unrelocated symbols from other */
+/* modules. As such it is safer to store relevant function addresses and */
+/* execute them only after all modules are relocated. */
+/*---------------------------------------------------------------------------*/
+TYPE_QUEUE_IMPLEMENTATION(IF_single_record*, IF_table)
+IF_table_Queue TI_init_table = TYPE_QUEUE_INITIALIZER;
+
+static VIRTUAL_TARGET *get_vt_obj(int given_id);
+static void read_args_from_section(DLIMP_Loaded_Module* ep_module);
+static BOOL seg_has_space_for_write(DLIMP_Loaded_Module* lmodule, int sz);
+static BOOL write_arguments_to_args_section(DLOAD_HANDLE handle,
+ int argc, char** argv,
+ DLIMP_Loaded_Module *ep_module);
+
+/*****************************************************************************/
+/* DLOAD_create() */
+/* */
+/* Create an instance of the dynamic loader core. */
+/* */
+/* client_handle: Private client token to be returned during select DLIF */
+/* function calls. */
+/* */
+/* returns: an opaque DLOAD core loader handle, identifying this instance.*/
+/* */
+/*****************************************************************************/
+DLOAD_HANDLE DLOAD_create(void *client_handle)
+{
+ LOADER_OBJECT *pLoaderObject = DLIF_malloc(sizeof(LOADER_OBJECT));
+
+ /*-----------------------------------------------------------------------*/
+ /* Fill out the Loader Object: */
+ /*-----------------------------------------------------------------------*/
+ /* Set up initial objects_loading queue. */
+ /*-----------------------------------------------------------------------*/
+ AL_initialize(&(pLoaderObject->DLIMP_module_dependency_list),
+ sizeof (const char*), 1);
+
+ /*-----------------------------------------------------------------------*/
+ /* Initialize Loaded Module Ptr Queue */
+ /*-----------------------------------------------------------------------*/
+ loaded_module_ptr_initialize_queue(&pLoaderObject->DLIMP_loaded_objects);
+
+ /*-----------------------------------------------------------------------*/
+ /* Initialize Dynamic Module Ptr Stack */
+ /*-----------------------------------------------------------------------*/
+ dynamic_module_ptr_initialize_stack(&pLoaderObject->DLIMP_dependency_stack);
+
+ pLoaderObject->file_handle = 1;
+
+ /*-----------------------------------------------------------------------*/
+ /* Store client token, so it can be handed back during DLIF calls */
+ /*-----------------------------------------------------------------------*/
+ pLoaderObject->client_handle = client_handle;
+
+ return((DLOAD_HANDLE)pLoaderObject);
+}
+
+/*****************************************************************************/
+/* DLOAD_destroy() */
+/* */
+/* Remove an instance of the dynamic loader core, and free all resources */
+/* allocated during DLOAD_create(). */
+/* */
+/* client_handle: Private client token to be returned during select DLIF */
+/* function calls. */
+/* Preconditions: 1) handle must be valid. */
+/* 2) Loader instance must be in "UNLOADED" state. */
+/* */
+/*****************************************************************************/
+void DLOAD_destroy(DLOAD_HANDLE handle)
+{
+ LOADER_OBJECT * pLoaderObject;
+
+ pLoaderObject = (LOADER_OBJECT *)handle;
+ AL_destroy(&(pLoaderObject->DLIMP_module_dependency_list));
+
+ /*--------------------------*/
+ /* Free the instance object */
+ /*--------------------------*/
+ DLIF_free (pLoaderObject);
+}
+
+/*****************************************************************************/
+/* DLIMP_get_first_dyntag() */
+/* */
+/* Return value for first tag entry in the given dynamic table whose */
+/* tag type matches the given key. */
+/* */
+/*****************************************************************************/
+uint32_t DLIMP_get_first_dyntag(int tag, struct Elf32_Dyn* dyn_table)
+{
+ /*------------------------------------------------------------------------*/
+ /* Spin through dynamic segment looking for a specific dynamic tag. */
+ /* Return the value associated with the tag, if the tag is found. */
+ /*------------------------------------------------------------------------*/
+ struct Elf32_Dyn *dtp = dyn_table;
+
+ while (dtp->d_tag != DT_NULL)
+ {
+ if (dtp->d_tag == tag) return dtp->d_un.d_val;
+ else dtp++;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Tag wasn't found, return a known bogus value for the tag. */
+ /*------------------------------------------------------------------------*/
+ return INT_MAX;
+}
+
+/*****************************************************************************/
+/* dload_and_allocate_dependencies() */
+/* */
+/* If not already loaded, load each dependent file identified in the */
+/* dynamic segment with a DT_NEEDED tag. Dependent files are listed in */
+/* order and should be loaded in the same order that they appear in the */
+/* dynamic segment. */
+/* */
+/*****************************************************************************/
+static BOOL dload_and_allocate_dependencies( DLOAD_HANDLE handle,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ /*------------------------------------------------------------------------*/
+ /* Spin through each dynamic tag entry in the dynamic segment. */
+ /*------------------------------------------------------------------------*/
+ struct Elf32_Dyn* dyn_nugget = dyn_module->dyntab;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Starting dload_and_allocate_dependencies() for %s ...\n",
+ dyn_module->name);
+#endif
+
+ while(dyn_nugget->d_tag != DT_NULL)
+ {
+ /*---------------------------------------------------------------------*/
+ /* For each DT_NEEDED dynamic tag that we find in the dynamic segment, */
+ /* load the dependent file identified by the so_name value attached */
+ /* to the DT_NEEDED dynamic tag. */
+ /*---------------------------------------------------------------------*/
+ if (dyn_nugget->d_tag == DT_NEEDED)
+ {
+ loaded_module_ptr_Queue_Node* ptr;
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Found DT_NEEDED: %s\n",
+ dyn_module->strtab+dyn_nugget->d_un.d_val);
+#endif
+
+ /*------------------------------------------------------------------*/
+ /* Find out if the file named by the DT_NEEDED tag has already */
+ /* been loaded. If it has, then we only have to bump the use count */
+ /* of the named dependent file. */
+ /*------------------------------------------------------------------*/
+ for (ptr = pHandle->DLIMP_loaded_objects.front_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ {
+
+
+ if (!strcmp(ptr->value->name,
+ dyn_module->strtab + dyn_nugget->d_un.d_val))
+ {
+ ptr->value->use_count++;
+ AL_append(&(dyn_module->loaded_module->dependencies),
+ &(ptr->value->file_handle));
+ break;
+ }
+ }
+
+ /*------------------------------------------------------------------*/
+ /* If the named dependent file has not been loaded, then we ask the */
+ /* client to invoke a load of the dependent file on our behalf. */
+ /*------------------------------------------------------------------*/
+ if (ptr == NULL)
+ {
+ int32_t dependent_handle = DLIF_load_dependent(
+ pHandle->client_handle,
+ dyn_module->strtab +
+ dyn_nugget->d_un.d_val);
+ AL_append(&(dyn_module->loaded_module->dependencies),
+ &dependent_handle);
+ if (dependent_handle == 0) return FALSE;
+ }
+ }
+
+ dyn_nugget++;
+ }
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Finished dload_and_allocate_dependencies() for %s\n",
+ dyn_module->name);
+#endif
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* load_object() */
+/* */
+/* Finish the process of loading an object file. */
+/* */
+/*****************************************************************************/
+static int load_object(LOADER_FILE_DESC *fd, DLIMP_Dynamic_Module *dyn_module)
+{
+ /*------------------------------------------------------------------------*/
+ /* With the dynamic loader already running on the target, we are able to */
+ /* relocate directly into target memory, so there is nothing more to be */
+ /* done (at least in the bare-metal dynamic linking ABI model). */
+ /*------------------------------------------------------------------------*/
+ return 1;
+}
+
+/*****************************************************************************/
+/* write_arguments_to_args_section() */
+/* */
+/* Write argv and argc to .args section. */
+/* */
+/*****************************************************************************/
+static BOOL write_arguments_to_args_section(DLOAD_HANDLE handle,
+ int argc, char** argv,
+ DLIMP_Loaded_Module *ep_module)
+{
+ int mem_inc = MEM_INC;
+ int ptr_sz = PTR_SZ;
+ int p_size = ptr_sz / mem_inc;
+ int i_size = T_INTSZ / mem_inc;
+ int c_size = T_CHARSZ /mem_inc;
+ int argv_offset = 0;
+ int str_offset = 0;
+ int size = 0;
+ int arg;
+ int *targ_argv_pointers = NULL;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ uint8_t *c_args = NULL;
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Write_arguments_to_args_section:\n");
+#endif
+
+ /*-----------------------------------------------------------------------*/
+ /* IF NO ARGUMENTS, ABORT QUIETLY, WITH a SUCCESSFUL CODE. */
+ /*-----------------------------------------------------------------------*/
+ if (argc == 0) return TRUE;
+
+ /*-----------------------------------------------------------------------*/
+ /* __c_args__ points to the beginning of the .args section, if there */
+ /* is one. This is stored in the Loaded Module, and must have a */
+ /* legitimate address. If not, abort with Warning. */
+ /*-----------------------------------------------------------------------*/
+ c_args = ep_module->c_args;
+ if (!c_args || c_args == (uint8_t *)0xFFFFFFFF)
+ {
+ DLIF_warning(DLWT_MISC, "__c_args__ does not have valid value.\n");
+ return FALSE;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* WE OUGHT TO WORRY ABOUT ALIGNMENT: IF SECTION ISN'T PROPERLY ALIGNED, */
+ /* ABORT THE PROCESSING OF ARGUMENTS WITH A NICE ERROR MESSAGE. */
+ /*-----------------------------------------------------------------------*/
+ if (c_args && ((Elf32_Addr)c_args & (MAX(p_size, i_size) - 1)))
+ {
+ DLIF_warning(DLWT_MISC, ".args section not properly aligned\n");
+ return FALSE;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* CALCULATE OFFSET IN TABLE WHERE ARGV AND THE STRINGS WILL BE STORED. */
+ /* NOTE THAT argv MAY NEED MORE ALIGNMENT THAN AN INTEGER, SO ITS OFFSET */
+ /* IS REALLY THE MAXIMUM OF A POINTER SIZE AND INTEGER SIZE. ALSO NOTE */
+ /* WE NEED TO ALLOCATE AN EXTRA POINTER FOR argv[argc]. */
+ /*-----------------------------------------------------------------------*/
+ argv_offset = MAX(p_size, i_size);
+ str_offset = argv_offset + (argc * p_size) + p_size ;
+
+ /*-----------------------------------------------------------------------*/
+ /* CALCULATE SPACE REQUIRED FOR WRITING OUT .args SECTION. CHECK IF THE */
+ /* SEGMENT HAS ENOUGH SPACE AVAILABLE. IF NOT, RETURN WITH ERROR CODE. */
+ /*-----------------------------------------------------------------------*/
+ size = str_offset;
+
+ for (arg = 0; arg < argc; arg++)
+ size += (c_size * (strlen(argv[arg]) + 1));
+
+ if (!seg_has_space_for_write(ep_module, size))
+ {
+ DLIF_warning(DLWT_MISC,
+ "Segment has insufficient space for .args contents\n");
+ return FALSE;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* OVERALL, WE NEED TO CREATE A TARGET IMAGE THAT CORRESPONDS TO: */
+ /* int argc; */
+ /* char *argv[argc]; */
+ /* <strings pointed to by argv> */
+ /* So say, for C6x, for "-v -d", we would need 22 bytes: */
+ /* 4 bytes // argc */
+ /* 4 bytes // argv[0] pointer value */
+ /* 4 bytes // argv[1] pointer value */
+ /* 4 bytes // argv[argc] end of pointer value array, normally 0 */
+ /* 3 bytes // "-v" */
+ /* 3 bytes // "-d" */
+ /*-----------------------------------------------------------------------*/
+
+ /*-----------------------------------------------------------------------*/
+ /* FIRST WRITE OUT ARGC. */
+ /*-----------------------------------------------------------------------*/
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace ("-- Copy %d bytes from 0x%x to 0x%x\n",
+ i_size, (uint32_t) &argc, (uint32_t) c_args);
+#endif
+
+ DLIF_memcpy(pHandle->client_handle, c_args, &argc, i_size);
+
+ /*-----------------------------------------------------------------------*/
+ /* CREATE AN INTERNAL ARRAY OF ARGV POINTER VALUES, THEN WRITE THEM OUT */
+ /*-----------------------------------------------------------------------*/
+ targ_argv_pointers = (int *)DLIF_malloc((argc + 1) * sizeof(int));
+ for (arg = 0; arg < argc ; arg++)
+ {
+ targ_argv_pointers[arg] = (int)(str_offset + c_args);
+ str_offset += (strlen(argv[arg]) + 1) * c_size;
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace ("\t\ttarg_argv_pointers[%d] : 0x%x\n",
+ arg, targ_argv_pointers[arg]);
+#endif
+ }
+
+ targ_argv_pointers[argc] = 0;
+
+ /*-----------------------------------------------------------------------*/
+ /* WRITE OUT THIS INTERNAL ARRAY OF ARGV POINTER VALUES */
+ /*-----------------------------------------------------------------------*/
+ for (arg = 0; arg <= argc; arg++)
+ {
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace ("-- Copy %d bytes from 0x%x to 0x%x\n",
+ p_size, (uint32_t) &targ_argv_pointers[arg],
+ (uint32_t) (c_args + argv_offset));
+#endif
+ DLIF_memcpy(pHandle->client_handle,
+ (void *)(c_args + argv_offset),
+ &targ_argv_pointers[arg],
+ p_size);
+ argv_offset += p_size;
+ }
+
+#if LOADER_DEBUG
+if (debugging_on)
+{
+ DLIF_trace ("\t\targv being copied : 0x%x\n",(uint32_t)argv);
+ for (arg = 0; arg < argc; arg++)
+ {
+ DLIF_trace ("\t\t---\n\t\t&argv[%d] being copied : 0x%x\n", arg,
+ (uint32_t)&argv[arg]);
+ DLIF_trace ("\t\targv[%d] being copied : 0x%x\n",arg,
+ (uint32_t)argv[arg]);
+ DLIF_trace ("\t\targv[%d] being copied : %s\n",arg, (char *)argv[arg]);
+ }
+}
+#endif
+
+ /*-----------------------------------------------------------------------*/
+ /* LASTLY WRITE OUT ALL THE STRINGS. */
+ /*-----------------------------------------------------------------------*/
+ for (arg = 0; arg < argc; arg++)
+ {
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace ("-- Copy %d bytes from 0x%x to 0x%x\n",
+ (uint32_t)strlen(argv[arg]) + 1,
+ (uint32_t)&argv[arg],
+ (uint32_t)(targ_argv_pointers[arg]));
+#endif
+ DLIF_memcpy(pHandle->client_handle,
+ (void *)(targ_argv_pointers[arg]),
+ argv[arg],
+ strlen(argv[arg]) + 1);
+ }
+
+ return TRUE;
+}
+
+
+/*****************************************************************************/
+/* initialize_loaded_module() */
+/* */
+/* Initialize DLIMP_Loaded_Module internal data object associated with a */
+/* dynamic module. This function will also set up a queue of */
+/* DLIMP_Loaded_Segment(s) associated with the loaded module. */
+/* This function is called as we are getting ready to actually load the */
+/* object file contents into target memory. Each segment will get a */
+/* target memory request that it can use to ask the client for target */
+/* memory space. This function will also assign a file handle to the */
+/* loaded module. */
+/* */
+/*---------------------------------------------------------------------------*/
+/* */
+/* In applications that use the DSBT model, this function will also need to */
+/* negotiate the module's DSBT index with the client. */
+/* */
+/*****************************************************************************/
+static void initialize_loaded_module(DLOAD_HANDLE handle,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ int i;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ /*------------------------------------------------------------------------*/
+ /* Allocate a DLIMP_Loaded_Module data structure for the specified ELF */
+ /* file and assign a file handle for it (bumping the file handle counter */
+ /* as we go). */
+ /*------------------------------------------------------------------------*/
+ DLIMP_Loaded_Module *loaded_module =
+ dyn_module->loaded_module = DLIF_malloc(sizeof(DLIMP_Loaded_Module));
+
+#if LOADER_DEBUG || LOADER_PROFILE
+ /*------------------------------------------------------------------------*/
+ /* Start clock on initialization of loaded module object. */
+ /*------------------------------------------------------------------------*/
+ if (debugging_on || profiling_on)
+ {
+ DLIF_trace("Starting initialize_loaded_module() ...\n");
+ if (profiling_on) profile_start_clock();
+ }
+#endif
+
+ if (dyn_module->name)
+ {
+ loaded_module->name = DLIF_malloc(strlen(dyn_module->name) + 1);
+ strcpy(loaded_module->name, dyn_module->name);
+ }
+ else
+ loaded_module->name = "<unknown>";
+
+ loaded_module->file_handle = pHandle->file_handle++;
+ loaded_module->direct_dependent_only = dyn_module->direct_dependent_only;
+ loaded_module->use_count = 1;
+
+ /*------------------------------------------------------------------------*/
+ /* In case we wrapped around the file handle, return error. */
+ /*------------------------------------------------------------------------*/
+ if (pHandle->file_handle == 0)
+ DLIF_error(DLET_MISC, "DLOAD File handle overflowed.\n");
+
+ /*------------------------------------------------------------------------*/
+ /* Initially the loaded module does not have access to its global */
+ /* symbols. These need to be copied from the dynamic module (see call */
+ /* to DLSYM_copy_globals() below). */
+ /* */
+ /* THESE INITIALIZATIONS SHOULD BE MOVED TO AN INIT ROUTINE FOR THE */
+ /* LOADED MODULE */
+ /*------------------------------------------------------------------------*/
+ loaded_module->gsymtab = NULL;
+ loaded_module->gstrtab = NULL;
+ loaded_module->gsymnum = loaded_module->gstrsz = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Initialize the Array_List of dependencies. */
+ /*------------------------------------------------------------------------*/
+ AL_initialize(&(loaded_module->dependencies), sizeof(int), 1);
+
+ if (dyn_module->symtab)
+ DLSYM_copy_globals(dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Initialize the module loaded segments Array_List. */
+ /*------------------------------------------------------------------------*/
+ AL_initialize(&(loaded_module->loaded_segments),
+ sizeof(DLIMP_Loaded_Segment), dyn_module->phnum);
+
+ /*------------------------------------------------------------------------*/
+ /* Spin thru segment headers and process each load segment encountered. */
+ /*------------------------------------------------------------------------*/
+ for (i = 0; i < dyn_module->phnum; i++)
+ if (dyn_module->phdr[i].p_type == PT_LOAD)
+ {
+ /*------------------------------------------------------------------*/
+ /* Note that this is parallel to and does not supplant the ELF */
+ /* phdr tables. */
+ /*------------------------------------------------------------------*/
+ DLIMP_Loaded_Segment seg;
+ seg.obj_desc = DLIF_malloc(sizeof(struct DLOAD_MEMORY_SEGMENT));
+ seg.phdr.p_vaddr = dyn_module->phdr[i].p_vaddr;
+ seg.phdr.p_offset = dyn_module->phdr[i].p_offset;
+ seg.obj_desc->target_page = 0; /*not used*/
+ seg.modified = 0;
+ seg.phdr.p_filesz = seg.obj_desc->objsz_in_bytes
+ = dyn_module->phdr[i].p_filesz;
+ seg.phdr.p_memsz = seg.obj_desc->memsz_in_bytes
+ = dyn_module->phdr[i].p_memsz;
+ seg.phdr.p_align = dyn_module->phdr[i].p_align;
+ seg.phdr.p_flags = dyn_module->phdr[i].p_flags;
+ AL_append(&(loaded_module->loaded_segments), &seg);
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Initialize the DSO termination information for this module. */
+ /* It will be copied over from the enclosing dyn_module object when */
+ /* placement is completed and dyn_module's local copy of the dynamic */
+ /* table is updated. */
+ /*------------------------------------------------------------------------*/
+ loaded_module->fini_array = (Elf32_Addr) NULL;
+ loaded_module->fini_arraysz = 0;
+ loaded_module->fini = (Elf32_Addr) NULL;
+
+#if LOADER_DEBUG || LOADER_PROFILE
+ if (debugging_on || profiling_on)
+ {
+ DLIF_trace("Finished initialize_loaded_module()\n");
+ if (profiling_on)
+ {
+ profile_stop_clock();
+ DLIF_trace("Took %lu cycles.\n",
+ (unsigned long)profile_cycle_count());
+ }
+ }
+#endif
+
+}
+
+/*****************************************************************************/
+/* load_static_segment() */
+/* */
+/* The core dynamic loader requires that a statically linked executable */
+/* be placed in target memory at the location that was determined during */
+/* the static link that created the executable. Failure to get the */
+/* required target memory where the static executable is to be loaded */
+/* will cause the dynamic loader to emit an error and abort the load. */
+/* */
+/*****************************************************************************/
+static BOOL load_static_segment(DLOAD_HANDLE handle, LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ int i;
+ DLIMP_Loaded_Segment* seg = (DLIMP_Loaded_Segment*)
+ (dyn_module->loaded_module->loaded_segments.buf);
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ /*------------------------------------------------------------------------*/
+ /* For each segment in the loaded module, build up a target memory */
+ /* request for the segment, get rights to target memory where we want */
+ /* to load the segment from the client, then get the client to write the */
+ /* segment contents out to target memory to the appropriate address. */
+ /*------------------------------------------------------------------------*/
+ for (i = 0; i < dyn_module->loaded_module->loaded_segments.size; i++)
+ {
+ struct DLOAD_MEMORY_REQUEST targ_req;
+ seg[i].obj_desc->target_page = 0;
+ targ_req.flags = 0;
+
+ /*---------------------------------------------------------------------*/
+ /* This is a static executable. DLIF_allocate should give us the */
+ /* address we ask for or fail. */
+ /*---------------------------------------------------------------------*/
+ if (seg[i].phdr.p_flags & PF_X) targ_req.flags |= DLOAD_SF_executable;
+ if (seg[i].phdr.p_flags & PF_W) targ_req.flags |= DLOAD_SF_writable;
+
+
+ targ_req.align = seg[i].phdr.p_align;
+ seg[i].obj_desc->target_address = (TARGET_ADDRESS)seg[i].phdr.p_vaddr;
+ targ_req.flags &= ~DLOAD_SF_relocatable;
+ targ_req.fp = fd;
+ targ_req.segment = seg[i].obj_desc;
+ targ_req.offset = seg[i].phdr.p_offset;
+ targ_req.flip_endian = dyn_module->wrong_endian;
+
+ /*---------------------------------------------------------------------*/
+ /* Ask the client side of the dynamic loader to allocate target memory */
+ /* for this segment to be loaded into. */
+ /*---------------------------------------------------------------------*/
+ if (!DLIF_allocate(pHandle->client_handle, &targ_req)) return FALSE;
+
+ /*---------------------------------------------------------------------*/
+ /* If there is any initialized data in the segment, we'll first write */
+ /* it into a host writable buffer (DLIF_copy()) and then flush it to */
+ /* target memory. */
+ /*---------------------------------------------------------------------*/
+ if (seg[i].phdr.p_filesz)
+ {
+ DLIF_copy(pHandle->client_handle, &targ_req);
+ DLIF_write(pHandle->client_handle, &targ_req);
+ }
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* relocate_target_dynamic_tag_info() */
+/* */
+/* Update a target specific dynamic tag value that happens to be a */
+/* virtual address of a section. Returns TRUE if the tag was updated or */
+/* is not a virtual address and FALSE if it was not successfully updated */
+/* or was not recognized. */
+/*****************************************************************************/
+static BOOL relocate_target_dynamic_tag_info(DLIMP_Dynamic_Module *dyn_module,
+ int i)
+{
+ return cur_target->relocate_dynamic_tag_info(dyn_module, i);
+}
+
+/*****************************************************************************/
+/* DLIMP_update_dyntag_section_address() */
+/* */
+/* Given the index of a dynamic tag which we happen to know points to a */
+/* section address, find the program header table entry associated with */
+/* the specified address and update the tag value with the real address */
+/* of the section. */
+/* */
+/*****************************************************************************/
+BOOL DLIMP_update_dyntag_section_address(DLIMP_Dynamic_Module *dyn_module,
+ int32_t i)
+{
+ int j;
+ DLIMP_Loaded_Segment *seg = (DLIMP_Loaded_Segment *)
+ (dyn_module->loaded_module->loaded_segments.buf);
+
+ /*------------------------------------------------------------------------*/
+ /* If dynamic tag does not access an existing section, then no update */
+ /* is required. */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->dyntab[i].d_un.d_ptr == (Elf32_Addr)0)
+ { return TRUE; }
+
+ for (j = 0; j < dyn_module->loaded_module->loaded_segments.size; j++)
+ {
+ if ((dyn_module->dyntab[i].d_un.d_ptr >= seg[j].input_vaddr) &&
+ (dyn_module->dyntab[i].d_un.d_ptr <
+ (seg[j].input_vaddr + seg[j].phdr.p_memsz)))
+ {
+ dyn_module->dyntab[i].d_un.d_ptr +=
+ (seg[j].phdr.p_vaddr - seg[j].input_vaddr);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* relocate_dynamic_tag_info() */
+/* */
+/* Once segment allocation has been completed, we'll need to go through */
+/* the dynamic table and update any tag values that happen to be virtual */
+/* addresses of segments (DT_C6000_DSBT_BASE, for example). */
+/* */
+/*****************************************************************************/
+static BOOL relocate_dynamic_tag_info(LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ /*------------------------------------------------------------------------*/
+ /* Spin through dynamic table loking for tags that have a value which is */
+ /* the virtual address of a section. After the sections are allocated, */
+ /* we'll need to update these values with the new address of the section. */
+ /*------------------------------------------------------------------------*/
+ int i;
+ for (i = 0; dyn_module->dyntab[i].d_tag != DT_NULL; i++)
+ {
+ switch (dyn_module->dyntab[i].d_tag)
+ {
+ /*------------------------------------------------------------------*/
+ /* Only tag values that are virtual addresses will be affected. */
+ /*------------------------------------------------------------------*/
+ case DT_NEEDED:
+ case DT_PLTRELSZ:
+ case DT_HASH:
+ case DT_STRTAB:
+ case DT_SYMTAB:
+ case DT_RELA:
+ case DT_RELASZ:
+ case DT_RELAENT:
+ case DT_STRSZ:
+ case DT_SYMENT:
+ case DT_SONAME:
+ case DT_RPATH:
+ case DT_SYMBOLIC:
+ case DT_REL:
+ case DT_RELSZ:
+ case DT_RELENT:
+ case DT_PLTREL:
+ case DT_DEBUG:
+ case DT_TEXTREL:
+ case DT_BIND_NOW:
+ case DT_INIT_ARRAYSZ:
+ case DT_RUNPATH:
+ case DT_FLAGS:
+ case DT_PREINIT_ARRAYSZ:
+ continue;
+
+ /*------------------------------------------------------------------*/
+ /* NOTE!!! */
+ /* case DT_ENCODING: -- tag type has same "id" as DT_PREINIT_ARRAY */
+ /*------------------------------------------------------------------*/
+
+ /*------------------------------------------------------------------*/
+ /* This is a generic dynamic tag whose value is a virtual address */
+ /* of a section. It needs to be relocated to the section's actual */
+ /* address in target memory. */
+ /*------------------------------------------------------------------*/
+ case DT_PREINIT_ARRAY:
+ case DT_INIT:
+ case DT_INIT_ARRAY:
+ if (!DLIMP_update_dyntag_section_address(dyn_module, i))
+ return FALSE;
+
+ continue;
+
+ /*------------------------------------------------------------------*/
+ /* Once we have resolved the actual address of termination function */
+ /* sections, we need to copy their addresses over to the loaded */
+ /* module object (dyn_module will be deleted before we get to */
+ /* unloading the module). */
+ /*------------------------------------------------------------------*/
+ case DT_FINI_ARRAY:
+ case DT_FINI:
+ if (!DLIMP_update_dyntag_section_address(dyn_module, i))
+ return FALSE;
+
+ if (dyn_module->dyntab[i].d_tag == DT_FINI)
+ dyn_module->loaded_module->fini =
+ dyn_module->dyntab[i].d_un.d_ptr;
+ else
+ dyn_module->loaded_module->fini_array =
+ dyn_module->dyntab[i].d_un.d_ptr;
+
+ continue;
+
+ case DT_FINI_ARRAYSZ:
+ dyn_module->loaded_module->fini_arraysz =
+ dyn_module->dyntab[i].d_un.d_val;
+ continue;
+
+ /*------------------------------------------------------------------*/
+ /* Is this a virtual address??? */
+ /*------------------------------------------------------------------*/
+ case DT_JMPREL: /* is this a virtual address??? */
+ continue;
+
+ /*------------------------------------------------------------------*/
+ /* The remaining dynamic tag types should be target specific. If */
+ /* something generic slips through to here, then the handler for */
+ /* relocating target specific dynamic tags should fail. */
+ /*------------------------------------------------------------------*/
+ default:
+ if (!relocate_target_dynamic_tag_info(dyn_module, i))
+ return FALSE;
+ }
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* We've gotten through all of the dynamic table without incident. */
+ /* All dynamic tag values that were virtual section addresses should have */
+ /* been updated with the final address of the section that they point to. */
+ /*------------------------------------------------------------------------*/
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* allocate_dynamic_segments_and relocate_symbols() */
+/* */
+/* Allocate target memory for each segment in this module, getting a */
+/* host-accessible space to copy the content of each segment into. Then */
+/* update the symbol table and program header table to reflect the new */
+/* target address for each segment. Processing of the dynamic relocation */
+/* entries will wait until all dependent files have been loaded and */
+/* allocated into target memory. */
+/* */
+/*---------------------------------------------------------------------------*/
+/* */
+/* The relocation entries in the ELF file do not handle the necessary */
+/* adjustments to the memory addresses in the program header or symbol */
+/* tables. These must be done manually. */
+/* */
+/* This is harder for us than for most dynamic loaders, because we have to */
+/* work in environments without virtual memory and thus where the offsets */
+/* between segments in memory may be different than they were in the file. */
+/* So, even though a dynamic loader usually only has to adjust all the */
+/* segments by a single fixed offset, we need to offset the symbols and */
+/* program header addresses segment by segment. This job is done by the */
+/* function below. */
+/* */
+/*****************************************************************************/
+static BOOL allocate_dynamic_segments_and_relocate_symbols
+ (DLOAD_HANDLE handle,
+ LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ int i,j;
+ DLIMP_Loaded_Segment* seg = (DLIMP_Loaded_Segment*)
+ (dyn_module->loaded_module->loaded_segments.buf);
+ struct Elf32_Ehdr *fhdr = &(dyn_module->fhdr);
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+#if LOADER_DEBUG || LOADER_PROFILE
+ if (debugging_on || profiling_on)
+ {
+ DLIF_trace("Dynamic executable found.\n"
+ "Starting allocate_dynamic_segments_and_relocate_symbols()"
+ "...\n");
+ if (profiling_on) profile_start_clock();
+ }
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* Spin through the list of loaded segments from the current module. */
+ /*------------------------------------------------------------------------*/
+ for (i = 0; i < dyn_module->loaded_module->loaded_segments.size; i++)
+ {
+ /*--------------------------------------------------------------------*/
+ /* Allocate target memory for segment via client-provided target */
+ /* memory API. */
+ /*--------------------------------------------------------------------*/
+ int32_t addr_offset;
+ struct DLOAD_MEMORY_REQUEST targ_req;
+ seg[i].obj_desc->target_page = 0;
+ targ_req.flags = 0;
+ if (seg[i].phdr.p_flags & PF_X) targ_req.flags |= DLOAD_SF_executable;
+ if (seg[i].phdr.p_flags & PF_W) targ_req.flags |= DLOAD_SF_writable;
+
+ targ_req.align = 0x20;
+ seg[i].obj_desc->target_address = (TARGET_ADDRESS)seg[i].phdr.p_vaddr;
+ targ_req.flags |= DLOAD_SF_relocatable;
+ targ_req.fp = fd;
+ targ_req.segment = seg[i].obj_desc;
+ targ_req.offset = seg[i].phdr.p_offset;
+ targ_req.flip_endian = dyn_module->wrong_endian;
+
+ if (!DLIF_allocate(pHandle->client_handle, &targ_req))
+ {
+ DLIF_error(DLET_MEMORY, "DLIF allocation failure.\n");
+ return FALSE;
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* Calculate the offset we need to adjust segment header and symbol */
+ /* table addresses. */
+ /*--------------------------------------------------------------------*/
+ addr_offset = (int32_t)(seg[i].obj_desc->target_address) -
+ (int32_t)(seg[i].phdr.p_vaddr);
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ {
+ DLIF_trace("Segment %d (at 0x%x, 0x%x bytes) relocated to 0x%x\n", i,
+ (int32_t)(seg[i].phdr.p_vaddr),
+ (int32_t)(seg[i].phdr.p_memsz),
+ (int32_t)(seg[i].obj_desc->target_address));
+ DLIF_trace("Addr Offset is 0x%x\n", addr_offset);
+ }
+#endif
+
+ /*--------------------------------------------------------------------*/
+ /* Update program entry point if needed. Need to replace to deal */
+ /* with full ELF initialization routine. */
+ /*--------------------------------------------------------------------*/
+ if (dyn_module->relocate_entry_point &&
+ fhdr->e_entry >= (Elf32_Addr)(seg[i].phdr.p_vaddr) &&
+ fhdr->e_entry <
+ (Elf32_Addr)((uint8_t*)(seg[i].phdr.p_vaddr) +
+ (uint32_t)(seg[i].phdr.p_memsz)))
+ {
+#if LOADER_DEBUG
+ if (debugging_on)
+ {
+ DLIF_trace("Entry point 0x%x relocated to 0x%x\n",
+ fhdr->e_entry, fhdr->e_entry + addr_offset);
+ }
+#endif
+ fhdr->e_entry += addr_offset;
+
+ /*------------------------------------------------------------------*/
+ /* Mark the entry point as being relocated so we will not do it */
+ /* again. */
+ /*------------------------------------------------------------------*/
+ dyn_module->relocate_entry_point = FALSE;
+ }
+
+ /*---------------------------------------------------------------------*/
+ /* Fix program header entries in segment and Elf32_Phdr structs. */
+ /*---------------------------------------------------------------------*/
+ for (j = 0; j < fhdr->e_phnum; j++)
+ if (dyn_module->phdr[j].p_vaddr == (Elf32_Addr)seg[i].phdr.p_vaddr)
+ {
+ dyn_module->phdr[j].p_vaddr += addr_offset;
+ dyn_module->phdr[i].p_paddr += addr_offset;
+ break;
+ }
+
+ seg[i].input_vaddr = (Elf32_Addr)(seg[i].phdr.p_vaddr);
+ seg[i].phdr.p_vaddr += addr_offset;
+
+ /*---------------------------------------------------------------------*/
+ /* Great, now the hard part: fix offsets in symbols. It would be nice */
+ /* if there were an easier way to deal with this. */
+ /*---------------------------------------------------------------------*/
+ {
+ struct Elf32_Sym *gsymtab =
+ ((struct Elf32_Sym*)(dyn_module->loaded_module->gsymtab));
+ Elf32_Addr segment_start = (Elf32_Addr)seg[i].phdr.p_vaddr;
+ Elf32_Addr segment_end = (Elf32_Addr)seg[i].phdr.p_vaddr +
+ seg[i].phdr.p_memsz;
+ Elf32_Word global_index = dyn_module->symnum -
+ dyn_module->loaded_module->gsymnum;
+
+ for (j = 0; j < dyn_module->symnum; j++)
+ {
+ /*---------------------------------------------------------------*/
+ /* Get the relocated symbol value. */
+ /*---------------------------------------------------------------*/
+ Elf32_Addr symval_adj = dyn_module->symtab[j].st_value +
+ addr_offset;
+
+ /*---------------------------------------------------------------*/
+ /* If the symbol is defined in this segment, update the symbol */
+ /* value and mark the symbol so that we don't relocate it again. */
+ /*---------------------------------------------------------------*/
+ if (symval_adj >= segment_start && symval_adj < segment_end &&
+ dyn_module->symtab[j].st_shndx != INT16_MAX)
+ {
+ dyn_module->symtab[j].st_value = symval_adj;
+
+ /*------------------------------------------------------------*/
+ /* The module symbol table only has the global symbols. */
+ /*------------------------------------------------------------*/
+ if (j >= global_index)
+ gsymtab[j-global_index].st_value = symval_adj;
+
+ /*------------------------------------------------------------*/
+ /* Mark the symbol as relocated. */
+ /*------------------------------------------------------------*/
+ dyn_module->symtab[j].st_shndx = INT16_MAX;
+ }
+ }
+ }
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Update dynamic tag information. Some dynamic tags have values which */
+ /* are virtual addresses of sections. These values need to be updated */
+ /* once segment allocation is completed and the new segment addresses are */
+ /* known. */
+ /*------------------------------------------------------------------------*/
+ /* We should only traverse through the dynamic table once because we want */
+ /* to avoid the possibility of updating the same tag multiple times (an */
+ /* error, if it happens). */
+ /*------------------------------------------------------------------------*/
+ if (!relocate_dynamic_tag_info(fd, dyn_module))
+ {
+ DLIF_error(DLET_MISC, "Failed dynamic table update.\n");
+ return FALSE;
+ }
+
+#if LOADER_DEBUG || LOADER_PROFILE
+ if (debugging_on || profiling_on)
+ {
+ DLIF_trace("Finished allocate_dynamic_segments_and_relocate_symbols()\n");
+ if (profiling_on)
+ {
+ profile_stop_clock();
+ DLIF_trace("Took %lu cycles.\n", (unsigned long) profile_cycle_count());
+ }
+ }
+#endif
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* delete_DLIMP_Loaded_Module() */
+/* */
+/* Free host memory associated with a DLIMP_Loaded_Module data structure */
+/* and all of the DLIMP_Loaded_Segment objects that are associated with */
+/* it. */
+/* */
+/*****************************************************************************/
+static void delete_DLIMP_Loaded_Module(DLOAD_HANDLE handle,
+ DLIMP_Loaded_Module **pplm)
+{
+ DLIMP_Loaded_Module *loaded_module = *pplm;
+ DLIMP_Loaded_Segment *segments = (DLIMP_Loaded_Segment*)
+ (loaded_module->loaded_segments.buf);
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ /*-----------------------------------------------------------------------*/
+ /* Spin through the segments attached to this loaded module, freeing up */
+ /* any target memory that was allocated by the client for the segment. */
+ /*-----------------------------------------------------------------------*/
+ int i;
+ for (i = 0; i < loaded_module->loaded_segments.size; i++)
+ {
+ if (!DLIF_release(pHandle->client_handle, segments[i].obj_desc))
+ DLIF_error(DLET_MISC, "Failed call to DLIF_release!\n");;
+ DLIF_free(segments[i].obj_desc);
+ }
+
+ /*----------------------------------------------------------------------*/
+ /* Hacky way of indicating that the base image is no longer available. */
+ /* WHHHHAAAAAAATTT!?!?!?!?!?! */
+ /*----------------------------------------------------------------------*/
+ if (loaded_module->file_handle == DLIMP_application_handle)
+ DLIMP_application_handle = 0;
+
+ /*-----------------------------------------------------------------------*/
+ /* Free host heap memory that was allocated for the internal loaded */
+ /* module data structure members. */
+ /*-----------------------------------------------------------------------*/
+ if (loaded_module->name) DLIF_free(loaded_module->name);
+ if (loaded_module->gsymtab) DLIF_free(loaded_module->gsymtab);
+ loaded_module->gsymnum = 0;
+ if (loaded_module->gstrtab) DLIF_free(loaded_module->gstrtab);
+ loaded_module->gstrsz = 0;
+ AL_destroy(&(loaded_module->loaded_segments));
+ AL_destroy(&(loaded_module->dependencies));
+
+ /*-----------------------------------------------------------------------*/
+ /* Finally, free the host memory for the loaded module object, then NULL */
+ /* the pointer that was passed in. */
+ /*-----------------------------------------------------------------------*/
+ DLIF_free(loaded_module);
+ *pplm = NULL;
+}
+
+/*****************************************************************************/
+/* new_DLIMP_Dynamic_Module() */
+/* */
+/* Allocate a dynamic module data structure from host memory and */
+/* initialize its members to their default values. */
+/* */
+/*****************************************************************************/
+static DLIMP_Dynamic_Module *new_DLIMP_Dynamic_Module(LOADER_FILE_DESC *fd)
+{
+ /*-----------------------------------------------------------------------*/
+ /* Allocate space for dynamic module data structure from host memory. */
+ /*-----------------------------------------------------------------------*/
+ DLIMP_Dynamic_Module *dyn_module =
+ (DLIMP_Dynamic_Module *)DLIF_malloc(sizeof(DLIMP_Dynamic_Module));
+
+ /*-----------------------------------------------------------------------*/
+ /* Initialize data members of the new dynamic module data structure. */
+ /*-----------------------------------------------------------------------*/
+ dyn_module->name = NULL;
+ dyn_module->fd = fd;
+ dyn_module->phdr = NULL;
+ dyn_module->phnum = 0;
+ dyn_module->strtab = NULL;
+ dyn_module->strsz = 0;
+ dyn_module->dyntab = NULL;
+ dyn_module->symtab = NULL;
+ dyn_module->symnum = 0;
+ dyn_module->gsymtab_offset = 0;
+ dyn_module->gstrtab_offset = 0;
+ dyn_module->c_args = NULL;
+ dyn_module->argc = 0;
+ dyn_module->argv = NULL;
+ dyn_module->loaded_module = NULL;
+ dyn_module->wrong_endian = 0;
+ dyn_module->direct_dependent_only = TRUE;
+ dyn_module->relocatable = FALSE;
+ dyn_module->relocate_entry_point = TRUE;
+
+ dyn_module->dsbt_size = 0;
+ dyn_module->dsbt_index = DSBT_INDEX_INVALID;
+ dyn_module->dsbt_base_tagidx = -1;
+
+ dyn_module->preinit_array_idx = -1;
+ dyn_module->preinit_arraysz = 0;
+ dyn_module->init_idx = -1;
+ dyn_module->init_array_idx = -1;
+ dyn_module->init_arraysz = 0;
+
+ return dyn_module;
+}
+
+/*****************************************************************************/
+/* detach_loaded_module() */
+/* */
+/* Detach loaded module data structure from given dynamic module. When */
+/* an object file has been successfully loaded, the loader core will */
+/* detach the loaded module data structure from the dynamic module data */
+/* structure because the loaded module must continue to persist until is */
+/* is actually unloaded from target memory. If there is a problem with */
+/* the load, then the host memory associated with the loaded module will */
+/* be released as part of the destruction of the dynamic module. */
+/* */
+/*****************************************************************************/
+static
+DLIMP_Loaded_Module *detach_loaded_module(DLIMP_Dynamic_Module *dyn_module)
+{
+ if (dyn_module && dyn_module->loaded_module)
+ {
+ DLIMP_Loaded_Module *loaded_module = dyn_module->loaded_module;
+ dyn_module->loaded_module = NULL;
+ return loaded_module;
+ }
+
+ return NULL;
+}
+/*****************************************************************************/
+/* delete_DLIMP_Dynamic_Module() */
+/* */
+/* Remove local copies of the string table, symbol table, program header */
+/* table, and dynamic table. */
+/* */
+/*****************************************************************************/
+static void delete_DLIMP_Dynamic_Module(DLOAD_HANDLE handle,
+ DLIMP_Dynamic_Module **ppdm)
+{
+ DLIMP_Dynamic_Module *dyn_module = NULL;
+
+ if (!ppdm || (*ppdm == NULL))
+ {
+ DLIF_error(DLET_MISC,
+ "Internal Error: invalid argument to dynamic module "
+ "destructor function; aborting loader\n");
+ DLIF_exit(1);
+ }
+
+ dyn_module = *ppdm;
+ if (dyn_module->name) DLIF_free(dyn_module->name);
+ if (dyn_module->strtab) DLIF_free(dyn_module->strtab);
+ if (dyn_module->symtab) DLIF_free(dyn_module->symtab);
+ if (dyn_module->phdr) DLIF_free(dyn_module->phdr);
+ if (dyn_module->dyntab) DLIF_free(dyn_module->dyntab);
+
+ /*------------------------------------------------------------------------*/
+ /* If we left the loaded module attached to the dynamic module, then */
+ /* something must have gone wrong with the load. Remove the loaded */
+ /* module from the queue of loaded modules, if it is there. Then free */
+ /* the host memory allocated to the loaded module and its segments. */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->loaded_module != NULL)
+ delete_DLIMP_Loaded_Module(handle, &(dyn_module->loaded_module));
+
+ /*------------------------------------------------------------------------*/
+ /* Finally, free the host memory for this dynamic module object and NULL */
+ /* the pointer to the object. */
+ /*------------------------------------------------------------------------*/
+ DLIF_free(dyn_module);
+ *ppdm = NULL;
+}
+
+/*****************************************************************************/
+/* file_header_magic_number_is_valid() */
+/* */
+/* Given an object file header, check the magic number to ensure that it */
+/* is an object file format that we recognize. This implementation of */
+/* the dynamic loader core will handle ELF object file format. */
+/* */
+/*****************************************************************************/
+static BOOL file_header_magic_number_is_valid(struct Elf32_Ehdr* header)
+{
+ /*------------------------------------------------------------------------*/
+ /* Check for correct ELF magic numbers in file header. */
+ /*------------------------------------------------------------------------*/
+ if (!header->e_ident[EI_MAG0] == ELFMAG0 ||
+ !header->e_ident[EI_MAG1] == ELFMAG1 ||
+ !header->e_ident[EI_MAG2] == ELFMAG2 ||
+ !header->e_ident[EI_MAG3] == ELFMAG3)
+ {
+ DLIF_error(DLET_FILE, "Invalid ELF magic number.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* file_header_machine_is_valid() */
+/* */
+/* Check if the machine specified in the file header is supported by the */
+/* loader. If the loader was compiled with support for all targets, */
+/* the machine will be initially set to EM_NONE. Once a module has been */
+/* loaded, all remaining modules must have the same machine value. */
+/*****************************************************************************/
+static int file_header_machine_is_valid(Elf32_Half e_machine)
+{
+ /*------------------------------------------------------------------------*/
+ /* Currently we support only ARM or C6x */
+ /*------------------------------------------------------------------------*/
+ switch(e_machine)
+ {
+#ifdef ARM_TARGET
+ case EM_ARM : return TRUE;
+#endif
+#ifdef C60_TARGET
+ case EM_TI_C6000 : return TRUE;
+#endif
+
+ default : return FALSE;
+ }
+}
+
+/*****************************************************************************/
+/* is_valid_elf_object_file() */
+/* */
+/* Check file size against anticipated end location of string table, */
+/* symbol table, program header tables, etc. If we anything untoward, */
+/* then we declare that the ELF file is corrupt and the load is aborted. */
+/* */
+/*****************************************************************************/
+static BOOL is_valid_elf_object_file(LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ uint32_t fsz;
+ int i;
+
+ /*------------------------------------------------------------------------*/
+ /* Get file size. */
+ /*------------------------------------------------------------------------*/
+ DLIF_fseek(fd, 0, LOADER_SEEK_END);
+ fsz = DLIF_ftell(fd);
+
+ /*------------------------------------------------------------------------*/
+ /* Check for invalid table sizes (string table, symbol table, and */
+ /* program header tables). */
+ /*------------------------------------------------------------------------*/
+ if (!((dyn_module->strsz < fsz) &&
+ (dyn_module->symnum < fsz) &&
+ (dyn_module->phnum * sizeof(struct Elf32_Phdr)) < fsz))
+ {
+ DLIF_error(DLET_FILE, "Invalid ELF table bounds.\n");
+ return FALSE;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Check for null so_name string in file with dynamic information. */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->dyntab && !strcmp(dyn_module->name, ""))
+ {
+ DLIF_error(DLET_MISC, "Dynamic file lacks SO_NAME identifier.\n");
+ return FALSE;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Check for invalid program header information. */
+ /*------------------------------------------------------------------------*/
+ for (i = 0; i < dyn_module->phnum; i++)
+ {
+ struct Elf32_Phdr* phdr = dyn_module->phdr + i;
+
+ /*---------------------------------------------------------------------*/
+ /* Sanity check for relative sizes of filesz and memsz. */
+ /*---------------------------------------------------------------------*/
+ if (!(phdr->p_type != PT_LOAD || phdr->p_filesz <= phdr->p_memsz))
+ {
+ DLIF_error(DLET_MISC,
+ "Invalid file or memory size for segment %d.\n", i);
+ return FALSE;
+ }
+
+ /*---------------------------------------------------------------------*/
+ /* Check that segment file offset doesn't go off the end of the file. */
+ /*---------------------------------------------------------------------*/
+ if (!(phdr->p_offset + phdr->p_filesz < fsz))
+ {
+ DLIF_error(DLET_FILE,
+ "File location of segment %d is past the end of file.\n", i);
+ return FALSE;
+ }
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Check that a ET_DYN-type file is relocatable. */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->fhdr.e_type == ET_DYN && !dyn_module->symtab) return FALSE;
+
+ /*------------------------------------------------------------------------*/
+ /* All checks passed. */
+ /*------------------------------------------------------------------------*/
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* process_eiosabi() */
+/* */
+/* Check the EI_OSABI field to validate it and set any parameters based on */
+/* it. */
+/*****************************************************************************/
+static BOOL process_eiosabi(DLIMP_Dynamic_Module* dyn_module)
+{
+ return cur_target->process_eiosabi(dyn_module);
+}
+
+/*****************************************************************************/
+/* dload_file_header() */
+/* */
+/* Read ELF file header. Store critical information in the provided */
+/* DLIMP_Dynamic_Module record. Check file header for validity. */
+/* */
+/*****************************************************************************/
+static BOOL dload_file_header(LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ /*------------------------------------------------------------------------*/
+ /* Read ELF file header from given input file. */
+ /*------------------------------------------------------------------------*/
+ DLIF_fread(&(dyn_module->fhdr), sizeof(struct Elf32_Ehdr), 1, fd);
+
+ /*------------------------------------------------------------------------*/
+ /* Determine target vs. host endian-ness. Does header data need to be */
+ /* byte swapped? */
+ /*------------------------------------------------------------------------*/
+ dyn_module->wrong_endian =
+ (dyn_module->fhdr.e_ident[EI_DATA] != DLIMP_get_endian());
+
+ /*------------------------------------------------------------------------*/
+ /* Swap file header structures, if needed. */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->wrong_endian)
+ DLIMP_change_ehdr_endian(&(dyn_module->fhdr));
+
+ /*------------------------------------------------------------------------*/
+ /* Write out magic ELF information for debug purposes. */
+ /*------------------------------------------------------------------------*/
+#if LOADER_DEBUG
+ if (debugging_on)
+ {
+ DLIF_trace("ELF: %c%c%c\n", dyn_module->fhdr.e_ident[1],
+ dyn_module->fhdr.e_ident[2],
+ dyn_module->fhdr.e_ident[3]);
+ DLIF_trace("ELF file header entry point: %x\n",
+ dyn_module->fhdr.e_entry);
+ }
+#endif
+
+
+ /*------------------------------------------------------------------------*/
+ /* Verify magic numbers in ELF file header. */
+ /*------------------------------------------------------------------------*/
+ if (!file_header_magic_number_is_valid(&(dyn_module->fhdr)))
+ {
+ DLIF_error(DLET_FILE, "Invalid ELF file header magic number.\n");
+ return FALSE;
+ }
+
+ if (!file_header_machine_is_valid(dyn_module->fhdr.e_machine))
+ {
+ DLIF_error(DLET_FILE, "Invalid ELF file target machine.\n");
+ return FALSE;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Verify file is an executable or dynamic shared object or library. */
+ /*------------------------------------------------------------------------*/
+ if ((dyn_module->fhdr.e_type != ET_EXEC) &&
+ (dyn_module->fhdr.e_type != ET_DYN))
+ {
+ DLIF_error(DLET_FILE, "Invalid ELF file type.\n");
+ return FALSE;
+ }
+
+#if LOADER_DEBUG || LOADER_PROFILE
+ /*------------------------------------------------------------------------*/
+ /* Stop profiling clock when file header information has finished */
+ /* loading. Re-start clock on initialization of symbol table, and */
+ /* dynamic table pointers. */
+ /*------------------------------------------------------------------------*/
+ if (debugging_on || profiling_on)
+ {
+ DLIF_trace("done.\n");
+ if (profiling_on)
+ {
+ profile_stop_clock();
+ DLIF_trace("Took %lu cycles.\n",
+ (unsigned long)profile_cycle_count());
+ profile_start_clock();
+ }
+ }
+#endif
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* dload_program_header_table() */
+/* */
+/* Make a local copy of the ELF object file's program header table in the */
+/* dynamic module data structure. */
+/* */
+/*****************************************************************************/
+static void dload_program_header_table(LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ /*------------------------------------------------------------------------*/
+ /* Read the program header tables from the object file. */
+ /*------------------------------------------------------------------------*/
+ struct Elf32_Ehdr *fhdr = &(dyn_module->fhdr);
+ dyn_module->phdr = (struct Elf32_Phdr*)
+ (DLIF_malloc(fhdr->e_phnum * fhdr->e_phentsize));
+ DLIF_fseek(fd, fhdr->e_phoff, LOADER_SEEK_SET);
+ DLIF_fread(dyn_module->phdr, fhdr->e_phentsize, fhdr->e_phnum,fd);
+ dyn_module->phnum = fhdr->e_phnum;
+
+ /*------------------------------------------------------------------------*/
+ /* Byte swap the program header tables if the target endian-ness is not */
+ /* the same as the host endian-ness. */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->wrong_endian)
+ {
+ int i;
+ for (i = 0; i < dyn_module->phnum; i++)
+ DLIMP_change_phdr_endian(dyn_module->phdr + i);
+ }
+}
+
+/*****************************************************************************/
+/* dload_headers() */
+/* */
+/* Read ELF object file header and program header table information into */
+/* the given dynamic module data structure. If the object file contains */
+/* dynamic information, read in the dynamic tags, dynamic symbol table, */
+/* and global string table. Check to make sure that we are not already */
+/* in the process of loading the module (circular dependencies), then */
+/* perform some level of sanity checking on the content of the file to */
+/* provide some assurance that the file is not corrupted. */
+/* */
+/*****************************************************************************/
+static BOOL dload_headers(LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+#if LOADER_DEBUG || LOADER_PROFILE
+ /*------------------------------------------------------------------------*/
+ /* More progress information. Start timing if profiling is enabled. */
+ /*------------------------------------------------------------------------*/
+ if (debugging_on || profiling_on)
+ {
+ DLIF_trace("\nReading file headers ...\n");
+ if (profiling_on) profile_start_clock();
+ }
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* Read file header information and check vs. expected ELF object file */
+ /* header content. */
+ /*------------------------------------------------------------------------*/
+ if (!dload_file_header(fd, dyn_module))
+ return FALSE;
+
+ /*------------------------------------------------------------------------*/
+ /* Read program header table information into the dynamic module object. */
+ /*------------------------------------------------------------------------*/
+ dload_program_header_table(fd, dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Once headers have been read in, use e_machine to set virtual target. */
+ /* This can then be used to access target specific functions. */
+ /*------------------------------------------------------------------------*/
+ cur_target = get_vt_obj(dyn_module->fhdr.e_machine);
+ if (!cur_target)
+ {
+ DLIF_error(DLET_FILE, "Attempt to load invalid ELF file, '%s'.\n",
+ dyn_module->name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* find_dynamic_segment() */
+/* */
+/* Find the dynamic segment in the given ELF object file, if there is */
+/* one. If the segment is found, then the segment ID output parameter */
+/* is set to the index of the dynamic segment in the program header */
+/* table. If the dynamic segment is not found, the dynamic module's */
+/* relocatable flag is set to FALSE, and return FALSE. */
+/* */
+/*****************************************************************************/
+static BOOL find_dynamic_segment(DLIMP_Dynamic_Module *dyn_module,
+ Elf32_Word *dyn_seg_idx)
+{
+ int i;
+
+ /*------------------------------------------------------------------------*/
+ /* We should have a valid dynamic module pointer and somewhere to put the */
+ /* dynamic segment id, if we find one. If either of these are missing, */
+ /* we should get an internal error and abort the loader. */
+ /*------------------------------------------------------------------------*/
+ if ((dyn_module == NULL) || (dyn_seg_idx == NULL))
+ {
+ DLIF_error(DLET_MISC, "Internal error: find_dynamic_segment() needs "
+ "non-NULL arguments.\n");
+ DLIF_exit(1);
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Spin through segment program headers to find the dynamic segment. */
+ /*------------------------------------------------------------------------*/
+ dyn_module->relocatable = TRUE;
+ for (i = 0; i < dyn_module->phnum; i++)
+ if (dyn_module->phdr[i].p_type == PT_DYNAMIC)
+ { *dyn_seg_idx = i; return TRUE; }
+
+ /*------------------------------------------------------------------------*/
+ /* No dynamic segment found, mark the object module as not relocatable */
+ /* and warn the user. */
+ /*------------------------------------------------------------------------*/
+ dyn_module->relocatable = FALSE;
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* copy_dynamic_table() */
+/* */
+/* Make a local copy of the dynamic table read from the dynamic segment */
+/* in the ELF object file. */
+/* */
+/*****************************************************************************/
+static void copy_dynamic_table(LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module,
+ Elf32_Word dyn_seg_idx)
+{
+ /*------------------------------------------------------------------------*/
+ /* Allocate space for the dynamic table from host memory and read its */
+ /* content from the ELF object file. */
+ /*------------------------------------------------------------------------*/
+ Elf32_Word num_elem;
+ dyn_module->dyntab = DLIF_malloc(dyn_module->phdr[dyn_seg_idx].p_filesz);
+ num_elem = dyn_module->phdr[dyn_seg_idx].p_filesz / sizeof(struct Elf32_Dyn);
+ DLIF_fseek(fd, dyn_module->phdr[dyn_seg_idx].p_offset, LOADER_SEEK_SET);
+ DLIF_fread(dyn_module->dyntab, sizeof(struct Elf32_Dyn), num_elem, fd);
+
+ /*------------------------------------------------------------------------*/
+ /* If necessary, byte swap each entry in the dynamic table. */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->wrong_endian)
+ {
+ int i;
+ for (i = 0; i < num_elem; i++)
+ DLIMP_change_dynent_endian(&dyn_module->dyntab[i]);
+ }
+}
+
+/*****************************************************************************/
+/* process_target_dynamic_tag() */
+/* */
+/* Process a target specific dynamic tag entry. Returns TRUE if the tag */
+/* was handled and FALSE if it was not recognized. */
+/*****************************************************************************/
+static BOOL process_target_dynamic_tag(DLIMP_Dynamic_Module* dyn_module, int i)
+{
+ return cur_target->process_dynamic_tag(dyn_module, i);
+}
+
+/*****************************************************************************/
+/* process_dynamic_table() */
+/* */
+/* Process dynamic tag entries from the dynamic table. At the conclusion */
+/* of this function, we should have made a copy of the global symbols */
+/* and the global symbol names. */
+/* */
+/*****************************************************************************/
+static BOOL process_dynamic_table(LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ int i;
+ BOOL soname_found = FALSE;
+ Elf32_Addr soname_offset = 0;
+ Elf32_Addr strtab_offset = 0;
+ Elf32_Addr hash_offset = 0;
+ Elf32_Addr symtab_offset = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Iterate over the dynamic table in order to process dynamic tags. */
+ /* See ELF TIS Specification for details on the meaning of each dynamic */
+ /* tag. The C6000 ELF ABI Specification provides more details about the */
+ /* TI specific C6000 ELF ABI tags. */
+ /*------------------------------------------------------------------------*/
+ for (i = 0; dyn_module->dyntab[i].d_tag != DT_NULL; i++)
+ {
+ switch(dyn_module->dyntab[i].d_tag)
+ {
+ /*------------------------------------------------------------------*/
+ /* DT_SONAME: Contains name of dynamic object, used for dependency */
+ /* comparisons. Its value is an offset from the start */
+ /* of the string table. We need to copy the string at */
+ /* this offset into dmodule->name. */
+ /*------------------------------------------------------------------*/
+ case DT_SONAME:
+#if LOADER_DEBUG
+ if (debugging_on) DLIF_trace("Found SO_NAME.\n");
+#endif
+ /*---------------------------------------------------------------*/
+ /* We store the offset of the so_name in the dynamic string */
+ /* table so that it doesn't matter which dynamic tag we see */
+ /* first (DT_SONAME actually is generated before DT_STRTAB). */
+ /*---------------------------------------------------------------*/
+ soname_found = TRUE;
+ soname_offset = dyn_module->dyntab[i].d_un.d_ptr;
+ break;
+
+ /*------------------------------------------------------------------*/
+ /* DT_STRSZ: Contains the size of the string table. */
+ /*------------------------------------------------------------------*/
+ case DT_STRSZ:
+ dyn_module->strsz = dyn_module->dyntab[i].d_un.d_val;
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Found string table Size: 0x%x\n", dyn_module->strsz);
+#endif
+ break;
+
+ /*------------------------------------------------------------------*/
+ /* DT_STRTAB: Contains the file offset of the string table. The */
+ /* tag directly after this is guaranteed to be DT_STRSZ, */
+ /* containing the string table size. We need to */
+ /* allocate memory for the string table and copy it from */
+ /* the file. */
+ /*------------------------------------------------------------------*/
+ case DT_STRTAB:
+ strtab_offset = dyn_module->dyntab[i].d_un.d_ptr;
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Found string table: 0x%x\n", strtab_offset);
+#endif
+ break;
+
+ /*------------------------------------------------------------------*/
+ /* DT_HASH: Contains the file offset of the symbol hash table. */
+ /*------------------------------------------------------------------*/
+ case DT_HASH:
+ hash_offset = dyn_module->dyntab[i].d_un.d_ptr;
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Found symbol hash table: 0x%x\n", hash_offset);
+#endif
+ break;
+
+ /*------------------------------------------------------------------*/
+ /* DT_SYMTAB: Contains the file offset of the symbol table. */
+ /*------------------------------------------------------------------*/
+ case DT_SYMTAB:
+ symtab_offset = dyn_module->dyntab[i].d_un.d_ptr;
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Found symbol table: 0x%x\n", symtab_offset);
+#endif
+ break;
+
+ /*------------------------------------------------------------------*/
+ /* DSO Initialization / Termination Model Dynamic Tags */
+ /*------------------------------------------------------------------*/
+ /* For initialization tags, we store indices and array sizes in */
+ /* the dyn_module. Termination works a little different, the */
+ /* indices into the local copy of the dynamic table are stored in */
+ /* dyn_module, but the DT_FINI_ARRAYSZ value is recorded with the */
+ /* loaded module. */
+ /*------------------------------------------------------------------*/
+ /* After placement is done, the DT_FINI and DT_FINI_ARRAY values */
+ /* need to be copied from the local dynamic table into the loaded */
+ /* module object. */
+ /*------------------------------------------------------------------*/
+ case DT_PREINIT_ARRAY:
+ dyn_module->preinit_array_idx = i;
+ break;
+
+ case DT_PREINIT_ARRAYSZ:
+ dyn_module->preinit_arraysz = dyn_module->dyntab[i].d_un.d_val;
+ break;
+
+ case DT_INIT:
+ dyn_module->init_idx = i;
+ break;
+
+ case DT_INIT_ARRAY:
+ dyn_module->init_array_idx = i;
+ break;
+
+ case DT_INIT_ARRAYSZ:
+ dyn_module->init_arraysz = dyn_module->dyntab[i].d_un.d_val;
+ break;
+
+ /*------------------------------------------------------------------*/
+ /* This information will be copied over to the loaded module */
+ /* object after placement has been completed and the information */
+ /* in the dynamic table has been relocated. */
+ /*------------------------------------------------------------------*/
+ case DT_FINI_ARRAY:
+ case DT_FINI_ARRAYSZ:
+ case DT_FINI:
+ break;
+
+ /*------------------------------------------------------------------*/
+ /* Unrecognized tag, may not be illegal, but is not explicitly */
+ /* handled by this function. Should it be? */
+ /*------------------------------------------------------------------*/
+ default:
+ {
+ if (!process_target_dynamic_tag(dyn_module, i))
+ {
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Unrecognized dynamic tag: 0x%X\n",
+ dyn_module->dyntab[i].d_tag);
+#endif
+ }
+
+ break;
+ }
+
+ }
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* If string table offset and size were found, read string table in from */
+ /* the ELF object file. */
+ /*------------------------------------------------------------------------*/
+ if (strtab_offset && dyn_module->strsz)
+ {
+ DLIF_fseek(fd, strtab_offset, LOADER_SEEK_SET);
+ dyn_module->strtab = DLIF_malloc(dyn_module->strsz);
+ DLIF_fread(dyn_module->strtab, sizeof(uint8_t), dyn_module->strsz, fd);
+ }
+ else
+ {
+ DLIF_warning(DLWT_MISC,
+ "Mandatory dynamic tag DT_STRTAB/DT_STRSZ not found!\n");
+ return FALSE;
+ }
+
+
+ /*------------------------------------------------------------------------*/
+ /* If symbol hash table is found read-in the hash table. */
+ /*------------------------------------------------------------------------*/
+ if (hash_offset)
+ {
+ /*---------------------------------------------------------------------*/
+ /* Hash table has the following format. nchain equals the number of */
+ /* entries in the symbol table (symnum) */
+ /* */
+ /* +----------------------------+ */
+ /* | nbucket | */
+ /* +----------------------------+ */
+ /* | nchain | */
+ /* +----------------------------+ */
+ /* | bucket[0] | */
+ /* | ... | */
+ /* | bucket[nbucket-1] | */
+ /* +----------------------------+ */
+ /* | chain[0] | */
+ /* | ... | */
+ /* | chain[nchain-1] | */
+ /* +----------------------------+ */
+ /*---------------------------------------------------------------------*/
+ Elf32_Word hash_nbucket;
+ Elf32_Word hash_nchain;
+
+ /*---------------------------------------------------------------------*/
+ /* Seek to the hash offset and read first two words into nbucket and */
+ /* symnum. */
+ /*---------------------------------------------------------------------*/
+ DLIF_fseek(fd, hash_offset, LOADER_SEEK_SET);
+ DLIF_fread(&(hash_nbucket), sizeof(Elf32_Word), 1, fd);
+ DLIF_fread(&(hash_nchain), sizeof(Elf32_Word), 1, fd);
+ if (dyn_module->wrong_endian)
+ {
+ DLIMP_change_endian32((int32_t*)(&(hash_nbucket)));
+ DLIMP_change_endian32((int32_t*)(&(hash_nchain)));
+ }
+
+ /*---------------------------------------------------------------------*/
+ /* The number of entires in the dynamic symbol table is not encoded */
+ /* anywhere in the elf file. However, the nchain is guaranteed to be */
+ /* the same as the number of symbols. Use nchain to set the symnum. */
+ /*---------------------------------------------------------------------*/
+ dyn_module->symnum = hash_nchain;
+#if LOADER_DEBUG
+ if (debugging_on) DLIF_trace("symnum=%d\n", hash_nchain);
+#endif
+ }
+ else
+ {
+ DLIF_warning(DLWT_MISC, "Mandatory dynamic tag DT_HASH is not found!\n");
+ return FALSE;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Read dynamic symbol table. */
+ /*------------------------------------------------------------------------*/
+ if (symtab_offset)
+ {
+ int j = 0;
+ DLIF_fseek(fd, symtab_offset, LOADER_SEEK_SET);
+ dyn_module->symtab =
+ DLIF_malloc(dyn_module->symnum * sizeof(struct Elf32_Sym));
+ DLIF_fread(dyn_module->symtab, sizeof(struct Elf32_Sym),
+ dyn_module->symnum, fd);
+ if (dyn_module->wrong_endian)
+ {
+ for (j = 0; j < dyn_module->symnum; j++)
+ DLIMP_change_sym_endian(dyn_module->symtab + j);
+ }
+
+ /*---------------------------------------------------------------------*/
+ /* The st_name field of an Elf32_Sym entity is an offset into the */
+ /* string table. Convert it into a pointer to the string. */
+ /*---------------------------------------------------------------------*/
+ if (strtab_offset)
+ for (j = 0; j < dyn_module->symnum; j++)
+ dyn_module->symtab[j].st_name += (Elf32_Word) dyn_module->strtab;
+ }
+ else
+ {
+ DLIF_warning(DLWT_MISC,
+ "Mandatory dynamic tag DT_SYMTAB is not found!\n");
+ return FALSE;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Read the SONAME. */
+ /*------------------------------------------------------------------------*/
+ if (!soname_found)
+ {
+ DLIF_warning(DLWT_MISC, "Dynamic tag DT_SONAME is not found!\n");
+ dyn_module->name = DLIF_malloc(sizeof(char));
+ *dyn_module->name = '\0';
+ }
+ else
+ {
+ dyn_module->name =
+ DLIF_malloc(strlen(dyn_module->strtab + soname_offset) + 1);
+ strcpy(dyn_module->name, dyn_module->strtab + soname_offset);
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("Name of dynamic object: %s\n", dyn_module->name);
+#endif
+ }
+
+ return TRUE;
+}
+
+
+/*****************************************************************************/
+/* dload_dynamic_information() */
+/* */
+/* Given a dynamic module with a dynamic segment which is located via */
+/* given dynamic segment index, make a local copy of the dynamic table */
+/* in the dynamic module object, then process the dynamic tag entries in */
+/* the table. */
+/* */
+/*****************************************************************************/
+static BOOL dload_dynamic_information(LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module,
+ Elf32_Word dyn_seg_idx)
+{
+ /*------------------------------------------------------------------------*/
+ /* Read a copy of the dynamic table into the dynamic module object. */
+ /*------------------------------------------------------------------------*/
+ copy_dynamic_table(fd, dyn_module, dyn_seg_idx);
+
+ /*------------------------------------------------------------------------*/
+ /* Process dynamic entries in the dynamic table. If any problems are */
+ /* encountered, the loader should emit an error or warning and return */
+ /* FALSE here. */
+ /*------------------------------------------------------------------------*/
+ return process_dynamic_table(fd, dyn_module);
+}
+
+/*****************************************************************************/
+/* check_circular_dependency() */
+/* */
+/* Determine whether a dynamic module is already in the process of being */
+/* loaded before we try to start loading it again. If it is already */
+/* being loaded, then the dynamic loader has detected a circular */
+/* dependency. An error will be emitted and the load will be aborted. */
+/* */
+/*****************************************************************************/
+static BOOL check_circular_dependency(DLOAD_HANDLE handle,
+ const char *dyn_mod_name)
+{
+ /*------------------------------------------------------------------------*/
+ /* Check the name of the given dependency module to be loaded against the */
+ /* list of modules that are currently in the process of being loaded. */
+ /* Report an error if any circular dependencies are detected. */
+ /*------------------------------------------------------------------------*/
+ int i;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (i = 0; i < pHandle->DLIMP_module_dependency_list.size; i++)
+ if (!strcmp(dyn_mod_name,
+ ((char**)(pHandle->DLIMP_module_dependency_list.buf))[i]))
+ {
+ DLIF_error(DLET_MISC,
+ "Circular dependency detected, '%s' is already in the "
+ "process of loading.\n", dyn_mod_name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* dload_dynamic_segment() */
+/* */
+/* Find the dynamic segment in the given ELF module, if there is one. */
+/* If there is a dynamic segment, then make a local copy of the dynamic */
+/* table in the dynamic module object provided, then process the dynamic */
+/* tag entries in the table. */
+/* */
+/* If there is no dynamic segment, then we return success from this */
+/* function, marking the dynamic module as "not relocatable". */
+/* */
+/*****************************************************************************/
+static BOOL dload_dynamic_segment(DLOAD_HANDLE handle,
+ LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ /*------------------------------------------------------------------------*/
+ /* If we don't find dynamic segment, the relocatable flag will have been */
+ /* set to false to indicate that the module is a static executable. We */
+ /* still return TRUE from this function so that we can proceed with */
+ /* static loading. */
+ /*------------------------------------------------------------------------*/
+ Elf32_Word dyn_seg_idx = 0;
+ if (!find_dynamic_segment(dyn_module, &dyn_seg_idx))
+ return TRUE;
+
+ /*------------------------------------------------------------------------*/
+ /* Process the OSABI now, after we know if the module is relocatable. */
+ /*------------------------------------------------------------------------*/
+ if (!process_eiosabi(dyn_module))
+ {
+ DLIF_error(DLET_FILE, "Unsupported EI_OSABI value.\n");
+ return FALSE;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Read the dynamic table from the ELF file, then process the dynamic */
+ /* tags in the table. */
+ /*------------------------------------------------------------------------*/
+ if (!dload_dynamic_information(fd, dyn_module, dyn_seg_idx))
+ return FALSE;
+
+ /*------------------------------------------------------------------------*/
+ /* Check to make sure that this module is not already being loaded. If */
+ /* is, then it will cause a circular dependency to be introduced. */
+ /* Loader should detect circular dependencies and emit an error. */
+ /*------------------------------------------------------------------------*/
+ if (!check_circular_dependency(handle, dyn_module->name))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+/* COPY_SEGMENTS() - */
+/* */
+/* Copy all segments into host memory. */
+/*****************************************************************************/
+static void copy_segments(DLOAD_HANDLE handle, LOADER_FILE_DESC* fp,
+ DLIMP_Dynamic_Module* dyn_module)
+{
+ DLIMP_Loaded_Segment* seg =
+ (DLIMP_Loaded_Segment*)(dyn_module->loaded_module->loaded_segments.buf);
+ int s, seg_size = dyn_module->loaded_module->loaded_segments.size;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+
+ for (s=0; s<seg_size; s++)
+ {
+ struct DLOAD_MEMORY_REQUEST targ_req;
+ targ_req.fp = fp;
+ targ_req.segment = seg[s].obj_desc;
+ targ_req.offset = seg[s].phdr.p_offset;
+ targ_req.flags = DLOAD_SF_relocatable;
+
+ if (seg[s].phdr.p_flags & PF_X) targ_req.flags |= DLOAD_SF_executable;
+ if (seg[s].phdr.p_flags & PF_W) targ_req.flags |= DLOAD_SF_writable;
+
+ targ_req.align = seg[s].phdr.p_align;
+
+ /*---------------------------------------------------------------------*/
+ /* Copy segment data from the file into host buffer where it can */
+ /* be relocated. */
+ /*---------------------------------------------------------------------*/
+ DLIF_copy(pHandle->client_handle, &targ_req);
+ seg[s].host_address = targ_req.host_address;
+ }
+}
+
+/*****************************************************************************/
+/* WRITE_SEGMENTS() - */
+/* */
+/* Write all segments to target memory. */
+/*****************************************************************************/
+static void write_segments(DLOAD_HANDLE handle,
+ LOADER_FILE_DESC* fp,
+ DLIMP_Dynamic_Module* dyn_module)
+{
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+ DLIMP_Loaded_Segment* seg =
+ (DLIMP_Loaded_Segment*)(dyn_module->loaded_module->loaded_segments.buf);
+ int s, seg_size = dyn_module->loaded_module->loaded_segments.size;
+
+ for (s=0; s<seg_size; s++)
+ {
+ struct DLOAD_MEMORY_REQUEST targ_req;
+
+ targ_req.fp = fp;
+ targ_req.segment = seg[s].obj_desc;
+ targ_req.offset = seg[s].phdr.p_offset;
+ targ_req.flags = DLOAD_SF_relocatable;
+
+ if (seg[s].phdr.p_flags & PF_X) targ_req.flags |= DLOAD_SF_executable;
+ if (seg[s].phdr.p_flags & PF_W) targ_req.flags |= DLOAD_SF_writable;
+
+ targ_req.align = seg[s].phdr.p_align;
+ targ_req.host_address = seg[s].host_address;
+
+ /*---------------------------------------------------------------------*/
+ /* Copy segment data from the file into host buffer where it can */
+ /* be relocated. */
+ /*---------------------------------------------------------------------*/
+ DLIF_write(pHandle->client_handle, &targ_req);
+ }
+}
+
+/*****************************************************************************/
+/* SEG_HAS_SPACE_FOR_WRITE() - */
+/* */
+/* Check if segment has enough space to recieve contents of .args section. */
+/*****************************************************************************/
+static BOOL seg_has_space_for_write(DLIMP_Loaded_Module* lmodule, int sz)
+{
+ DLIMP_Loaded_Segment* seg =
+ (DLIMP_Loaded_Segment*)(lmodule->loaded_segments.buf);
+ int s, seg_size = lmodule->loaded_segments.size;
+
+ Elf32_Addr write_address = (Elf32_Addr)lmodule->c_args;
+
+ for (s=0; s<seg_size; s++)
+ {
+ Elf32_Addr seg_boundary =
+ seg[s].phdr.p_vaddr + seg[s].obj_desc->memsz_in_bytes;
+
+ /*---------------------------------------------------------------------*/
+ /* If address to write to is greater than segment addr and less than */
+ /* segment end, it must lie in current segment. */
+ /*---------------------------------------------------------------------*/
+ if ((write_address >= seg[s].phdr.p_vaddr) &&
+ (write_address < seg_boundary))
+ {
+ if ((write_address + sz) > seg_boundary)
+ {
+#if LOADER_DEBUG
+ if (debugging_on)
+ {
+ DLIF_trace("Write requires 0x%x bytes\n",write_address + sz);
+ DLIF_trace("Seg boundary at : 0x%x\n",seg_boundary);
+ DLIF_trace("WARNING - Not enough space in segment\n");
+ }
+#endif
+ return FALSE;
+ }
+ else return TRUE;
+ }
+ }
+ /*------------------------------------------------------------------------*/
+ /* Given address doesn't belong to any known segment. */
+ /*------------------------------------------------------------------------*/
+ return FALSE;
+}
+
+
+/*****************************************************************************/
+/* DLOAD_initialize() */
+/* */
+/* Construct and initialize data structures internal to the dynamic */
+/* loader core. */
+/* */
+/*---------------------------------------------------------------------------*/
+/* */
+/* This function is deprecated, replaced by DLOAD_create(). */
+/* */
+/*****************************************************************************/
+void DLOAD_initialize(DLOAD_HANDLE handle)
+{
+}
+
+/*****************************************************************************/
+/* DLOAD_finalize() */
+/* */
+/* Destroy and finalize data structures internal to the dynamic */
+/* loader core. */
+/* */
+/*---------------------------------------------------------------------------*/
+/* */
+/* This function is deprecated, replaced by DLOAD_destroy(). */
+/* */
+/*****************************************************************************/
+void DLOAD_finalize(DLOAD_HANDLE handle)
+{
+}
+
+/*****************************************************************************/
+/* dload_static_executable() */
+/* */
+/* Account for target memory allocated to static executable and wrap up */
+/* loading. No relocation is necessary. */
+/* */
+/*****************************************************************************/
+static int32_t dload_static_executable(DLOAD_HANDLE handle,
+ LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ int32_t local_file_handle = 0;
+
+#if LOADER_DEBUG
+ if (debugging_on) DLIF_trace("Starting dload_static_executable() ...\n");
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* Set entry point for static executable and attempt to allocate target */
+ /* memory for the static executable. */
+ /*------------------------------------------------------------------------*/
+ dyn_module->loaded_module->entry_point = dyn_module->fhdr.e_entry;
+ if (load_static_segment(handle, fd, dyn_module) &&
+ load_object(fd, dyn_module))
+ {
+ /*---------------------------------------------------------------------*/
+ /* If successful, we'll want to detach the loaded module object from */
+ /* the dynamic module object that created it. Take note of the file */
+ /* handle. */
+ /*---------------------------------------------------------------------*/
+ DLIMP_Loaded_Module *loaded_module = detach_loaded_module(dyn_module);
+ local_file_handle = loaded_module->file_handle;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Static load failed. Flag an error. */
+ /*------------------------------------------------------------------------*/
+ else
+ DLIF_error(DLET_MEMORY,
+ "Failed to allocate target memory for static executable.\n");
+
+ /*------------------------------------------------------------------------*/
+ /* Destruct dynamic module object. */
+ /*------------------------------------------------------------------------*/
+ delete_DLIMP_Dynamic_Module(handle, &dyn_module);
+
+#if LOADER_DEBUG
+ if (debugging_on) DLIF_trace("Finished dload_static_executable()\n");
+#endif
+
+ return local_file_handle;
+}
+
+#if LOADER_DEBUG || LOADER_PROFILE
+int DLREL_relocations;
+time_t DLREL_total_reloc_time;
+#endif
+
+/*****************************************************************************/
+/* process_dynamic_module_relocations() */
+/* */
+/* Make a host-accessible copy of all of the segments, process all */
+/* relocation entries associated with the given module within that */
+/* space, then write the updated segment buffers back out to target */
+/* memory. */
+/* */
+/*****************************************************************************/
+static void process_dynamic_module_relocations(DLOAD_HANDLE handle,
+ LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+#if LOADER_DEBUG || LOADER_PROFILE
+ if(debugging_on || profiling_on)
+ {
+ DLIF_trace("Running relocate()...\n");
+ if (profiling_on) profile_start_clock();
+ }
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* Copy segments from file to host memory */
+ /*------------------------------------------------------------------------*/
+ copy_segments(handle, fd, dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Process dynamic relocations. */
+ /*------------------------------------------------------------------------*/
+ DLREL_relocate(handle, fd, dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Write segments from host memory to target memory */
+ /*------------------------------------------------------------------------*/
+ write_segments(handle, fd, dyn_module);
+
+#if LOADER_DEBUG || LOADER_PROFILE
+ /*------------------------------------------------------------------------*/
+ /* Report timing and progress information for relocation step. */
+ /*------------------------------------------------------------------------*/
+ if (debugging_on || profiling_on)
+ {
+ if (profiling_on)
+ {
+ profile_stop_clock();
+ DLIF_trace("Took %lu cycles.\n",
+ (unsigned long) profile_cycle_count());
+ DLIF_trace("Total reloc time: %lu\n",
+ (unsigned long) DLREL_total_reloc_time);
+ DLIF_trace("Time per relocation: %ld\n",
+ DLREL_relocations ? DLREL_total_reloc_time / DLREL_relocations : 0);
+ }
+
+ DLIF_trace("Number of relocations: %d\n", DLREL_relocations);
+ DLIF_trace("\nAbout to run load_object()...");
+ DLREL_total_reloc_time = DLREL_relocations = 0;
+ if (profiling_on) profile_start_clock();
+ }
+#endif
+
+}
+
+/*****************************************************************************/
+/* store_preinit_data() */
+/* */
+/* Given a dynamic module object, store pre-initialization function */
+/* information. The user may also provide a custom iniitialization */
+/* function that needs to be executed before the compiler */
+/* generated static initialization functions are executed. */
+/* The dynamic loader will now create a table TI_init_table to store */
+/* pre-init and init data. This is done because pre-init and */
+/* init functions could reference as-yet unrelocated symbols from other */
+/* modules. As such it is safer to store relevant function addresses and */
+/* execute them only after all modules are relocated (CQ34088). */
+/* */
+/*****************************************************************************/
+static void store_preinit_data(DLIMP_Dynamic_Module *dyn_module)
+{
+ IF_single_record *preinit_rec = NULL;
+ /*------------------------------------------------------------------------*/
+ /* Check for presence of DT_PREINIT_ARRAY and DT_PREINIT_ARRAYSZ */
+ /* dynamic tags associated with this module. The dyn_module object will */
+ /* hold the relevant indices into the local copy of the dynamic table. */
+ /* The value of the DT_INIT_ARRAY tag will have been updated after */
+ /* placement of the module was completed. Arrays of size 0 will be */
+ /* ignored (CQ36935). */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->preinit_arraysz > 0)
+ {
+ preinit_rec = (IF_single_record *)DLIF_malloc(sizeof(IF_single_record));
+ /*---------------------------------------------------------------------*/
+ /* Retrieve the address of the .preinit_array section from the value */
+ /* of the DT_PREINIT_ARRAY tag, and store it in the TI_init_table. */
+ /*---------------------------------------------------------------------*/
+ preinit_rec->size = dyn_module->preinit_arraysz;
+ preinit_rec->sect_addr = (TARGET_ADDRESS)
+ (dyn_module->dyntab[dyn_module->preinit_array_idx].d_un.d_ptr);
+ }
+
+ if (preinit_rec) IF_table_enqueue(&TI_init_table, preinit_rec);
+}
+
+/*****************************************************************************/
+/* store_init_data() */
+/* */
+/* Given a dynamic module object, save off initialization function(s) for */
+/* all global and static data objects that are defined in the module */
+/* which require construction. The dynamic loader will now create a table */
+/* TI_init_table to store pre-init and init data. This is done because */
+/* pre-init and init functions could reference as-yet unrelocated symbols */
+/* from other modules. As such it is safer to store relevant function */
+/* addresses and execute them only after all modules are relocated. */
+/* */
+/*****************************************************************************/
+static void store_init_data(DLIMP_Dynamic_Module *dyn_module)
+{
+ /*------------------------------------------------------------------------*/
+ /* Check for presence of a DT_INIT dynamic tag associated with this */
+ /* module. The dynamic module will hold the index into the local copy of */
+ /* the dynamic table. This entry in the dynamic table will have been */
+ /* updated after placement of the module is completed. */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->init_idx != -1)
+ {
+ IF_single_record *init_rec =
+ (IF_single_record *)DLIF_malloc(sizeof(IF_single_record));
+ /*---------------------------------------------------------------------*/
+ /* Retrieve the address of the initialization function from the value */
+ /* of the DT_INIT tag, and get the client to execute the function. */
+ /*---------------------------------------------------------------------*/
+ init_rec->size = 0;
+ init_rec->sect_addr = (TARGET_ADDRESS)
+ (dyn_module->dyntab[dyn_module->init_idx].d_un.d_ptr);
+
+ IF_table_enqueue(&TI_init_table, init_rec);
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Check for presence of a DT_INIT_ARRAY and DT_INIT_ARRAYSZ dynamic tags */
+ /* associated with this module. The dyn_module object will hold the */
+ /* relevant indices into the local copy of the dynamic table. The value */
+ /* of the DT_INIT_ARRAY tag will have been updated after placement of the */
+ /* module was completed. Arraysz must be a postive number > 0, else it */
+ /* be ignored (CQ36935). */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->init_arraysz > 0)
+ {
+ IF_single_record *arr_rec =
+ (IF_single_record *)DLIF_malloc(sizeof(IF_single_record));
+ /*---------------------------------------------------------------------*/
+ /* Retrieve the address of the .init_array section from the value of */
+ /* DT_INIT_ARRAY tag. */
+ /*---------------------------------------------------------------------*/
+ arr_rec->size = dyn_module->init_arraysz;
+ arr_rec->sect_addr = (TARGET_ADDRESS)
+ (dyn_module->dyntab[dyn_module->init_array_idx].d_un.d_ptr);
+
+ IF_table_enqueue(&TI_init_table, arr_rec);
+ }
+}
+
+/*****************************************************************************/
+/* execute_module_initialization() */
+/* */
+/* Given a dynamic module object, execute pre-initialization and */
+/* initialization function(s) for all global and static data objects that */
+/* are defined in the module which require construction. The user may */
+/* also provide a custom iniitialization function that needs to be */
+/* executed before the compiler generated static initialization functions */
+/* are executed. */
+/* Note that the functions to be executed have already been saved off in */
+/* the TI_init_table, by store_preinit_data() and store_init_data(). */
+/* */
+/*****************************************************************************/
+static void execute_module_initialization(DLOAD_HANDLE handle)
+{
+ IF_single_record *val = NULL;
+ IF_table_Queue_Node *curr_ptr = TI_init_table.front_ptr;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (; curr_ptr; curr_ptr = curr_ptr->next_ptr)
+ {
+ val = curr_ptr->value;
+
+ /*---------------------------------------------------------------------*/
+ /* A size of 0 indicates DT_INIT, otherwise this is an ARRAY. */
+ /*---------------------------------------------------------------------*/
+ if (val->size != 0)
+ {
+ /*------------------------------------------------------------------*/
+ /* Now make a loader-accessible copy of the .init_array section. */
+ /*------------------------------------------------------------------*/
+ int32_t i;
+ int32_t num_init_fcns = val->size/sizeof(TARGET_ADDRESS);
+ TARGET_ADDRESS *init_array_buf = (TARGET_ADDRESS *)
+ DLIF_malloc(val->size);
+
+ DLIF_read(pHandle->client_handle,
+ init_array_buf, 1, val->size,
+ (TARGET_ADDRESS)val->sect_addr);
+
+ /*------------------------------------------------------------------*/
+ /* Call each function whose address occupies an entry in array in */
+ /* the order that they appear in the array. The size of the array is*/
+ /* provided by the init_arraysz field in the dynamic module (copied */
+ /* earlier when the dynamic table was read in). Make sure that */
+ /* function addresses are valid before execution. */
+ /*------------------------------------------------------------------*/
+ for (i = 0; i < num_init_fcns; i++)
+ if (init_array_buf[i])
+ DLIF_execute(pHandle->client_handle,
+ (TARGET_ADDRESS)(init_array_buf[i]));
+ else
+ DLIF_warning(DLWT_MISC,
+ "DT_INIT_ARRAY/DT_PREINIT_ARRAY function address is NULL!");
+
+ DLIF_free(init_array_buf);
+ }
+ else
+ {
+ if (val->sect_addr)
+ DLIF_execute(pHandle->client_handle,
+ (TARGET_ADDRESS)(val->sect_addr));
+ else
+ DLIF_warning(DLWT_MISC, "DT_INIT function address is NULL!");
+ }
+ }
+}
+
+/*****************************************************************************/
+/* adjust_module_init_fini() */
+/* If the dynamic loader need not process the module initialization */
+/* and termination (fini section) then adjust the module info so that */
+/* the respective sizes become zero. */
+/*****************************************************************************/
+static void adjust_module_init_fini(DLIMP_Dynamic_Module *dm)
+{
+ /*------------------------------------------------------------------------*/
+ /* The C6x RTS boot code has the function _c_int00 which performs */
+ /* the C/C++ initialization. This function processes the .init_array */
+ /* to perform the C/C++ initialization and handles termination through */
+ /* the at_exit functionality. If the dynamic executable we are loading */
+ /* includes _c_int00, the loader assumes that the application code takes */
+ /* care of all initialization and termination. Hence the loader won't */
+ /* perform the initialization and termination. */
+ /* NOTE: Use of __TI_STACK_SIZE is a hack. The _c_int00 symbol is not */
+ /* in the dynamic symbol table. The right fix is for the linker */
+ /* not to generate the init array tags if the build includes RTS */
+ /* boot routine. */
+ /*------------------------------------------------------------------------*/
+ if (dm->fhdr.e_type == ET_EXEC &&
+ DLSYM_lookup_local_symtab("__TI_STACK_SIZE", dm->symtab, dm->symnum,
+ NULL))
+ {
+ dm->init_arraysz = 0;
+ dm->init_array_idx = -1;
+
+ dm->preinit_arraysz = 0;
+ dm->preinit_array_idx = -1;
+
+ dm->loaded_module->fini_arraysz = 0;
+ dm->loaded_module->fini_array = (Elf32_Addr) NULL;
+ dm->loaded_module->fini = (Elf32_Addr) NULL;
+ }
+}
+
+/*****************************************************************************/
+/* relocate_dependency_graph_modules() */
+/* */
+/* For each dynamic module on the dependency stack, process dynamic */
+/* relocation entries then perform initialization for all global and */
+/* static objects that are defined in tha given module. The stack is */
+/* emptied from the top (LIFO). Each dynamic module object is popped */
+/* off the top of the stack, the module gets relocated, its global and */
+/* static objects that need to be constructed will be constructed, and */
+/* then, after detaching the loaded module object from its dynamic */
+/* module, the dynamic module object is destructed. */
+/* */
+/*****************************************************************************/
+static
+int32_t relocate_dependency_graph_modules(DLOAD_HANDLE handle,
+ LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module)
+{
+ /*------------------------------------------------------------------------*/
+ /* Processing of relocations will only be triggered when this function */
+ /* is called from the top-level object module (at the bottom of the */
+ /* dependency graph stack). */
+ /*------------------------------------------------------------------------*/
+ int32_t local_file_handle = dyn_module->loaded_module->file_handle;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+ dynamic_module_ptr_Stack_Node *ptr =
+ pHandle->DLIMP_dependency_stack.bottom_ptr;
+ if (ptr && (ptr->value != dyn_module)) return local_file_handle;
+
+ if (is_dsbt_module(dyn_module))
+ {
+ /*--------------------------------------------------------------------*/
+ /* Assign DSBT indices. */
+ /*--------------------------------------------------------------------*/
+ DLIF_assign_dsbt_indices();
+
+ /*--------------------------------------------------------------------*/
+ /* Update the content of all DSBTs for any module that uses the */
+ /* DSBT model. */
+ /*--------------------------------------------------------------------*/
+ DLIF_update_all_dsbts();
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Ok, we are ready to process relocations. The relocation tables */
+ /* associated with dependent files will be processed first. Consume */
+ /* dynamic module objects from the dependency graph stack from dependents */
+ /* to the root of the dependency graph. */
+ /*------------------------------------------------------------------------*/
+ while (pHandle->DLIMP_dependency_stack.size > 0)
+ {
+ DLIMP_Dynamic_Module *dyn_mod_ptr =
+ dynamic_module_ptr_pop(&pHandle->DLIMP_dependency_stack);
+
+ /*---------------------------------------------------------------------*/
+ /* Process dynamic relocations associated with this module. */
+ /*---------------------------------------------------------------------*/
+ process_dynamic_module_relocations(handle, dyn_mod_ptr->fd, dyn_mod_ptr);
+
+ /*---------------------------------------------------------------------*/
+ /* __c_args__ points to the beginning of the .args section, if there */
+ /* is one. Record this pointer in the ELF file internal data object. */
+ /* Also store this in the loaded module, since this will be needed to */
+ /* write argv, argc to .args at execution time. */
+ /*---------------------------------------------------------------------*/
+ DLSYM_lookup_local_symtab("__c_args__", dyn_mod_ptr->symtab,
+ dyn_mod_ptr->symnum,
+ (Elf32_Addr *)&dyn_mod_ptr->c_args);
+ dyn_mod_ptr->loaded_module->c_args = dyn_mod_ptr->c_args;
+
+ /*---------------------------------------------------------------------*/
+ /* Pick up entry point address from ELF file header. */
+ /* We currently only support a single entry point into the ELF file. */
+ /* To support Braveheart notion of nodes, with multiple entry points,*/
+ /* we'll need to get the list of entry points associated with a node,*/
+ /* then add capability to the "execute" command to select the entry */
+ /* point that we want to start executing from. */
+ /*---------------------------------------------------------------------*/
+ dyn_mod_ptr->loaded_module->entry_point = dyn_mod_ptr->fhdr.e_entry;
+
+ /*---------------------------------------------------------------------*/
+ /* Copy command-line arguments into args section and deal with DSBT */
+ /* issues (copy DSBT to its run location). */
+ /* Note that below function is commented out because this doesn't do */
+ /* much as of now. */
+ /*---------------------------------------------------------------------*/
+ //load_object(dyn_mod_ptr->fd, dyn_mod_ptr);
+
+ /*---------------------------------------------------------------------*/
+ /* Perform initialization, if needed, for this module. */
+ /*---------------------------------------------------------------------*/
+ store_init_data(dyn_mod_ptr);
+
+ /*---------------------------------------------------------------------*/
+ /* Free all dependent file pointers. */
+ /*---------------------------------------------------------------------*/
+ if (dyn_mod_ptr->fd != fd)
+ {
+ DLIF_fclose(dyn_mod_ptr->fd);
+ dyn_mod_ptr->fd = NULL;
+ }
+
+ /*---------------------------------------------------------------------*/
+ /* Detach loaded module object from the dynamic module object that */
+ /* created it, then throw away the dynamic module object. */
+ /*---------------------------------------------------------------------*/
+ detach_loaded_module(dyn_mod_ptr);
+ delete_DLIMP_Dynamic_Module(handle, &dyn_mod_ptr);
+ }
+
+ return local_file_handle;
+}
+
+/*****************************************************************************/
+/* DLOAD_load() */
+/* */
+/* Dynamically load the specified file and return a file handle for the */
+/* loaded file. If the load fails, this function will return a value of */
+/* zero (0) for the file handle. */
+/* */
+/* The core loader must have read access to the file pointed to by fd. */
+/* */
+/*****************************************************************************/
+int32_t DLOAD_load(DLOAD_HANDLE handle, LOADER_FILE_DESC *fd)
+{
+ int32_t fl_handle;
+
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+ DLIMP_Dynamic_Module *dyn_module = new_DLIMP_Dynamic_Module(fd);
+
+ if (!dyn_module)
+ return 0;
+
+#if LOADER_DEBUG
+ /*------------------------------------------------------------------------*/
+ /* Spit out some loader progress information when we begin loading an */
+ /* object. */
+ /*------------------------------------------------------------------------*/
+ if (debugging_on) DLIF_trace("Loading file...\n");
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* If no access to a program was provided, there is nothing to do. */
+ /*------------------------------------------------------------------------*/
+ if (!fd)
+ {
+ DLIF_error(DLET_FILE, "Missing file specification.\n");
+ delete_DLIMP_Dynamic_Module(handle, &dyn_module);
+ return 0;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Read file headers and dynamic information into dynamic module. */
+ /*------------------------------------------------------------------------*/
+ if (!dload_headers(fd, dyn_module))
+ {
+ delete_DLIMP_Dynamic_Module(handle, &dyn_module);
+ return 0;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Find the dynamic segment, if there is one, and read dynamic */
+ /* information from the ELF object file into the dynamic module data */
+ /* structure associated with this file. */
+ /*------------------------------------------------------------------------*/
+ if (!dload_dynamic_segment(handle, fd, dyn_module))
+ return 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Perform sanity checking on the read-in ELF file. */
+ /*------------------------------------------------------------------------*/
+ if (!is_valid_elf_object_file(fd, dyn_module))
+ {
+ DLIF_error(DLET_FILE, "Attempt to load invalid ELF file, '%s'.\n",
+ dyn_module->name);
+ return 0;
+ }
+
+#if LOADER_DEBUG || LOADER_PROFILE
+ /*------------------------------------------------------------------------*/
+ /* Stop clock on initialization of ELF file information. Start clock on */
+ /* initialization of ELF module. */
+ /*------------------------------------------------------------------------*/
+ if (debugging_on || profiling_on)
+ {
+ DLIF_trace("Finished dload_dynamic_segment.\n");
+ if (profiling_on)
+ {
+ profile_stop_clock();
+ DLIF_trace("Took %lu cycles.\n",
+ (unsigned long) profile_cycle_count());
+ }
+ }
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* Initialize internal ELF module and segment structures. Sets */
+ /* loaded_module in *dyn_module. This also deals with assigning a file */
+ /* handle and bumping file handle counter. */
+ /*------------------------------------------------------------------------*/
+ initialize_loaded_module(handle, dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Append Module structure to loaded object list. */
+ /*------------------------------------------------------------------------*/
+ loaded_module_ptr_enqueue(&pHandle->DLIMP_loaded_objects,
+ dyn_module->loaded_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Support static loading as special case. */
+ /*------------------------------------------------------------------------*/
+ if (!dyn_module->relocatable)
+ return dload_static_executable(handle, fd, dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Get space & address for segments, and offset symbols and program */
+ /* header table to reflect the relocated address. Also offset the */
+ /* addresses in the internal Segment structures used by the Module */
+ /* structure. Note that this step needs to be performed prior and in */
+ /* addition to the relocation entry processing. */
+ /*------------------------------------------------------------------------*/
+ if (!allocate_dynamic_segments_and_relocate_symbols(handle, fd, dyn_module))
+ return 0;
+
+ /*------------------------------------------------------------------------*/
+ /* __c_args__ points to the beginning of the .args section, if there is */
+ /* one. __TI_STATIC_BASE points to the beginning of the DP-relative data */
+ /* segment (value to initialize DP). Record these addresses in the ELF */
+ /* file internal data object. */
+ /*------------------------------------------------------------------------*/
+ DLSYM_lookup_local_symtab("__c_args__", dyn_module->symtab,
+ dyn_module->symnum,
+ (Elf32_Addr *)&dyn_module->c_args);
+
+ DLSYM_lookup_local_symtab("__TI_STATIC_BASE", dyn_module->symtab,
+ dyn_module->symnum,
+ (Elf32_Addr *)&dyn_module->static_base);
+ dyn_module->loaded_module->static_base = dyn_module->static_base;
+
+ /*------------------------------------------------------------------------*/
+ /* If the user application performs initialization and termination, */
+ /* the dynamic loader shouldn't process the init/fini sections. */
+ /* Check and adjust the init/fini information accordingly. */
+ /*------------------------------------------------------------------------*/
+ adjust_module_init_fini(dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Execute any user defined pre-initialization functions that may be */
+ /* associated with a dynamic executable module. */
+ /*------------------------------------------------------------------------*/
+ if (dyn_module->fhdr.e_type == ET_EXEC)
+ store_preinit_data(dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Append current ELF file to list of objects currently loading. */
+ /* This is used to detect circular dependencies while we are processing */
+ /* the dependents of this file. */
+ /*------------------------------------------------------------------------*/
+ AL_append(&pHandle->DLIMP_module_dependency_list, &dyn_module->name);
+
+ /*------------------------------------------------------------------------*/
+ /* Push this dynamic module object onto the dependency stack. */
+ /* All of the modules on the stack will get relocated after all of the */
+ /* dependent files have been loaded and allocated. */
+ /*------------------------------------------------------------------------*/
+ dynamic_module_ptr_push(&pHandle->DLIMP_dependency_stack, dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* If this object file uses the DSBT model, then register a DSBT index */
+ /* request with the client's DSBT support management. */
+ /*------------------------------------------------------------------------*/
+ if (is_dsbt_module(dyn_module) &&
+ !DLIF_register_dsbt_index_request(handle,
+ dyn_module->name,
+ dyn_module->loaded_module->file_handle,
+ dyn_module->dsbt_index))
+ return 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Load this ELF file's dependees (all files on its DT_NEEDED list). */
+ /* Dependees must be loaded and relocated before processing this module's */
+ /* relocations. */
+ /*------------------------------------------------------------------------*/
+ if (!dload_and_allocate_dependencies(handle, dyn_module))
+ return 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Remove the current ELF file from the list of files that are in the */
+ /* process of loading. */
+ /*------------------------------------------------------------------------*/
+ pHandle->DLIMP_module_dependency_list.size--;
+
+ /*------------------------------------------------------------------------*/
+ /* Process relocation entries. */
+ /*------------------------------------------------------------------------*/
+ fl_handle = relocate_dependency_graph_modules(handle, fd, dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* With initialization complete, and all relocations having been resolved */
+ /* do module initialization. */
+ /*------------------------------------------------------------------------*/
+ execute_module_initialization(handle);
+
+ return fl_handle;
+}
+
+/*****************************************************************************/
+/* DLOAD_get_entry_names() */
+/* */
+/* Build a list of entry point names for a loaded object. Currently, */
+/* any global symbol in the module is considered a valid entry point */
+/* regardless of whether it is defined in code or associated with a */
+/* data object. We would need to process the content of the symbol */
+/* table entry or its debug information to determine whether it is a */
+/* valid entry point or not. */
+/* */
+/*****************************************************************************/
+BOOL DLOAD_get_entry_names(DLOAD_HANDLE handle,
+ uint32_t file_handle,
+ int32_t *entry_pt_cnt,
+ char ***entry_pt_names)
+{
+ /*------------------------------------------------------------------------*/
+ /* Spin through list of loaded files until we find the file handle we */
+ /* are looking for. Then build a list of entry points from that file's */
+ /* symbol table. */
+ /*------------------------------------------------------------------------*/
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ loaded_module_ptr_Queue_Node* ptr;
+ for (ptr = pHandle->DLIMP_loaded_objects.front_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ {
+ if (ptr->value->file_handle == file_handle)
+ {
+ DLIMP_Loaded_Module *module = ptr->value;
+ struct Elf32_Sym *symtab;
+ int i;
+
+ /*------------------------------------------------------------------*/
+ /* Any symbol in our file's symbol table is considered a valid */
+ /* entry point. */
+ /*------------------------------------------------------------------*/
+ symtab = (struct Elf32_Sym*)module->gsymtab;
+ *entry_pt_cnt = module->gsymnum;
+ *entry_pt_names = DLIF_malloc(*entry_pt_cnt * sizeof(char*));
+ for (i = 0; i < module->gsymnum; i++)
+ {
+ const char *sym_name = (const char *)symtab[i].st_name;
+ **entry_pt_names = DLIF_malloc(strlen(sym_name) + 1);
+ strcpy(**entry_pt_names,sym_name);
+ }
+
+ return TRUE;
+ }
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* We didn't find the file we were looking for, return false. */
+ /*------------------------------------------------------------------------*/
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLOAD_prepare_for_execution() */
+/* */
+/* Given a file handle, prepare for execution : */
+/* - Return entry point associated with that module in the *sym_val */
+/* output parameter. */
+/* - Write out the given arguments to the .args section contained in the */
+/* same module. */
+/* - As a test (for the Reference implementation) read the arguments */
+/* using the DLIF_read_arguments() function and set global argc,argv. */
+/* */
+/*****************************************************************************/
+BOOL DLOAD_prepare_for_execution(DLOAD_HANDLE handle, uint32_t file_handle,
+ TARGET_ADDRESS *sym_val,
+ int argc, char** argv)
+{
+ /*------------------------------------------------------------------------*/
+ /* Spin through list of loaded files until we find the file handle we */
+ /* are looking for. Then return the entry point address associated with */
+ /* that module. */
+ /*------------------------------------------------------------------------*/
+ DLIMP_Loaded_Module *ep_loaded_module;
+ loaded_module_ptr_Queue_Node* ptr;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (ptr = pHandle->DLIMP_loaded_objects.front_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ if (ptr->value->file_handle == file_handle)
+ {
+ *sym_val = (TARGET_ADDRESS)(ptr->value->entry_point);
+ ep_loaded_module = ptr->value;
+
+ /*------------------------------------------------------------------*/
+ /* Write argc, argv to the .args section in this module. */
+ /*------------------------------------------------------------------*/
+ if (!write_arguments_to_args_section(handle, argc, argv,
+ ep_loaded_module))
+ {
+ DLIF_error(DLET_MISC, "Couldn't write to .args section\n");
+ return FALSE;
+ }
+
+ /*------------------------------------------------------------------*/
+ /* For the Reference Implementation we simulate a "boot" (rts boot */
+ /* routine reads argc, argv from .args), by reading argc, argv from */
+ /* .args section. Note that we just wrote these values to the .args */
+ /* so this read serves as a test for the Reference Implementation. */
+ /*------------------------------------------------------------------*/
+ read_args_from_section(ep_loaded_module);
+ return TRUE;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* We didn't find the file we were looking for, return false. */
+ /*------------------------------------------------------------------------*/
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLOAD_load_arguments() */
+/* */
+/* Write out the given arguments to the .args section contained in the */
+/* same module. */
+/* */
+/*****************************************************************************/
+BOOL DLOAD_load_arguments(DLOAD_HANDLE handle, uint32_t file_handle,
+ int argc, char** argv)
+{
+ /*------------------------------------------------------------------------*/
+ /* Spin through list of loaded files until we find the file handle we */
+ /* are looking for. Then return the entry point address associated with */
+ /* that module. */
+ /*------------------------------------------------------------------------*/
+ DLIMP_Loaded_Module *ep_loaded_module;
+ loaded_module_ptr_Queue_Node* ptr;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (ptr = pHandle->DLIMP_loaded_objects.front_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ if (ptr->value->file_handle == file_handle)
+ {
+ ep_loaded_module = ptr->value;
+
+ /*------------------------------------------------------------------*/
+ /* Write argc, argv to the .args section in this module. */
+ /*------------------------------------------------------------------*/
+ if (!write_arguments_to_args_section(handle, argc, argv,
+ ep_loaded_module))
+ {
+ DLIF_error(DLET_MISC, "Couldn't write to .args section\n");
+ return FALSE;
+ }
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* We didn't find the file we were looking for, return false. */
+ /*------------------------------------------------------------------------*/
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLOAD_get_entry_point() */
+/* */
+/* Given a file handle, return the entry point associated with that */
+/* module in the *sym_val output parameter. */
+/* */
+/*****************************************************************************/
+BOOL DLOAD_get_entry_point(DLOAD_HANDLE handle, uint32_t file_handle,
+ TARGET_ADDRESS *sym_val)
+{
+ /*------------------------------------------------------------------------*/
+ /* Spin through list of loaded files until we find the file handle we */
+ /* are looking for. Then return the entry point address associated with */
+ /* that module. */
+ /*------------------------------------------------------------------------*/
+ loaded_module_ptr_Queue_Node* ptr;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (ptr = pHandle->DLIMP_loaded_objects.front_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ if (ptr->value->file_handle == file_handle)
+ {
+ *sym_val = (TARGET_ADDRESS)(ptr->value->entry_point);
+ return TRUE;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* We didn't find the file we were looking for, return false. */
+ /*------------------------------------------------------------------------*/
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLOAD_query_symbol() */
+/* */
+/* Query the value of a global symbol from a specific file. The value */
+/* result will be written to *sym_val. The function returns TRUE if the */
+/* symbol was found, and FALSE if it wasn't. */
+/* */
+/*****************************************************************************/
+BOOL DLOAD_query_symbol(DLOAD_HANDLE handle,
+ uint32_t file_handle,
+ const char *sym_name,
+ TARGET_ADDRESS *sym_val)
+{
+ /*------------------------------------------------------------------------*/
+ /* Spin through list of loaded files until we find the file handle we */
+ /* are looking for. Then return the value (target address) associated */
+ /* with the symbol we are looking for in that file. */
+ /*------------------------------------------------------------------------*/
+ loaded_module_ptr_Queue_Node* ptr;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (ptr = pHandle->DLIMP_loaded_objects.front_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ {
+ if (ptr->value->file_handle == file_handle)
+ {
+ DLIMP_Loaded_Module *module = ptr->value;
+ struct Elf32_Sym *symtab;
+ int i;
+
+ /*------------------------------------------------------------------*/
+ /* Search through the symbol table by name. */
+ /*------------------------------------------------------------------*/
+ symtab = (struct Elf32_Sym*)module->gsymtab;
+ for(i=0; i < module->gsymnum; i++)
+ {
+ if (!strcmp(sym_name, (const char *)symtab[i].st_name))
+ {
+ *sym_val = (TARGET_ADDRESS) symtab[i].st_value;
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* We didn't find the symbol we were looking for, return false. */
+ /*------------------------------------------------------------------------*/
+ return FALSE;
+}
+
+
+
+/*****************************************************************************/
+/* unlink_loaded_module() */
+/* */
+/* Unlink a loaded module data object from the list of loaded objects, */
+/* returning a pointer to the object so that it can be deconstructed. */
+/* */
+/*****************************************************************************/
+static DLIMP_Loaded_Module *unlink_loaded_module(DLOAD_HANDLE handle,
+ loaded_module_ptr_Queue_Node *back_ptr,
+ loaded_module_ptr_Queue_Node *lm_node)
+{
+ DLIMP_Loaded_Module *loaded_module = lm_node->value;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+ loaded_module_ptr_remove(&pHandle->DLIMP_loaded_objects, lm_node->value);
+ return loaded_module;
+}
+
+/*****************************************************************************/
+/* execute_module_termination() */
+/* */
+/* Execute termination functions associated with this loaded module. */
+/* Termination functions are called in the reverse order as their */
+/* corresponding initialization functions. */
+/* */
+/*****************************************************************************/
+static void execute_module_termination(DLOAD_HANDLE handle,
+ DLIMP_Loaded_Module *loaded_module)
+{
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ /*------------------------------------------------------------------------*/
+ /* If a DT_FINI_ARRAY dynamic tag was encountered for this module, spin */
+ /* through the array in reverse order, calling each function address */
+ /* stored in the array. */
+ /*------------------------------------------------------------------------*/
+ if (loaded_module->fini_arraysz != 0)
+ {
+ /*---------------------------------------------------------------------*/
+ /* Now make a loader-accessible copy of the .fini_array section. */
+ /*---------------------------------------------------------------------*/
+ int32_t i;
+ int32_t num_fini_fcns =
+ loaded_module->fini_arraysz/sizeof(TARGET_ADDRESS);
+ TARGET_ADDRESS *fini_array_buf = (TARGET_ADDRESS *)
+ DLIF_malloc(loaded_module->fini_arraysz);
+
+ DLIF_read(pHandle->client_handle,
+ fini_array_buf, 1, loaded_module->fini_arraysz,
+ (TARGET_ADDRESS)loaded_module->fini_array);
+
+ /*---------------------------------------------------------------------*/
+ /* Now spin through the array in reverse order, executing each */
+ /* termination function whose address occupies an entry in the array. */
+ /*---------------------------------------------------------------------*/
+ for (i = num_fini_fcns - 1; i >= 0; i--)
+ DLIF_execute(pHandle->client_handle,
+ (TARGET_ADDRESS)(fini_array_buf[i]));
+
+ DLIF_free(fini_array_buf);
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* If a DT_FINI dynamic tag was encountered for this module, call the */
+ /* function indicated by the tag's value to complete the termination */
+ /* process for this module. */
+ /*------------------------------------------------------------------------*/
+ if (loaded_module->fini != (Elf32_Addr) NULL)
+ DLIF_execute(pHandle->client_handle,
+ (TARGET_ADDRESS)loaded_module->fini);
+}
+
+/*****************************************************************************/
+/* remove_loaded_module() */
+/* */
+/* Find and unlink a loaded module data object from the list of loaded */
+/* objects, then call its destructor to free the host memory associated */
+/* with the loaded module and all of its loaded segments. */
+/* */
+/*****************************************************************************/
+static void remove_loaded_module(DLOAD_HANDLE handle,
+ loaded_module_ptr_Queue_Node *lm_node)
+{
+ DLIMP_Loaded_Module *lm_object = NULL;
+ loaded_module_ptr_Queue_Node *back_ptr = NULL;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ if (lm_node != pHandle->DLIMP_loaded_objects.front_ptr)
+ for (back_ptr = pHandle->DLIMP_loaded_objects.front_ptr;
+ back_ptr->next_ptr != lm_node;
+ back_ptr = back_ptr->next_ptr);
+
+ lm_object = unlink_loaded_module(handle, back_ptr, lm_node);
+
+ delete_DLIMP_Loaded_Module(handle, &lm_object);
+}
+
+/*****************************************************************************/
+/* DLOAD_unload() */
+/* */
+/* Unload specified module (identified by its file handle) from target */
+/* memory. Free up any target memory that was allocated for the module's */
+/* segments and also any host heap memory that was allocated for the */
+/* internal module and segment data structures. */
+/* */
+/* Return TRUE if program entry is actually destroyed. This is a way of */
+/* communicating to the client when it needs to actually remove debug */
+/* information associated with this module (so that client does not have */
+/* to maintain a use count that mirrors the program entry). */
+/* */
+/*****************************************************************************/
+BOOL DLOAD_unload(DLOAD_HANDLE handle, uint32_t file_handle)
+{
+ loaded_module_ptr_Queue_Node* lm_node;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (lm_node = pHandle->DLIMP_loaded_objects.front_ptr; lm_node != NULL;
+ lm_node = lm_node->next_ptr)
+ {
+ if (lm_node->value->file_handle == file_handle)
+ {
+ --lm_node->value->use_count;
+ if (lm_node->value->use_count == 0)
+ {
+ DLIMP_Loaded_Module *loaded_module =
+ (DLIMP_Loaded_Module *)lm_node->value;
+ int j;
+ int *dep_file_handles;
+
+ /*---------------------------------------------------------------*/
+ /* Termination functions need to be executed in the reverse */
+ /* order as the corresponding initialization functions, so */
+ /* before we go unload this module's dependents, we need to */
+ /* perform the user/global/static termination functions */
+ /* associated with this module. */
+ /*---------------------------------------------------------------*/
+ execute_module_termination(handle, loaded_module);
+
+ /*---------------------------------------------------------------*/
+ /* Unload dependent modules via the client. Client needs to know */
+ /* when a dependent gets unloaded so that it can update debug */
+ /* information. */
+ /*---------------------------------------------------------------*/
+ dep_file_handles = (int*)(loaded_module->dependencies.buf);
+ for (j = 0; j < loaded_module->dependencies.size; j++)
+ DLIF_unload_dependent(pHandle->client_handle,
+ dep_file_handles[j]);
+
+ /*---------------------------------------------------------------*/
+ /* Find the predecessor node of the value we're deleting, */
+ /* because its next_ptr will need to be updated. */
+ /* */
+ /* We can't keep a back pointer around because */
+ /* DLIF_unload_dependent() might free that node, making our */
+ /* pointer invalid. Turn the Queue template into a doubly */
+ /* linked list if this overhead becomes a problem. */
+ /*---------------------------------------------------------------*/
+ remove_loaded_module(handle, lm_node);
+
+ /*---------------------------------------------------------------*/
+ /* Once unloading is done, reset virtual target to NULL. */
+ /*---------------------------------------------------------------*/
+ cur_target = NULL;
+
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLOAD_load_symbols() */
+/* */
+/* Load the symbols from the given file and make symbols available for */
+/* global symbol linkage. */
+/* */
+/*****************************************************************************/
+int32_t DLOAD_load_symbols(DLOAD_HANDLE handle, LOADER_FILE_DESC *fd)
+{
+ DLIMP_Dynamic_Module *dyn_module = new_DLIMP_Dynamic_Module(fd);
+ DLIMP_Loaded_Module *loaded_module = NULL;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ /*------------------------------------------------------------------------*/
+ /* Ensure we have a valid dynamic module object from the constructor. */
+ /*------------------------------------------------------------------------*/
+ if (!dyn_module)
+ return 0;
+
+ /*------------------------------------------------------------------------*/
+ /* If no access to a program was provided, there is nothing to do. */
+ /*------------------------------------------------------------------------*/
+ if (!fd)
+ {
+ DLIF_error(DLET_FILE, "Missing file specification.\n");
+ return 0;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Record argc and argv pointers with the dynamic module record. */
+ /*------------------------------------------------------------------------*/
+ dyn_module->argc = 0;
+ dyn_module->argv = NULL;
+
+ /*------------------------------------------------------------------------*/
+ /* Read file headers and dynamic information into dynamic module. */
+ /*------------------------------------------------------------------------*/
+ if (!dload_headers(fd, dyn_module))
+ {
+ delete_DLIMP_Dynamic_Module(handle, &dyn_module);
+ return 0;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Find the dynamic segment, if there is one, and read dynamic */
+ /* information from the ELF object file into the dynamic module data */
+ /* structure associated with this file. */
+ /*------------------------------------------------------------------------*/
+ if (!dload_dynamic_segment(handle, fd, dyn_module))
+ {
+ delete_DLIMP_Dynamic_Module(handle, &dyn_module);
+ return 0;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Perform sanity checking on the read-in ELF file. */
+ /*------------------------------------------------------------------------*/
+ if (!is_valid_elf_object_file(fd, dyn_module))
+ {
+ DLIF_error(DLET_FILE, "Attempt to load invalid ELF file, '%s'.\n",
+ dyn_module->name);
+ delete_DLIMP_Dynamic_Module(handle, &dyn_module);
+ return 0;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Initialize internal ELF module and segment structures. Sets */
+ /* loaded_module in *dyn_module. This also deals with assigning a file */
+ /* handle and bumping file handle counter. */
+ /*------------------------------------------------------------------------*/
+ initialize_loaded_module(handle, dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Add this module to the loaded module queue. */
+ /* Detach the loaded module object from the dynamic module thath created */
+ /* it. Ownership of the host memory allocated for the loaded module */
+ /* object now belongs to the DLIMP_loaded_objects list. */
+ /*------------------------------------------------------------------------*/
+ loaded_module_ptr_enqueue(&pHandle->DLIMP_loaded_objects,
+ dyn_module->loaded_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Register a DSBT index request for this module and update its own copy */
+ /* of the DSBT with the contents of the client's master DSBT. */
+ /*------------------------------------------------------------------------*/
+ if (is_dsbt_module(dyn_module))
+ {
+ dynamic_module_ptr_push(&pHandle->DLIMP_dependency_stack, dyn_module);
+ DLIF_register_dsbt_index_request(handle,
+ dyn_module->name,
+ dyn_module->loaded_module->file_handle,
+ dyn_module->dsbt_index);
+ DLIF_assign_dsbt_indices();
+ DLIF_update_all_dsbts();
+ dynamic_module_ptr_pop(&pHandle->DLIMP_dependency_stack);
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Ownership of the host memory allocated for the loaded module object is */
+ /* transferred to the DLIMP_loaded_objects list. Free up the host memory */
+ /* for the dynamic module that created the loaded module object. Just */
+ /* call the destructor function for DLIMP_Dynamic_Module. */
+ /*------------------------------------------------------------------------*/
+ loaded_module = detach_loaded_module(dyn_module);
+ if(loaded_module == NULL)
+ {
+ delete_DLIMP_Dynamic_Module(handle, &dyn_module);
+ return 0;
+ }
+ delete_DLIMP_Dynamic_Module(handle, &dyn_module);
+
+ /*------------------------------------------------------------------------*/
+ /* Return a file handle so that the client can match this file to an ID. */
+ /*------------------------------------------------------------------------*/
+ return loaded_module->file_handle;
+}
+
+/*****************************************************************************/
+/* DSBT Support Functions */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* DLOAD_get_dsbt_size() */
+/* */
+/* Find the amount of space allocated for the specified module's DSBT. */
+/* It must be big enough to hold a copy of the master DSBT or the client */
+/* will flag an error. Those modules whose DSBT size is zero are assumed */
+/* to not be using the DSBT model. */
+/* */
+/*****************************************************************************/
+uint32_t DLOAD_get_dsbt_size(DLOAD_HANDLE handle, int32_t file_handle)
+{
+ dynamic_module_ptr_Stack_Node *ptr;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (ptr = pHandle->DLIMP_dependency_stack.top_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ {
+ DLIMP_Dynamic_Module *dmp = ptr->value;
+ if (dmp->loaded_module->file_handle == file_handle)
+ return dmp->dsbt_size;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* DLOAD_get_static_base() */
+/* */
+/* Look up static base symbol associated with the specified module. */
+/* */
+/*****************************************************************************/
+BOOL DLOAD_get_static_base(DLOAD_HANDLE handle, int32_t file_handle,
+ TARGET_ADDRESS *static_base)
+{
+ loaded_module_ptr_Queue_Node* ptr;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (ptr = pHandle->DLIMP_loaded_objects.front_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ {
+ DLIMP_Loaded_Module *lmp = ptr->value;
+ if (lmp->file_handle == file_handle)
+ {
+ *static_base = (TARGET_ADDRESS)lmp->static_base;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLOAD_get_dsbt_base() */
+/* */
+/* Look up address of DSBT for the specified module. */
+/* */
+/*****************************************************************************/
+BOOL DLOAD_get_dsbt_base(DLOAD_HANDLE handle, int32_t file_handle, TARGET_ADDRESS *dsbt_base)
+{
+ dynamic_module_ptr_Stack_Node *ptr;
+ LOADER_OBJECT *pHandle = (LOADER_OBJECT *)handle;
+
+ for (ptr = pHandle->DLIMP_dependency_stack.top_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ {
+ DLIMP_Dynamic_Module *dmp = ptr->value;
+ if (dmp->loaded_module->file_handle == file_handle)
+ {
+ *dsbt_base =
+ (TARGET_ADDRESS)dmp->dyntab[dmp->dsbt_base_tagidx].d_un.d_ptr;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* RELOCATE() - Perform RELA and REL type relocations for given ELF object */
+/* file that we are in the process of loading and relocating. */
+/*****************************************************************************/
+void DLREL_relocate(DLOAD_HANDLE handle, LOADER_FILE_DESC* elf_file,
+ DLIMP_Dynamic_Module* dyn_module)
+
+{
+ cur_target->relocate(handle, elf_file, dyn_module);
+}
+
+/*****************************************************************************/
+/* GET_VT_OBJ() - Once file headers have been read, use the e_machine id to */
+/* figure out the virtul target, so we can access trg specific funcs. */
+/*****************************************************************************/
+static VIRTUAL_TARGET *get_vt_obj(int given_id)
+{
+ VIRTUAL_TARGET *ptr;
+
+ for(ptr = vt_arr; ptr->machine_id != EM_NONE ; ptr++)
+ if (ptr->machine_id == given_id) return ptr;
+
+ return NULL;
+}
+
+#if 0 && LOADER_DEBUG // enable to make available in debugger
+/*****************************************************************************/
+/* DEBUG_QUEUE() - Debug function. */
+/*****************************************************************************/
+static void debug_queue(LOADER_OBJECT *pHandle, char* position)
+{
+ loaded_module_ptr_Queue_Node* ptr;
+
+ if (!debugging_on) return;
+
+ DLIF_trace ("\nDEBUG QUEUE : %s, pHandle : 0x%x\n\n", position,
+ (uint32_t)pHandle);
+
+ for (ptr = pHandle->DLIMP_loaded_objects.front_ptr; ptr != NULL;
+ ptr = ptr->next_ptr)
+ {
+ DLIF_trace ("ptr->value->name : %s\n",ptr->value->name);
+ }
+ DLIF_trace ("\n");
+}
+#endif
+
+/*****************************************************************************/
+/* READ_ARGS_FROM_SECTION() - This function reads the argc, argv from the */
+/* .args section, and is used to test Reference implementation. */
+/*****************************************************************************/
+static void read_args_from_section(DLIMP_Loaded_Module* ep_module)
+{
+ /*------------------------------------------------------------------------*/
+ /* Before this function in called, the loader has gotten argv/argc from */
+ /* the module and written it out to the .args section. c_args points to */
+ /* the .args section. */
+ /*------------------------------------------------------------------------*/
+ ARGS_CONTAINER *pargs = (ARGS_CONTAINER *)(ep_module->c_args);
+ if (!pargs || pargs == (ARGS_CONTAINER *)0xFFFFFFFF)
+ {
+ global_argc = 0;
+ global_argv = NULL;
+ }
+ else
+ {
+ global_argc = pargs->argc;
+ global_argv = pargs->argv;
+ }
+}
diff --git a/src/core/dsp/ocl_load/DLOAD/dload.h b/src/core/dsp/ocl_load/DLOAD/dload.h
new file mode 100644
index 0000000..bb7d427
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/dload.h
@@ -0,0 +1,334 @@
+/*
+* dload.h
+*
+* Define internal data structures used by core dynamic loader.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef DLOAD_H
+#define DLOAD_H
+
+#include "ArrayList.h"
+#include "Queue.h"
+#include "Stack.h"
+#include "elf32.h"
+#include "dload_api.h"
+#include "util.h"
+
+/*---------------------------------------------------------------------------*/
+/* Contains strings with names of files the loader is in process of loading. */
+/* This list is used to keep track of what objects are in the process of */
+/* loading while their dependents are being loaded so that we can detect */
+/* circular dependencies. */
+/*---------------------------------------------------------------------------*/
+extern Array_List DLIMP_module_dependency_list;
+
+/*---------------------------------------------------------------------------*/
+/* DLIMP_Loaded_Segment */
+/* */
+/* This structure represents a segment loaded on memory. */
+/* */
+/* This data structure should be created using host memory when a module */
+/* is being loaded into target memory. The data structure should persist */
+/* as long as the module stays resident in target memory. It should be */
+/* removed when the last use of the module is unloaded from the target. */
+/*---------------------------------------------------------------------------*/
+typedef struct
+{
+ struct Elf32_Phdr phdr;
+ Elf32_Addr input_vaddr; /* original segment load addr */
+ BOOL modified;
+ struct DLOAD_MEMORY_SEGMENT *obj_desc;
+ void * host_address;
+} DLIMP_Loaded_Segment;
+
+/*---------------------------------------------------------------------------*/
+/* DLIMP_Loaded_Module */
+/* */
+/* This structure contains all the information the dynamic loader needs */
+/* to retain after loading an object file's segments into target memory. */
+/* The data structure is created while the object file is being loaded, */
+/* and should persist until the last use of the module is unloaded from */
+/* target memory. */
+/* */
+/* The information contained here is used by the dynamic loader to */
+/* perform dynamic symbol resolution, to track the use count, and to */
+/* finally deallocate the module's segments when the module is unloaded. */
+/*---------------------------------------------------------------------------*/
+typedef struct
+{
+ char *name; /* Local copy of so_name */
+ int32_t file_handle;
+ int32_t use_count;
+ Elf32_Addr entry_point; /* Entry point address into module */
+ struct Elf32_Sym *gsymtab; /* Module's global symbol table */
+ Elf32_Word gsymnum; /* # global symbols */
+ char *gstrtab; /* Module's global symbol names */
+ Elf32_Word gstrsz; /* Size of global string table */
+ Array_List loaded_segments; /* List of DLIMP_Loaded_Segment(s) */
+ Array_List dependencies; /* List of dependent file handles */
+ BOOL direct_dependent_only;
+
+ Elf32_Addr fini; /* .fini function/section address */
+ Elf32_Addr fini_array; /* .fini_array term fcn ary addr */
+ int32_t fini_arraysz; /* sizeof .fini_array */
+ uint8_t *c_args; /* address of module's .args sect */
+ uint8_t *static_base; /* address of module's STATIC_BASE */
+
+} DLIMP_Loaded_Module;
+
+/*---------------------------------------------------------------------------*/
+/* DLIMP_loaded_objects */
+/* */
+/* A list of loaded module objects (DLIMP_Loaded_Module *) that the */
+/* loader has placed into target memory. */
+/*---------------------------------------------------------------------------*/
+TYPE_QUEUE_DEFINITION(DLIMP_Loaded_Module*, loaded_module_ptr)
+extern loaded_module_ptr_Queue DLIMP_loaded_objects;
+
+/*---------------------------------------------------------------------------*/
+/* DLIMP_Dynamic_Module */
+/* */
+/* This structure represents a dynamic module to be loaded by the dynamic */
+/* loader. It contains all the information necessary to load and relocate */
+/* the module. It actually contains most of the headers, dynamic info, */
+/* dynamic symbol table, string table etc. */
+/* */
+/* This structure is allocated in host memory while an ELF object file is */
+/* being loaded and will be destructed after the file has been */
+/* successfully loaded. To simplify loading and relocation of the object */
+/* file's segments, this data structure maintains a link to the loaded */
+/* module. This link is severed when the load is successfully completed. */
+/* The loaded module data structure will persist until the module is */
+/* actually unloaded from target memory, but this data structure will be */
+/* freed. */
+/* */
+/* If the load of the object file is not successful for any reason, then */
+/* the loaded module will not be detached from the dynamic module. In */
+/* such case, the destructor for the dynamic module will assume */
+/* responsibility for freeing any host memory associated with the loaded */
+/* module and its segments. */
+/*---------------------------------------------------------------------------*/
+typedef struct
+{
+ char *name; /* Local copy of so_name */
+ LOADER_FILE_DESC *fd; /* Access to ELF object file */
+ struct Elf32_Ehdr fhdr; /* ELF Object File Header */
+ struct Elf32_Phdr *phdr; /* ELF Program Header Table */
+ Elf32_Word phnum; /* # entries in program header table */
+ char* strtab; /* String Table */
+ Elf32_Word strsz; /* String Table size in bytes */
+ struct Elf32_Dyn *dyntab; /* Elf Dynamic Table (.dynamic scn) */
+ /* This contains a list of dynamic */
+ /* tags which is terminated by a NULL */
+ /* record. */
+ struct Elf32_Sym *symtab; /* Elf Dynamic Symbol Table */
+ Elf32_Word symnum; /* # symbols in dynamic symbol table */
+ Elf32_Word gsymtab_offset;/* Offset into symbol table where */
+ /* global symbols start. */
+ Elf32_Word gstrtab_offset;/* Offset into string table where */
+ /* global symbol names start. */
+
+ uint8_t *c_args;
+ uint8_t *static_base; /* address of module's STATIC_BASE */
+ int32_t argc;
+ char **argv;
+ DLIMP_Loaded_Module *loaded_module;
+ int32_t wrong_endian;
+ BOOL direct_dependent_only;
+ BOOL relocatable; /* TRUE if module can be relocated */
+ /* at load-time. FALSE if module is */
+ /* a static executable. */
+ BOOL relocate_entry_point; /* TRUE if the entry point has */
+ /* not been relocated */
+
+ int32_t dsbt_index; /* DSBT index requested/assigned */
+ uint32_t dsbt_size; /* DSBT size for this module */
+ int32_t dsbt_base_tagidx;/* Location of DSBT base dyn tag */
+
+ int32_t preinit_array_idx; /* DT_PREINIT_ARRAY dyn tag loc */
+ int32_t preinit_arraysz; /* sizeof pre-init array */
+ int32_t init_idx; /* DT_INIT dynamic tag location */
+ int32_t init_array_idx; /* DT_INIT_ARRAY dyn tag location */
+ int32_t init_arraysz; /* sizeof init array */
+
+} DLIMP_Dynamic_Module;
+
+/*---------------------------------------------------------------------------*/
+/* DLIMP_dependency_stack */
+/* */
+/* A LIFO stack of dynamic module objects (DLIMP_Dynamic_Module *) that */
+/* is retained while dependent files are being loaded and allocated. It */
+/* is used to guide which dynamic modules need to be relocated after all */
+/* items in the dependency graph have been allocated. The stack is only */
+/* used when the client asks the core loader to load a dynamic executable */
+/* or library. When relocation is completed, this stack should be empty. */
+/*---------------------------------------------------------------------------*/
+TYPE_STACK_DEFINITION(DLIMP_Dynamic_Module*, dynamic_module_ptr)
+extern dynamic_module_ptr_Stack DLIMP_dependency_stack;
+
+/*---------------------------------------------------------------------------*/
+/* Private Loader Object instance. */
+/*---------------------------------------------------------------------------*/
+typedef struct
+{
+ /*-----------------------------------------------------------------------*/
+ /* Contains filenames (type const char*) the system is in the process of */
+ /* loading. Used to detect cycles in incorrectly compiled ELF binaries. */
+ /*-----------------------------------------------------------------------*/
+ Array_List DLIMP_module_dependency_list;
+
+ /*-----------------------------------------------------------------------*/
+ /* Contains objects (type DLIMP_Loaded_Module) that the system has loaded*/
+ /* into target memory. */
+ /*-----------------------------------------------------------------------*/
+ loaded_module_ptr_Queue DLIMP_loaded_objects;
+
+ /*-----------------------------------------------------------------------*/
+ /* Dependency Graph Queue - FIFO queue of dynamic modules that are loaded*/
+ /* when client asks to load a dynamic executable or library. Note that */
+ /* dependents that have already been loaded with another module will not */
+ /* appear on this queue. */
+ /*-----------------------------------------------------------------------*/
+ dynamic_module_ptr_Stack DLIMP_dependency_stack;
+
+ /*-----------------------------------------------------------------------*/
+ /* Counter for generating unique IDs for file handles. */
+ /* NOTE: File handle is assigned sequencially but is never reclaimed */
+ /* when the modules are unloaded. It is conceivable that a loader*/
+ /* running for a long time and loading and unloading modules */
+ /* could wrap-around. The loader generates error in this case. */
+ /* Presumably each loader instance has a list of file handles, one for */
+ /* each file that it loads, and the file handle serves as an index into */
+ /* the list. Therefore even if the same file is loaded by two loader */
+ /* instances, both loader instances have a different file handle for the */
+ /* file - the file is mapped uniquely to it's appopriate file handle per */
+ /* loader instance. */
+ /*-----------------------------------------------------------------------*/
+ int32_t file_handle;
+
+ /*-----------------------------------------------------------------------*/
+ /* Client token, passed in via DLOAD_create() */
+ /*-----------------------------------------------------------------------*/
+ void * client_handle;
+} LOADER_OBJECT;
+
+
+/*****************************************************************************/
+/* IF data : Below are the data structures used to store init-fini data. */
+/*****************************************************************************/
+typedef struct
+{
+ TARGET_ADDRESS sect_addr;
+ int32_t size;
+}
+IF_single_record;
+
+TYPE_QUEUE_DEFINITION(IF_single_record*, IF_table)
+extern IF_table_Queue TI_init_table;
+
+
+/*****************************************************************************/
+/* Container used to read in argc, argv from the .srgs section. */
+/*****************************************************************************/
+typedef struct { int argc; char *argv[1]; } ARGS_CONTAINER;
+
+
+/*****************************************************************************/
+/* is_DSBT_module() */
+/* */
+/* return true if the module uses DSBT model */
+/*****************************************************************************/
+static inline BOOL is_dsbt_module(DLIMP_Dynamic_Module *dyn_module)
+{
+ return (dyn_module->dsbt_size != 0);
+}
+
+/*****************************************************************************/
+/* is_arm_module() */
+/* */
+/* return true if the module being processed is for ARM */
+/*****************************************************************************/
+static inline BOOL is_arm_module(struct Elf32_Ehdr* fhdr)
+{
+ return fhdr->e_machine == EM_ARM;
+}
+
+/*****************************************************************************/
+/* is_c60_module() */
+/* */
+/* return true if the module being processed is for C60 */
+/*****************************************************************************/
+static inline BOOL is_c60_module(struct Elf32_Ehdr* fhdr)
+{
+ return fhdr->e_machine == EM_TI_C6000;
+}
+
+/*---------------------------------------------------------------------------*/
+/* DLIMP_update_dyntag_section_address() */
+/* */
+/* Given the index of a dynamic tag which we happen to know points to a */
+/* section address, find the program header table entry associated with */
+/* the specified address and update the tag value with the real address */
+/* of the section. */
+/* */
+/*---------------------------------------------------------------------------*/
+extern BOOL DLIMP_update_dyntag_section_address(DLIMP_Dynamic_Module *dyn_module,
+ int32_t i);
+
+extern uint32_t DLIMP_get_first_dyntag(int tag, struct Elf32_Dyn* dyn_table);
+
+/*---------------------------------------------------------------------------*/
+/* Global flags to help manage internal debug and profiling efforts. */
+/*---------------------------------------------------------------------------*/
+#ifndef __TI_COMPILER_VERSION__
+#define LOADER_DEBUG 1
+#else
+#define LOADER_DEBUG 0
+#endif
+
+#undef LOADER_DEBUG
+
+#define LOADER_DEBUG 1
+#define LOADER_PROFILE 1
+
+#if LOADER_DEBUG
+extern BOOL debugging_on;
+#endif
+
+#if LOADER_DEBUG || LOADER_PROFILE
+extern BOOL profiling_on;
+#endif
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD/dload_endian.c b/src/core/dsp/ocl_load/DLOAD/dload_endian.c
new file mode 100644
index 0000000..ac6413b
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/dload_endian.c
@@ -0,0 +1,151 @@
+/*
+* dload_endian.c
+*
+* Simple helper functions to assist core loader with endian-ness issues
+* when the host endian-ness may be opposite the endian-ness of the target.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#include "dload_endian.h"
+
+/*****************************************************************************/
+/* DLIMP_GET_ENDIAN() - Determine endianness of the host. Uses ELF */
+/* endianness constants. */
+/*****************************************************************************/
+int DLIMP_get_endian()
+{
+ int32_t x = 0x1;
+
+ if (*((int16_t*)(&x))) return ELFDATA2LSB;
+
+ return ELFDATA2MSB;
+}
+
+/*****************************************************************************/
+/* DLIMP_CHANGE_ENDIAN32() - Swap endianness of a 32-bit integer. */
+/*****************************************************************************/
+void DLIMP_change_endian32(int32_t* to_change)
+{
+ int32_t temp = 0;
+ temp += (*to_change & 0x000000FF) << 24;
+ temp += (*to_change & 0x0000FF00) << 8;
+ temp += (*to_change & 0x00FF0000) >> 8;
+ temp += (*to_change & 0xFF000000) >> 24;
+ *to_change = temp;
+}
+
+/*****************************************************************************/
+/* DLIMP_CHANGE_ENDIAN16() - Swap endianness of a 16-bit integer. */
+/*****************************************************************************/
+void DLIMP_change_endian16(int16_t* to_change)
+{
+ int16_t temp = 0;
+ temp += (*to_change & 0x00FF) << 8;
+ temp += (*to_change & 0xFF00) >> 8;
+ *to_change = temp;
+}
+
+/*****************************************************************************/
+/* DLIMP_CHANGE_EHDR_ENDIAN() - Swap endianness of an ELF file header. */
+/*****************************************************************************/
+void DLIMP_change_ehdr_endian(struct Elf32_Ehdr* ehdr)
+{
+ DLIMP_change_endian16((int16_t*)(&ehdr->e_type));
+ DLIMP_change_endian16((int16_t*)(&ehdr->e_machine));
+ DLIMP_change_endian32((int32_t*)(&ehdr->e_version));
+ DLIMP_change_endian32((int32_t*)(&ehdr->e_entry));
+ DLIMP_change_endian32((int32_t*)(&ehdr->e_phoff));
+ DLIMP_change_endian32((int32_t*)(&ehdr->e_shoff));
+ DLIMP_change_endian32((int32_t*)(&ehdr->e_flags));
+ DLIMP_change_endian16((int16_t*)(&ehdr->e_ehsize));
+ DLIMP_change_endian16((int16_t*)(&ehdr->e_phentsize));
+ DLIMP_change_endian16((int16_t*)(&ehdr->e_phnum));
+ DLIMP_change_endian16((int16_t*)(&ehdr->e_shentsize));
+ DLIMP_change_endian16((int16_t*)(&ehdr->e_shnum));
+ DLIMP_change_endian16((int16_t*)(&ehdr->e_shstrndx));
+}
+
+/*****************************************************************************/
+/* DLIMP_CHANGE_PHDR_ENDIAN() - Swap endianness of an ELF program header. */
+/*****************************************************************************/
+void DLIMP_change_phdr_endian(struct Elf32_Phdr* phdr)
+{
+ DLIMP_change_endian32((int32_t*)(&phdr->p_type));
+ DLIMP_change_endian32((int32_t*)(&phdr->p_offset));
+ DLIMP_change_endian32((int32_t*)(&phdr->p_vaddr));
+ DLIMP_change_endian32((int32_t*)(&phdr->p_paddr));
+ DLIMP_change_endian32((int32_t*)(&phdr->p_filesz));
+ DLIMP_change_endian32((int32_t*)(&phdr->p_memsz));
+ DLIMP_change_endian32((int32_t*)(&phdr->p_flags));
+ DLIMP_change_endian32((int32_t*)(&phdr->p_align));
+}
+
+/*****************************************************************************/
+/* DLIMP_CHANGE_DYNENT_ENDIAN() - Swap endianness of a dynamic table entry. */
+/*****************************************************************************/
+void DLIMP_change_dynent_endian(struct Elf32_Dyn* dyn)
+{
+ DLIMP_change_endian32((int32_t*)(&dyn->d_tag));
+ DLIMP_change_endian32((int32_t*)(&dyn->d_un.d_val));
+}
+
+/*****************************************************************************/
+/* DLIMP_CHANGE_SYM_ENDIAN() - Swap endianness of an ELF symbol table entry. */
+/*****************************************************************************/
+void DLIMP_change_sym_endian(struct Elf32_Sym* sym)
+{
+ DLIMP_change_endian32((int32_t*)(&sym->st_name));
+ DLIMP_change_endian32((int32_t*)(&sym->st_value));
+ DLIMP_change_endian32((int32_t*)(&sym->st_size));
+ DLIMP_change_endian16((int16_t*)(&sym->st_shndx));
+}
+
+/*****************************************************************************/
+/* DLIMP_CHANGE_RELA_ENDIAN() - Swap endianness of a RELA-type relocation. */
+/*****************************************************************************/
+void DLIMP_change_rela_endian(struct Elf32_Rela* ra)
+{
+ DLIMP_change_endian32((int32_t*)(&ra->r_offset));
+ DLIMP_change_endian32((int32_t*)(&ra->r_info));
+ DLIMP_change_endian32((int32_t*)(&ra->r_addend));
+}
+
+/*****************************************************************************/
+/* DLIMP_CHANGE_REL_ENDIAN() - Swap endianness of a REL-type relocation. */
+/*****************************************************************************/
+void DLIMP_change_rel_endian(struct Elf32_Rel* r)
+{
+ DLIMP_change_endian32((int32_t*)(&r->r_offset));
+ DLIMP_change_endian32((int32_t*)(&r->r_info));
+}
diff --git a/src/core/dsp/ocl_load/DLOAD/dload_endian.h b/src/core/dsp/ocl_load/DLOAD/dload_endian.h
new file mode 100644
index 0000000..ee74e11
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/dload_endian.h
@@ -0,0 +1,58 @@
+/*
+* dload_endian.h
+*
+* Specification of functions used to assist loader with endian-ness issues.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef DLOAD_ENDIAN_H
+#define DLOAD_ENDIAN_H
+
+#include "elf32.h"
+
+/*---------------------------------------------------------------------------*/
+/* Prototypes for ELF file object reader endianness swap routines. */
+/*---------------------------------------------------------------------------*/
+
+int DLIMP_get_endian(void);
+void DLIMP_change_endian32(int32_t* to_change);
+void DLIMP_change_endian16(int16_t* to_change);
+void DLIMP_change_ehdr_endian(struct Elf32_Ehdr* to_change);
+void DLIMP_change_phdr_endian(struct Elf32_Phdr* to_change);
+void DLIMP_change_dynent_endian(struct Elf32_Dyn* to_change);
+void DLIMP_change_sym_endian(struct Elf32_Sym* to_change);
+void DLIMP_change_rela_endian(struct Elf32_Rela* to_change);
+void DLIMP_change_rel_endian(struct Elf32_Rel* to_change);
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD/elf32.c b/src/core/dsp/ocl_load/DLOAD/elf32.c
new file mode 100644
index 0000000..082ba01
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/elf32.c
@@ -0,0 +1,652 @@
+/*
+* elf32.c
+*
+* Basic Data Structures for 32-Bit ELF Object Format Files
+*
+* The data structures in this file come primarily from this specification:
+*
+* Tool Interface Standard (TIS)
+* Executable and Linking Format (ELF) Specification
+* Version 1.2
+*
+* TIS Committee
+* May 1995
+*
+* Additions and enhancements from this specification are also included:
+*
+* System V Application Binary Interface
+* DRAFT 17
+* December 2003
+*
+* http://sco.com/developers/gabi/2003-12-17/contents.html
+*
+* This is a C implementation of the data base objects that are commonly
+* used in the source for TI development tools that support ELF.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#include "elf32.h"
+
+/*---------------------------------------------------------------------------*/
+/* Dynamic Tag Database */
+/*---------------------------------------------------------------------------*/
+
+const struct EDYN_TAG EDYN_TAG_DB[] =
+{
+ /* EDYN_TAG_NULL */
+ {
+ /* d_tag_name */ "DT_NULL",
+ /* d_tag_value */ DT_NULL,
+ /* d_untype */ EDYN_UNTYPE_IGNORED,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_MANDATORY
+ },
+
+ /* EDYN_TAG_NEEDED */
+ {
+ /* d_tag_name */ "DT_NEEDED",
+ /* d_tag_value */ DT_NEEDED,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_PLTRELSZ */
+ {
+ /* d_tag_name */ "DT_PLTRELSZ",
+ /* d_tag_value */ DT_PLTRELSZ,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_PLTGOT */
+ {
+ /* d_tag_name */ "DT_PLTGOT",
+ /* d_tag_value */ DT_PLTGOT,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_HASH */
+ {
+ /* d_tag_name */ "DT_HASH",
+ /* d_tag_value */ DT_HASH,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_MANDATORY
+ },
+
+ /* EDYN_TAG_STRTAB */
+ {
+ /* d_tag_name */ "DT_STRTAB",
+ /* d_tag_value */ DT_STRTAB,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_MANDATORY
+ },
+
+ /* EDYN_TAG_SYMTAB */
+ {
+ /* d_tag_name */ "DT_SYMTAB",
+ /* d_tag_value */ DT_SYMTAB,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_MANDATORY
+ },
+
+ /* EDYN_TAG_RELA */
+ {
+ /* d_tag_name */ "DT_RELA",
+ /* d_tag_value */ DT_RELA,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_RELASZ */
+ {
+ /* d_tag_name */ "DT_RELASZ",
+ /* d_tag_value */ DT_RELASZ,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_RELAENT */
+ {
+ /* d_tag_name */ "DT_RELAENT",
+ /* d_tag_value */ DT_RELAENT,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_STRSZ */
+ {
+ /* d_tag_name */ "DT_STRSZ",
+ /* d_tag_value */ DT_STRSZ,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_MANDATORY
+ },
+
+ /* EDYN_TAG_SYMENT */
+ {
+ /* d_tag_name */ "DT_SYMENT",
+ /* d_tag_value */ DT_SYMENT,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_MANDATORY
+ },
+
+ /* EDYN_TAG_INIT */
+ {
+ /* d_tag_name */ "DT_INIT",
+ /* d_tag_value */ DT_INIT,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_FINI */
+ {
+ /* d_tag_name */ "DT_FINI",
+ /* d_tag_value */ DT_FINI,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_SONAME */
+ {
+ /* d_tag_name */ "DT_SONAME",
+ /* d_tag_value */ DT_SONAME,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_IGNORED,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_RPATH */
+ {
+ /* d_tag_name */ "DT_RPATH",
+ /* d_tag_value */ DT_RPATH,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_IGNORED
+ },
+
+ /* EDYN_TAG_SYMBOLIC */
+ {
+ /* d_tag_name */ "DT_SYMBOLIC",
+ /* d_tag_value */ DT_SYMBOLIC,
+ /* d_untype */ EDYN_UNTYPE_IGNORED,
+ /* d_exec_req */ EDYN_TAGREQ_IGNORED,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_REL */
+ {
+ /* d_tag_name */ "DT_REL",
+ /* d_tag_value */ DT_REL,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_RELSZ */
+ {
+ /* d_tag_name */ "DT_RELSZ",
+ /* d_tag_value */ DT_RELSZ,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_RELENT */
+ {
+ /* d_tag_name */ "DT_RELENT",
+ /* d_tag_value */ DT_RELENT,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_MANDATORY,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_PLTREL */
+ {
+ /* d_tag_name */ "DT_PLTREL",
+ /* d_tag_value */ DT_PLTREL,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_DEBUG */
+ {
+ /* d_tag_name */ "DT_DEBUG",
+ /* d_tag_value */ DT_DEBUG,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_IGNORED
+ },
+
+ /* EDYN_TAG_TEXTREL */
+ {
+ /* d_tag_name */ "DT_TEXTREL",
+ /* d_tag_value */ DT_TEXTREL,
+ /* d_untype */ EDYN_UNTYPE_IGNORED,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_JMPREL */
+ {
+ /* d_tag_name */ "DT_JMPREL",
+ /* d_tag_value */ DT_JMPREL,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_BIND_NOW */
+ {
+ /* d_tag_name */ "DT_BIND_NOW",
+ /* d_tag_value */ DT_BIND_NOW,
+ /* d_untype */ EDYN_UNTYPE_IGNORED,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_INIT_ARRAY */
+ {
+ /* d_tag_name */ "DT_INIT_ARRAY",
+ /* d_tag_value */ DT_INIT_ARRAY,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_FINI_ARRAY */
+ {
+ /* d_tag_name */ "DT_FINI_ARRAY",
+ /* d_tag_value */ DT_FINI_ARRAY,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_INIT_ARRAYSZ */
+ {
+ /* d_tag_name */ "DT_INIT_ARRAYSZ",
+ /* d_tag_value */ DT_INIT_ARRAYSZ,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_FINI_ARRAYSZ */
+ {
+ /* d_tag_name */ "DT_FINI_ARRAYSZ",
+ /* d_tag_value */ DT_FINI_ARRAYSZ,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_RUNPATH */
+ {
+ /* d_tag_name */ "DT_RUNPATH",
+ /* d_tag_value */ DT_RUNPATH,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_FLAGS */
+ {
+ /* d_tag_name */ "DT_FLAGS",
+ /* d_tag_value */ DT_FLAGS,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_OPTIONAL
+ },
+
+ /* EDYN_TAG_ENCODING */
+ {
+ /* d_tag_name */ "DT_ENCODING",
+ /* d_tag_value */ DT_ENCODING,
+ /* d_untype */ EDYN_UNTYPE_UNSPECIFIED,
+ /* d_exec_req */ EDYN_TAGREQ_UNSPECIFIED,
+ /* d_shared_req */ EDYN_TAGREQ_UNSPECIFIED
+ },
+
+ /* EDYN_TAG_PREINIT_ARRAY */
+ {
+ /* d_tag_name */ "DT_PREINIT_ARRAY",
+ /* d_tag_value */ DT_PREINIT_ARRAY,
+ /* d_untype */ EDYN_UNTYPE_PTR,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_IGNORED
+ },
+
+ /* EDYN_TAG_PREINIT_ARRAYSZ */
+ {
+ /* d_tag_name */ "DT_PREINIT_ARRAYSZ",
+ /* d_tag_value */ DT_PREINIT_ARRAYSZ,
+ /* d_untype */ EDYN_UNTYPE_VAL,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_IGNORED
+ },
+
+ /* Terminate array with an id of -1 */
+ {
+ /* d_tag_name */ "",
+ /* d_tag_value */ -1,
+ /* d_untype */ EDYN_UNTYPE_UNSPECIFIED,
+ /* d_exec_req */ EDYN_TAGREQ_OPTIONAL,
+ /* d_shared_req */ EDYN_TAGREQ_IGNORED
+ }
+};
+
+/*---------------------------------------------------------------------------*/
+/* Special Section Database */
+/*---------------------------------------------------------------------------*/
+const struct ESCN ESCN_DB[] =
+{
+ /* .bss */
+ {
+ /* name */ ESCN_BSS_name,
+ /* sh_type */ SHT_NOBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_WRITE
+ },
+
+ /* .comment */
+ {
+ /* name */ ESCN_COMMENT_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ 0
+ },
+
+ /* .data */
+ {
+ /* name */ ESCN_DATA_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_WRITE
+ },
+
+ /* .data1 */
+ {
+ /* name */ ESCN_DATA1_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_WRITE
+ },
+
+ /* .debug */
+ {
+ /* name */ ESCN_DEBUG_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ 0
+ },
+
+ /* .dynamic */
+ {
+ /* name */ ESCN_DYNAMIC_name,
+ /* sh_type */ SHT_DYNAMIC,
+ /* sh_entsize */ sizeof(struct Elf32_Dyn),
+ /* sh_flags */ SHF_ALLOC
+ },
+
+ /* .dynstr */
+ {
+ /* name */ ESCN_DYNSTR_name,
+ /* sh_type */ SHT_STRTAB,
+ /* sh_entsize */ sizeof(char),
+ /* sh_flags */ SHF_ALLOC + SHF_STRINGS
+ },
+
+ /* .dynsym */
+ {
+ /* name */ ESCN_DYNSYM_name,
+ /* sh_type */ SHT_DYNSYM,
+ /* sh_entsize */ sizeof(struct Elf32_Sym),
+ /* sh_flags */ SHF_ALLOC
+ },
+
+ /* .fini */
+ {
+ /* name */ ESCN_FINI_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_EXECINSTR
+ },
+
+ /* .fini_array */
+ {
+ /* name */ ESCN_FINI_ARRAY_name,
+ /* sh_type */ SHT_FINI_ARRAY,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_WRITE
+ },
+
+ /* .got */
+ {
+ /* name */ ESCN_GOT_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ 0
+ },
+
+ /* .hash */
+ {
+ /* name */ ESCN_HASH_name,
+ /* sh_type */ SHT_HASH,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC
+ },
+
+ /* .init */
+ {
+ /* name */ ESCN_INIT_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_EXECINSTR
+ },
+
+ /* .init_array */
+ {
+ /* name */ ESCN_INIT_ARRAY_name,
+ /* sh_type */ SHT_INIT_ARRAY,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_WRITE
+ },
+
+ /* .interp */
+ {
+ /* name */ ESCN_INTERP_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ 0
+ },
+
+ /* .line */
+ {
+ /* name */ ESCN_LINE_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ 0
+ },
+
+ /* .note */
+ {
+ /* name */ ESCN_NOTE_name,
+ /* sh_type */ SHT_NOTE,
+ /* sh_entsize */ 0,
+ /* sh_flags */ 0
+ },
+
+ /* .plt */
+ {
+ /* name */ ESCN_PLT_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ 0
+ },
+
+ /* .preinit_array */
+ {
+ /* name */ ESCN_PREINIT_ARRAY_name,
+ /* sh_type */ SHT_PREINIT_ARRAY,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_WRITE
+ },
+
+ /* .rel */
+ {
+ /* name */ ESCN_REL_name,
+ /* sh_type */ SHT_REL,
+ /* sh_entsize */ sizeof(struct Elf32_Rel),
+ /* sh_flags */ 0
+ },
+
+ /* .rela */
+ {
+ /* name */ ESCN_RELA_name,
+ /* sh_type */ SHT_RELA,
+ /* sh_entsize */ sizeof(struct Elf32_Rela),
+ /* sh_flags */ 0
+ },
+
+ /* .rodata */
+ {
+ /* name */ ESCN_RODATA_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC
+ },
+
+ /* .rodata1 */
+ {
+ /* name */ ESCN_RODATA1_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC
+ },
+
+ /* .shstrtab */
+ {
+ /* name */ ESCN_SHSTRTAB_name,
+ /* sh_type */ SHT_STRTAB,
+ /* sh_entsize */ sizeof(char),
+ /* sh_flags */ SHF_STRINGS
+ },
+
+ /* .strtab */
+ {
+ /* name */ ESCN_STRTAB_name,
+ /* sh_type */ SHT_STRTAB,
+ /* sh_entsize */ sizeof(char),
+ /* sh_flags */ SHF_STRINGS
+ },
+
+ /* .symtab */
+ {
+ /* name */ ESCN_SYMTAB_name,
+ /* sh_type */ SHT_SYMTAB,
+ /* sh_entsize */ sizeof(struct Elf32_Sym),
+ /* sh_flags */ 0
+ },
+
+ /* .symtab_shndx */
+ {
+ /* name */ ESCN_SYMTAB_SHNDX_name,
+ /* sh_type */ SHT_SYMTAB_SHNDX,
+ /* sh_entsize */ sizeof(Elf32_Word),
+ /* sh_flags */ 0
+ },
+
+ /* .tbss */
+ {
+ /* name */ ESCN_TBSS_name,
+ /* sh_type */ SHT_NOBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_WRITE + SHF_TLS
+ },
+
+ /* .tdata */
+ {
+ /* name */ ESCN_TDATA_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_WRITE + SHF_TLS
+ },
+
+ /* .tdata1 */
+ {
+ /* name */ ESCN_TDATA1_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_WRITE + SHF_TLS
+ },
+
+ /* .text */
+ {
+ /* name */ ESCN_TEXT_name,
+ /* sh_type */ SHT_PROGBITS,
+ /* sh_entsize */ 0,
+ /* sh_flags */ SHF_ALLOC + SHF_EXECINSTR
+ },
+#if 0
+ /* .build.attributes */
+ {
+ /* name */ ESCN_ATTRIBUTES_name,
+ /* sh_type */ SHT_ATTRIBUTES,
+ /* sh_entsize */ 0,
+ /* sh_flags */ 0
+ },
+#endif
+ /* Terminate array with a NULL name field */
+ {
+ /* name */ (const char*)0,
+ /* sh_type */ 0,
+ /* sh_entsize */ 0,
+ /* sh_flags */ 0
+ }
+};
+
diff --git a/src/core/dsp/ocl_load/DLOAD/elf32.h b/src/core/dsp/ocl_load/DLOAD/elf32.h
new file mode 100644
index 0000000..67358d6
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/elf32.h
@@ -0,0 +1,756 @@
+/*
+* elf32.h
+*
+* Basic Data Structures for 32-bit ELF Object Format Files
+*
+* The data structures in this file come primarily from this specification:
+*
+* Tool Interface Standard (TIS)
+* Executable and Linking Format (ELF) Specification
+* Version 1.2
+*
+* TIS Committee
+* May 1995
+*
+* Additions and enhancements from this specification are also included:
+*
+* System V Application Binary Interface
+* DRAFT 17
+* December 2003
+*
+* http://sco.com/developers/gabi/2003-12-17/contents.html
+*
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef ELF32_H
+#define ELF32_H
+
+#include <inttypes.h>
+
+/*---------------------------------------------------------------------------*/
+/* 32-Bit Data Types (Figure 1-2, page 1-2) */
+/*---------------------------------------------------------------------------*/
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+
+
+/*****************************************************************************/
+/* ELF Header */
+/* PP. 1-4 */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* ELF Identification Indexes (indexes into Elf32_Ehdr.e_ident[] below) */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ EI_MAG0 = 0, /* File identification */
+ EI_MAG1 = 1, /* File identification */
+ EI_MAG2 = 2, /* File identification */
+ EI_MAG3 = 3, /* File identification */
+ EI_CLASS = 4, /* File class */
+ EI_DATA = 5, /* Data encoding */
+ EI_VERSION = 6, /* File version */
+ EI_OSABI = 7, /* Operating system / ABI */
+ EI_ABIVERSION = 8, /* ABI version */
+ EI_PAD = 9, /* Start of padding bytes */
+ EI_NIDENT = 16 /* Size of Elf32_Ehdr.e_ident[] */
+};
+
+
+/*---------------------------------------------------------------------------*/
+/* ELF Header Data Structure */
+/*---------------------------------------------------------------------------*/
+struct Elf32_Ehdr
+{
+ uint8_t e_ident[EI_NIDENT]; /* ELF Magic Number */
+ Elf32_Half e_type; /* Object File Type */
+ Elf32_Half e_machine; /* Target Processor */
+ Elf32_Word e_version; /* Object File Version */
+ Elf32_Addr e_entry; /* Entry Point */
+ Elf32_Off e_phoff; /* Program Header Table Offset */
+ Elf32_Off e_shoff; /* Section Header Table Offset */
+ Elf32_Word e_flags; /* Processor-Specific Flags */
+ Elf32_Half e_ehsize; /* Size of ELF header */
+ Elf32_Half e_phentsize; /* Size of a Program Header */
+ Elf32_Half e_phnum; /* # Entries in Program Header Table */
+ Elf32_Half e_shentsize; /* Size of a Section Header */
+ Elf32_Half e_shnum; /* # Entries in Section Header Table */
+ Elf32_Half e_shstrndx; /* Section Name String Table Section */
+};
+
+
+/*---------------------------------------------------------------------------*/
+/* Object File Types (value of "e_type") */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ ET_NONE = 0, /* No file type */
+ ET_REL = 1, /* Relocatable file */
+ ET_EXEC = 2, /* Executable file */
+ ET_DYN = 3, /* Shared object file */
+ ET_CORE = 4, /* Core file */
+ ET_LOOS = 0xfe00, /* First OS-specific value */
+ ET_HIPS = 0xfeff, /* Last OS-specific value */
+ ET_LOPROC = 0xff00, /* First processor-specific value */
+ ET_HIPROC = 0xffff /* Last processor-specific value */
+};
+
+
+/*---------------------------------------------------------------------------*/
+/* Target Processors (value of "e_machine") */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ EM_NONE = 0, /* No machine */
+ EM_M32 = 1, /* AT&T WE 32100 */
+ EM_SPARC = 2, /* SPARC */
+ EM_386 = 3, /* Intel 80386 */
+ EM_68K = 4, /* Motorola 68000 */
+ EM_88K = 5, /* Motorola 88000 */
+ EM_860 = 7, /* Intel 80860 */
+ EM_MIPS = 8, /* MIPS I Architecture */
+ EM_S370 = 9, /* IBM System/370 Processor */
+ EM_MIPS_RS3_LE = 10, /* MIPS RS3000 Little-endian */
+ EM_PARISC = 15, /* Hewlett-Packard PA-RISC */
+ EM_VPP500 = 17, /* Fujitsu VPP500 */
+ EM_SPARC32PLUS = 18, /* Enhanced instruction set SPARC */
+ EM_960 = 19, /* Intel 80960 */
+ EM_PPC = 20, /* PowerPC */
+ EM_PPC64 = 21, /* 64-bit PowerPC */
+ EM_S390 = 22, /* IBM System/390 Processor */
+ EM_V800 = 36, /* NEC V800 */
+ EM_FR20 = 37, /* Fujitsu FR20 */
+ EM_RH32 = 38, /* TRW RH-32 */
+ EM_RCE = 39, /* Motorola RCE */
+ EM_ARM = 40, /* Advanced RISC Machines ARM */
+ EM_ALPHA = 41, /* Digital Alpha */
+ EM_SH = 42, /* Hitachi SH */
+ EM_SPARCV9 = 43, /* SPARC Version 9 */
+ EM_TRICORE = 44, /* Siemens TriCore embedded processor */
+ EM_ARC = 45, /* "Argonaut RISC Core, Argonaut Technologies Inc. */
+ EM_H8_300 = 46, /* Hitachi H8/300 */
+ EM_H8_300H = 47, /* Hitachi H8/300H */
+ EM_H8S = 48, /* Hitachi H8S */
+ EM_H8_500 = 49, /* Hitachi H8/500 */
+ EM_IA_64 = 50, /* Intel IA-64 processor architecture */
+ EM_MIPS_X = 51, /* Stanford MIPS-X */
+ EM_COLDFIRE = 52, /* Motorola ColdFire */
+ EM_68HC12 = 53, /* Motorola M68HC12 */
+ EM_MMA = 54, /* Fujitsu MMA Multimedia Accelerator */
+ EM_PCP = 55, /* Siemens PCP */
+ EM_NCPU = 56, /* Sony nCPU embedded RISC processor */
+ EM_NDR1 = 57, /* Denso NDR1 microprocessor */
+ EM_STARCORE = 58, /* Motorola Star*Core processor */
+ EM_ME16 = 59, /* Toyota ME16 processor */
+ EM_ST100 = 60, /* STMicroelectronics ST100 processor */
+ EM_TINYJ = 61, /* Advanced Logic Corp. TinyJ embedded processor f */
+ EM_X86_64 = 62, /* AMD x86-64 architecture */
+ EM_PDSP = 63, /* Sony DSP Processor */
+ EM_PDP10 = 64, /* Digital Equipment Corp. PDP-10 */
+ EM_PDP11 = 65, /* Digital Equipment Corp. PDP-11 */
+ EM_FX66 = 66, /* Siemens FX66 microcontroller */
+ EM_ST9PLUS = 67, /* STMicroelectronics ST9+ 8/16 bit microcontrolle */
+ EM_ST7 = 68, /* STMicroelectronics ST7 8-bit microcontroller */
+ EM_68HC16 = 69, /* Motorola MC68HC16 Microcontroller */
+ EM_68HC11 = 70, /* Motorola MC68HC11 Microcontroller */
+ EM_68HC08 = 71, /* Motorola MC68HC08 Microcontroller */
+ EM_68HC05 = 72, /* Motorola MC68HC05 Microcontroller */
+ EM_SVX = 73, /* Silicon Graphics SVx */
+ EM_ST19 = 74, /* STMicroelectronics ST19 8-bit microcontroller */
+ EM_VAX = 75, /* Digital VAX */
+ EM_CRIS = 76, /* Axis Communications 32-bit embedded processor */
+ EM_JAVELIN = 77, /* Infineon Technologies 32-bit embedded processor */
+ EM_FIREPATH = 78, /* Element 14 64-bit DSP Processor */
+ EM_ZSP = 79, /* LSI Logic 16-bit DSP Processor */
+ EM_MMIX = 80, /* Donald Knuth's educational 64-bit processor */
+ EM_HUANY = 81, /* Harvard University machine-independent object f */
+ EM_PRISM = 82, /* SiTera Prism */
+ EM_AVR = 83, /* Atmel AVR 8-bit microcontroller */
+ EM_FR30 = 84, /* Fujitsu FR30 */
+ EM_D10V = 85, /* Mitsubishi D10V */
+ EM_D30V = 86, /* Mitsubishi D30V */
+ EM_V850 = 87, /* NEC v850 */
+ EM_M32R = 88, /* Mitsubishi M32R */
+ EM_MN10300 = 89, /* Matsushita MN10300 */
+ EM_MN10200 = 90, /* Matsushita MN10200 */
+ EM_PJ = 91, /* picoJava */
+ EM_OPENRISC = 92, /* OpenRISC 32-bit embedded processor */
+ EM_ARC_A5 = 93, /* ARC Cores Tangent-A5 */
+ EM_XTENSA = 94, /* Tensilica Xtensa Architecture */
+ EM_VIDEOCORE = 95, /* Alphamosaic VideoCore processor */
+ EM_TMM_GPP = 96, /* Thompson Multimedia General Purpose Processor */
+ EM_NS32K = 97, /* National Semiconductor 32000 series */
+ EM_TPC = 98, /* Tenor Network TPC processor */
+ EM_SNP1K = 99, /* Trebia SNP 1000 processor */
+ EM_ST200 = 100, /* STMicroelectronics (www.st.com) ST200 microcont */
+ EM_IP2K = 101, /* Ubicom IP2xxx microcontroller family */
+ EM_MAX = 102, /* MAX Processor */
+ EM_CR = 103, /* National Semiconductor CompactRISC microprocess */
+ EM_F2MC16 = 104, /* Fujitsu F2MC16 */
+ EM_MSP430 = 105, /* Texas Instruments embedded microcontroller msp4 */
+ EM_BLACKFIN = 106, /* Analog Devices Blackfin (DSP) processor */
+ EM_SE_C33 = 107, /* S1C33 Family of Seiko Epson processors */
+ EM_SEP = 108, /* Sharp embedded microprocessor */
+ EM_ARCA = 109, /* Arca RISC Microprocessor */
+ EM_UNICORE = 110, /* Microprocessor series from PKU-Unity Ltd. and M */
+
+ /*------------------------------------------------------------------------*/
+ /* ELF Magic Numbers Reserved For Texas Instruments */
+ /* */
+ /* The magic numbers 140-159 were reserved through SCO to be included */
+ /* in the official ELF specification. Please see Don Darling */
+ /* regarding any changes or allocation of the numbers below. */
+ /* */
+ /* When we allocate a number for use, SCO needs to be notified so they */
+ /* can update the ELF specification accordingly. */
+ /*------------------------------------------------------------------------*/
+ EM_TI_C6000 = 140, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED02 = 141, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED03 = 142, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED04 = 143, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED05 = 144, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED06 = 145, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED07 = 146, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED08 = 147, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED09 = 148, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED10 = 149, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED11 = 150, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED12 = 151, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED13 = 152, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED14 = 153, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED15 = 154, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED16 = 155, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED17 = 156, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED18 = 157, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED19 = 158, /* Reserved for Texas Instruments; unused */
+ EM_TI_UNUSED20 = 159 /* Reserved for Texas Instruments; unused */
+};
+
+
+/*---------------------------------------------------------------------------*/
+/* Object File Version (value of "e_version") */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ EV_NONE = 0, /* Invalid version */
+ EV_CURRENT = 1 /* Current version */
+};
+
+
+/*****************************************************************************/
+/* ELF Identification */
+/* PP. 1-6 */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Identification Values for ELF Files */
+/*---------------------------------------------------------------------------*/
+
+/* EI_MAG0 to EI_MAG3 */
+enum
+{
+ ELFMAG0 = 0x7f, /* e_ident[EI_MAG0] */
+ ELFMAG1 = 'E', /* e_ident[EI_MAG1] */
+ ELFMAG2 = 'L', /* e_ident[EI_MAG2] */
+ ELFMAG3 = 'F' /* e_ident[EI_MAG3] */
+};
+
+/* EI_CLASS */
+enum
+{
+ ELFCLASSNONE = 0, /* Invalid class */
+ ELFCLASS32 = 1, /* 32-bit objects */
+ ELFCLASS64 = 2 /* 64-bit objects */
+};
+
+/* EI_DATA */
+enum
+{
+ ELFDATANONE = 0, /* Invalid data encoding */
+ ELFDATA2LSB = 1, /* Little-endian data */
+ ELFDATA2MSB = 2 /* Big-endian data */
+};
+
+/* EI_OSABI */
+enum
+{
+ ELFOSABI_NONE = 0, /* No extensions or unspecified */
+ ELFOSABI_HPUX = 1, /* Hewlett-Packard HP-UX */
+ ELFOSABI_NETBSD = 2, /* NetBSD */
+ ELFOSABI_LINUX = 3, /* Linux */
+ ELFOSABI_SOLARIS = 6, /* Sun Solaris */
+ ELFOSABI_AIX = 7, /* AIX */
+ ELFOSABI_IRIX = 8, /* IRIX */
+ ELFOSABI_FREEBSD = 9, /* FreeBSD */
+ ELFOSABI_TRU64 = 10, /* Compaq TRU64 UNIX */
+ ELFOSABI_MODESTO = 11, /* Novell Modesto */
+ ELFOSABI_OPENBSD = 12, /* Open BSD */
+ ELFOSABI_OPENVMS = 13, /* Open VMS */
+ ELFOSABI_NSK = 14, /* Hewlett-Packard Non-Stop Kernel */
+ ELFOSABI_AROS = 15 /* Amiga Research OS */
+};
+
+/*****************************************************************************/
+/* Program Header */
+/* PP. 2-2 */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Program Header Data Structure */
+/*---------------------------------------------------------------------------*/
+struct Elf32_Phdr
+{
+ Elf32_Word p_type; /* Segment type */
+ Elf32_Off p_offset; /* Segment file offset */
+ Elf32_Addr p_vaddr; /* Segment virtual address */
+ Elf32_Addr p_paddr; /* Segment physical address */
+ Elf32_Word p_filesz; /* Segment file image size */
+ Elf32_Word p_memsz; /* Segment memory image size */
+ Elf32_Word p_flags; /* Segment flags */
+ Elf32_Word p_align; /* Segment alignment */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Segment Types (value of "p_type") */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ PT_NULL = 0, /* Unused table entry */
+ PT_LOAD = 1, /* Loadable segment */
+ PT_DYNAMIC = 2, /* Dynamic linking information */
+ PT_INTERP = 3, /* Interpreter path string location */
+ PT_NOTE = 4, /* Location and size of auxiliary information */
+ PT_SHLIB = 5, /* Shared library information */
+ PT_PHDR = 6, /* Location and size of program header table */
+ PT_TLS = 7, /* Specifies the Thread-Local Storage template */
+ PT_LOOS = 0x60000000, /* First OS-specific value */
+ PT_HIOS = 0x6fffffff, /* Last OS-specific value */
+ PT_LOPROC = 0x70000000, /* First processor-specific value */
+ PT_HIPROC = 0x7fffffff /* Last processor-specific value */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Segment Permissions (value of "p_flags") */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ PF_X = 0x1, /* Execute */
+ PF_W = 0x2, /* Write */
+ PF_R = 0x4, /* Read */
+ PF_MASKOS = 0x0ff00000, /* OS-specific mask */
+ PF_MASKPROC = 0xf0000000 /* Processor-specific mask */
+};
+
+/*****************************************************************************/
+/* Sections */
+/* PP. 1-9 */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Section Header Data Structure */
+/*---------------------------------------------------------------------------*/
+struct Elf32_Shdr
+{
+ Elf32_Word sh_name; /* Section name (offset into string section) */
+ Elf32_Word sh_type; /* Section type */
+ Elf32_Word sh_flags; /* Section flags */
+ Elf32_Addr sh_addr; /* Address in memory image */
+ Elf32_Off sh_offset; /* File offset of section data */
+ Elf32_Word sh_size; /* Size of the section in bytes */
+ Elf32_Word sh_link; /* Link to the section header table */
+ Elf32_Word sh_info; /* Extra information depending on section type */
+ Elf32_Word sh_addralign; /* Address alignment constraints */
+ Elf32_Word sh_entsize; /* Size of fixed-size entries in section */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Special Section Indexes */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ SHN_UNDEF = 0, /* Referenced by undefined values */
+ SHN_LORESERVE = 0xff00, /* First reserved index */
+ SHN_LOPROC = 0xff00, /* First processor-specific index */
+ SHN_HIPROC = 0xff1f, /* Last processor-specific index */
+ SHN_LOOS = 0xff20, /* First OS-specific index */
+ SHN_HIOS = 0xff3f, /* Last OS-specific index */
+ SHN_ABS = 0xfff1, /* Referenced by absolute values */
+ SHN_COMMON = 0xfff2, /* Referenced by common values */
+ SHN_XINDEX = 0xffff, /* Indirect index reference (escape value) */
+ SHN_HIRESERVE = 0xffff /* Last reserved index */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Section Types (value of "sh_type") */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ SHT_NULL = 0, /* Inactive section */
+ SHT_PROGBITS = 1, /* Application-specific information */
+ SHT_SYMTAB = 2, /* Symbol table */
+ SHT_STRTAB = 3, /* String table */
+ SHT_RELA = 4, /* Relocation entries (explicit addends) */
+ SHT_HASH = 5, /* Symbol hash table */
+ SHT_DYNAMIC = 6, /* Dynamic linking information */
+ SHT_NOTE = 7, /* Miscellaneous information */
+ SHT_NOBITS = 8, /* Contains no data in file */
+ SHT_REL = 9, /* Relocation entries (no expl. addends) */
+ SHT_SHLIB = 10, /* Shared library */
+ SHT_DYNSYM = 11, /* Dynamic symbol table */
+ SHT_INIT_ARRAY = 14, /* Pointers to initialization functions */
+ SHT_FINI_ARRAY = 15, /* Pointers to termination functions */
+ SHT_PREINIT_ARRAY = 16, /* Pointers to pre-init functions */
+ SHT_GROUP = 17, /* Section group */
+ SHT_SYMTAB_SHNDX = 18, /* Section indexes for SHN_XINDEX refs. */
+ SHT_LOOS = 0x60000000, /* First OS-specific type */
+ SHT_HIOS = 0x6fffffff, /* Last OS-specific type */
+ SHT_LOPROC = 0x70000000, /* First processor-specific type */
+ SHT_HIPROC = 0x7fffffff, /* Last processor-specific type */
+ SHT_LOUSER = 0x80000000, /* First application-specific type */
+ SHT_HIUSER = 0xffffffff /* Last application-specific type */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Section Attribute Flags (value of "sh_flags") */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ SHF_WRITE = 0x1, /* Writable during process execution */
+ SHF_ALLOC = 0x2, /* Loaded into processor memory */
+ SHF_EXECINSTR = 0x4, /* Contains executable instructions */
+ SHF_MERGE = 0x10, /* Can be merged */
+ SHF_STRINGS = 0x20, /* Contains null-terminated strings */
+ SHF_INFO_LINK = 0x40, /* sh_info contains a section index */
+ SHF_LINK_ORDER = 0x80, /* Maintain section ordering */
+ SHF_OS_NONCONFORMING = 0x100, /* OS-specific processing required */
+ SHF_GROUP = 0x200, /* Member of a section group */
+ SHF_TLS = 0x400, /* Contains Thread-Local Storage */
+ SHF_MASKOS = 0x0ff00000, /* Mask of OS-specific flags */
+ SHF_MASKPROC = 0xf0000000 /* Mask for processor-specific flags */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Section Group Flags */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ GRP_COMDAT = 0x1, /* Common data; only one is kept by linker */
+ GRP_MASKOS = 0x0ff00000, /* Mask for OS-specific group flags */
+ GRP_MASKPROC = 0xf0000000 /* Mask for processor-specific group flags */
+};
+
+
+/*****************************************************************************/
+/* Symbol Table */
+/* PP. 1-18 */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Symbol Table Entry Data Structure */
+/*---------------------------------------------------------------------------*/
+struct Elf32_Sym
+{
+ Elf32_Word st_name; /* String table offset for symbol name */
+ Elf32_Addr st_value; /* Symbol value */
+ Elf32_Word st_size; /* Symbol size */
+ uint8_t st_info; /* Symbol type and binding */
+ uint8_t st_other; /* Symbol visibility */
+ Elf32_Half st_shndx; /* Symbol type / defining section */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Undefined Symbol Index */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ STN_UNDEF = 0 /* First symbol table entry is always undefined */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Symbol Binding and Type Utility Functions. */
+/*---------------------------------------------------------------------------*/
+static inline uint8_t ELF32_ST_BIND(uint8_t i) { return (i >> 4); }
+static inline uint8_t ELF32_ST_TYPE(uint8_t i) { return (i & 0xf); }
+static inline uint8_t ELF32_ST_INFO(uint8_t b, uint8_t t)
+ { return ((b << 4) + (t & 0xf)); }
+static inline uint8_t ELF32_ST_VISIBILITY(uint8_t o) { return (o & 0x3); }
+
+
+/*---------------------------------------------------------------------------*/
+/* Symbol Binding (value returned by ELF32_ST_BIND()) */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ STB_LOCAL = 0, /* Symbol does not have external linkage */
+ STB_GLOBAL = 1, /* Symbol has external linkage */
+ STB_WEAK = 2, /* Symbol has weak external linkage */
+ STB_LOOS = 10, /* First OS-specific binding */
+ STB_HIOS = 12, /* Last OS-specific binding */
+ STB_LOPROC = 13, /* First processor-specific binding */
+ STB_HIPROC = 15 /* Last processor-specific binding */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Symbol Types (value returned by ELF32_ST_TYPE()) */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ STT_NOTYPE = 0, /* Unspecified type */
+ STT_OBJECT = 1, /* Associated with a data object */
+ STT_FUNC = 2, /* Associated with executable code */
+ STT_SECTION = 3, /* Associated with a section */
+ STT_FILE = 4, /* Associated with a source file */
+ STT_COMMON = 5, /* Labels an uninitialized common block */
+ STT_TLS = 6, /* Specifies a thread-local storage entity */
+ STT_LOOS = 10, /* First OS-specific type */
+ STT_HIOS = 12, /* Last OS-specific type */
+ STT_LOPROC = 13, /* First processor-specific type */
+ STT_HIPROC = 15 /* Last processor-specific type */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Symbol Visibility (value returned by ELF32_ST_VISIBILITY()) */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ STV_DEFAULT = 0, /* Visibility specified by binding type */
+ STV_INTERNAL = 1, /* Like STV_HIDDEN, with processor-specific semantics */
+ STV_HIDDEN = 2, /* Not visible to other components */
+ STV_PROTECTED = 3 /* Visible in other components but not preemptable */
+};
+
+/*****************************************************************************/
+/* Relocation */
+/* PP. 1-22 */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Relocation Entries Data Structures */
+/*---------------------------------------------------------------------------*/
+struct Elf32_Rel
+{
+ Elf32_Addr r_offset; /* Offset of the relocatable value in the section */
+ Elf32_Word r_info; /* Symbol table index and relocation type */
+};
+
+struct Elf32_Rela
+{
+ Elf32_Addr r_offset; /* Offset of the relocatable value in the section */
+ Elf32_Word r_info; /* Symbol table index and relocation type */
+ Elf32_Sword r_addend; /* Constant addend used to compute new value */
+};
+
+/*---------------------------------------------------------------------------*/
+/* Relocation Symbol and Type Utility Functions. */
+/*---------------------------------------------------------------------------*/
+static inline uint32_t ELF32_R_SYM(uint32_t i) { return (i >> 8); }
+static inline uint8_t ELF32_R_TYPE(uint32_t i) { return (i & 0xFF); }
+static inline uint32_t ELF32_R_INFO(uint32_t s, uint8_t t)
+ { return ((s << 8) + t); }
+
+
+/*****************************************************************************/
+/* Dynamic Section */
+/* PP. 2-8 */
+/*****************************************************************************/
+struct Elf32_Dyn
+{
+ Elf32_Sword d_tag;
+ union
+ {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+};
+
+/* Name Value d_un Executable Shared Obj. */
+/* ---- ----- ---- ---------- ----------- */
+enum
+{
+ DT_NULL = 0, /* ignored mandatory mandatory */
+ DT_NEEDED = 1, /* d_val optional optional */
+ DT_PLTRELSZ = 2, /* d_val optional optional */
+ DT_PLTGOT = 3, /* d_ptr optional optional */
+ DT_HASH = 4, /* d_ptr mandatory mandatory */
+ DT_STRTAB = 5, /* d_ptr mandatory mandatory */
+ DT_SYMTAB = 6, /* d_ptr mandatory mandatory */
+ DT_RELA = 7, /* d_ptr mandatory optional */
+ DT_RELASZ = 8, /* d_val mandatory optional */
+ DT_RELAENT = 9, /* d_val mandatory optional */
+ DT_STRSZ = 10, /* d_val mandatory mandatory */
+ DT_SYMENT = 11, /* d_val mandatory mandatory */
+ DT_INIT = 12, /* d_ptr optional optional */
+ DT_FINI = 13, /* d_ptr optional optional */
+ DT_SONAME = 14, /* d_val ignored optional */
+ DT_RPATH = 15, /* d_val optional ignored */
+ DT_SYMBOLIC = 16, /* ignored ignored optional */
+ DT_REL = 17, /* d_ptr mandatory optional */
+ DT_RELSZ = 18, /* d_val mandatory optional */
+ DT_RELENT = 19, /* d_val mandatory optional */
+ DT_PLTREL = 20, /* d_val optional optional */
+ DT_DEBUG = 21, /* d_ptr optional ignored */
+ DT_TEXTREL = 22, /* ignored optional optional */
+ DT_JMPREL = 23, /* d_ptr optional optional */
+ DT_BIND_NOW = 24, /* ignored optional optional */
+ DT_INIT_ARRAY = 25, /* d_ptr optional optional */
+ DT_FINI_ARRAY = 26, /* d_ptr optional optional */
+ DT_INIT_ARRAYSZ = 27, /* d_val optional optional */
+ DT_FINI_ARRAYSZ = 28, /* d_val optional optional */
+ DT_RUNPATH = 29, /* d_val optional optional */
+ DT_FLAGS = 30, /* d_val optional optional */
+ DT_ENCODING = 32, /* unspecified unspecified unspecified */
+ DT_PREINIT_ARRAY = 32, /* d_ptr optional ignored */
+ DT_PREINIT_ARRAYSZ = 33, /* d_val optional ignored */
+ DT_LOOS = 0x60000000, /* unspecified unspecified unspecified */
+ DT_HIOS = 0x6ffff000, /* unspecified unspecified unspecified */
+ DT_LOPROC = 0x70000000, /* unspecified unspecified unspecified */
+ DT_HIPROC = 0x7fffffff /* unspecified unspecified unspecified */
+};
+
+
+/*---------------------------------------------------------------------------*/
+/* DT_FLAGS values. */
+/*---------------------------------------------------------------------------*/
+enum
+{
+ DF_ORIGIN = 0x01, /* loaded object may reference $ORIGIN subst. string */
+ DF_SYMBOLIC = 0x02, /* changes dynamic linker symbol resolution */
+ DF_TEXTREL = 0x04, /* do not allow relocation of non-writable segments */
+ DF_BIND_NOW = 0x08, /* don't use lazy binding */
+ DF_STATIC_TLS = 0x10, /* do not load this file dynamically */
+ DF_DIRECT_DEPENDENT = 0x20, /* limit global sym lookup to dependent list */
+ DF_WORLD = 0x40 /* Linux style global sym lookup, breadth-first */
+};
+
+
+/*---------------------------------------------------------------------------*/
+/* Dynamic Tag Database. */
+/*---------------------------------------------------------------------------*/
+
+/* Specifiers for which d_un union member to use */
+
+enum
+{
+ EDYN_UNTYPE_IGNORED,
+ EDYN_UNTYPE_VAL,
+ EDYN_UNTYPE_PTR,
+ EDYN_UNTYPE_UNSPECIFIED
+};
+
+
+/* Specifiers for executable/shared object file requirements */
+
+enum
+{
+ EDYN_TAGREQ_IGNORED,
+ EDYN_TAGREQ_MANDATORY,
+ EDYN_TAGREQ_OPTIONAL,
+ EDYN_TAGREQ_UNSPECIFIED
+};
+
+
+/* Data structure for one dynamic tag database entry */
+
+struct EDYN_TAG
+{
+ const char* d_tag_name; /* tag name string */
+ Elf32_Sword d_tag_value; /* DT_* tag value */
+ Elf32_Word d_untype; /* which d_un union member to use */
+ Elf32_Word d_exec_req; /* requirement for executable files */
+ Elf32_Word d_shared_req; /* requirement for shared object files */
+};
+
+extern const struct EDYN_TAG EDYN_TAG_DB[];
+
+/*****************************************************************************/
+/* Special Section Database */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Special Section Names */
+/*---------------------------------------------------------------------------*/
+#define ESCN_BSS_name ".bss"
+#define ESCN_COMMENT_name ".comment"
+#define ESCN_DATA1_name ".data1"
+#define ESCN_DATA_name ".data"
+#define ESCN_DEBUG_name ".debug"
+#define ESCN_DYNAMIC_name ".dynamic"
+#define ESCN_DYNSTR_name ".dynstr"
+#define ESCN_DYNSYM_name ".dynsym"
+#define ESCN_FINI_ARRAY_name ".fini_array"
+#define ESCN_FINI_name ".fini"
+#define ESCN_GOT_name ".got"
+#define ESCN_HASH_name ".hash"
+#define ESCN_INIT_ARRAY_name ".init_array"
+#define ESCN_INIT_name ".init"
+#define ESCN_INTERP_name ".interp"
+#define ESCN_LINE_name ".line"
+#define ESCN_NOTE_name ".note"
+#define ESCN_PLT_name ".plt"
+#define ESCN_PREINIT_ARRAY_name ".preinit_array"
+#define ESCN_RELA_name ".rela"
+#define ESCN_REL_name ".rel"
+#define ESCN_RODATA1_name ".rodata1"
+#define ESCN_RODATA_name ".rodata"
+#define ESCN_SHSTRTAB_name ".shstrtab"
+#define ESCN_STRTAB_name ".strtab"
+#define ESCN_SYMTAB_SHNDX_name ".symtab_shndx"
+#define ESCN_SYMTAB_name ".symtab"
+#define ESCN_TBSS_name ".tbss"
+#define ESCN_TDATA1_name ".tdata1"
+#define ESCN_TDATA_name ".tdata"
+#define ESCN_TEXT_name ".text"
+#define ESCN_ATTRIBUTES_name "__TI_build_attributes"
+#define ESCN_ICODE_name "__TI_ICODE"
+#define ESCN_XREF_name "__TI_XREF"
+
+/*---------------------------------------------------------------------------*/
+/* Special Section Information Data Structure. */
+/*---------------------------------------------------------------------------*/
+struct ESCN
+{
+ const char *name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_entsize;
+ Elf32_Word sh_flags;
+};
+
+extern const struct ESCN ESCN_DB[];
+
+#endif /* ELF32_H */
diff --git a/src/core/dsp/ocl_load/DLOAD/relocate.h b/src/core/dsp/ocl_load/DLOAD/relocate.h
new file mode 100644
index 0000000..ee21aa9
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/relocate.h
@@ -0,0 +1,64 @@
+/*
+* relocate.h
+*
+* Declare names and IDs of all C6x-specific relocation types supported
+* in the dynamic loader.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef RELOCATE_H
+#define RELOCATE_H
+
+#include <inttypes.h>
+#include "elf32.h"
+#include "dload.h"
+#include "dload_api.h"
+
+/*---------------------------------------------------------------------------*/
+/* Declare some globals that are used for internal debugging and profiling. */
+/*---------------------------------------------------------------------------*/
+#if LOADER_DEBUG || LOADER_PROFILE
+#include <time.h>
+extern int DLREL_relocations;
+extern time_t DLREL_total_reloc_time;
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+/* Landing point for core loader's relocation processor. */
+/*---------------------------------------------------------------------------*/
+void DLREL_relocate(DLOAD_HANDLE handle, LOADER_FILE_DESC *fd,
+ DLIMP_Dynamic_Module *dyn_module);
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD/symtab.h b/src/core/dsp/ocl_load/DLOAD/symtab.h
new file mode 100644
index 0000000..1f06584
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/symtab.h
@@ -0,0 +1,72 @@
+/*
+* symtab.h
+*
+* Specification of functions used by the core loader to create, maintain,
+* and destroy internal symbol tables.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef SYMTAB_H
+#define SYMTAB_H
+
+#include "ArrayList.h"
+#include "dload.h"
+
+/*****************************************************************************/
+/* This is the top-level application file handle. It should only be needed */
+/* under the Linux and DSBT models. */
+/*****************************************************************************/
+extern int32_t DLIMP_application_handle;
+
+/*---------------------------------------------------------------------------*/
+/* Core Loader Symbol Table Management Functions */
+/*---------------------------------------------------------------------------*/
+BOOL DLSYM_canonical_lookup(DLOAD_HANDLE handle,
+ int32_t sym_index,
+ DLIMP_Dynamic_Module *dyn_module,
+ Elf32_Addr *sym_value);
+
+BOOL DLSYM_global_lookup(DLOAD_HANDLE handle,
+ const char *sym_name,
+ DLIMP_Loaded_Module *pentry,
+ Elf32_Addr *sym_value);
+
+BOOL DLSYM_lookup_local_symtab(const char *sym_name,
+ struct Elf32_Sym *symtab,
+ Elf32_Word symnum,
+ Elf32_Addr *sym_value);
+
+void DLSYM_copy_globals(DLIMP_Dynamic_Module *dyn_module);
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD/util.h b/src/core/dsp/ocl_load/DLOAD/util.h
new file mode 100644
index 0000000..24c5b3f
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/util.h
@@ -0,0 +1,89 @@
+/*
+* util.h
+*
+* Definition of some useful string comparison routines (not
+* not provided on all platforms) and a few generic macros.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <ctype.h>
+
+#if !defined(__linux)
+
+/*****************************************************************************/
+/* STRCASECMP() - Case-insensitive strcmp. */
+/*****************************************************************************/
+static int strcasecmp(const char* s1, const char* s2)
+{
+ char c1, c2;
+ do { c1 = *s1++; c2 = *s2++; }
+ while (c1 && c2 && (tolower(c1) == tolower(c2)));
+
+ return tolower(c1) - tolower(c2);
+}
+
+/*****************************************************************************/
+/* STRNCASECMP() - Case-insensitive strncmp. */
+/*****************************************************************************/
+static int strncasecmp(const char* s1, const char* s2, size_t n)
+{
+ char c1, c2;
+
+ if (!n) return 0;
+
+ do { c1 = *s1++; c2 = *s2++; }
+ while (--n && c1 && c2 && (tolower(c1) == tolower(c2)));
+
+ return tolower(c1) - tolower(c2);
+}
+
+#endif
+
+/*****************************************************************************/
+/* Define MIN and MAX macros. */
+/*****************************************************************************/
+#define MIN(x,y) (((x) > (y)) ? (y) : (x))
+#define MAX(x,y) (((x) >= (y)) ? (x) : (y))
+
+/*****************************************************************************/
+/* C implementation of 'bool' type. */
+/*****************************************************************************/
+typedef int BOOL;
+#define TRUE 1
+#define FALSE 0
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD/version.h b/src/core/dsp/ocl_load/DLOAD/version.h
new file mode 100644
index 0000000..e36d1a9
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/version.h
@@ -0,0 +1,63 @@
+/*
+* version.h
+*
+* Dynamic Loader source version identifictaion.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef _VERSION_H_
+#define _VERSION_H_
+
+/*****************************************************************************/
+/* VERSION NUMBER COMPONENTS - ALWAYS INCREASING!! */
+/* Initial version ID is 1.0.0. Successive version ID's will be incremented */
+/* by automated processes during release port. */
+/*****************************************************************************/
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 0
+#define VERSION_PATCH 0
+
+/******************************************************************************/
+/* Macros used to convert version macros into strings. */
+/******************************************************************************/
+#define MKCSTR(_str) #_str
+#define MKMSTR(_str) MKCSTR(_str)
+
+/******************************************************************************/
+/* VERSION string construction macros. */
+/******************************************************************************/
+#define VERSTR MKMSTR(VERSION_MAJOR) "." MKMSTR(VERSION_MINOR) "." MKMSTR(VERSION_PATCH)
+#define VERSION "Texas Instruments Dynamic Loader API/Core v"VERSTR
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD/virtual_targets.h b/src/core/dsp/ocl_load/DLOAD/virtual_targets.h
new file mode 100644
index 0000000..1d44b4d
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD/virtual_targets.h
@@ -0,0 +1,90 @@
+/******************************************************************************
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated - http://www.ti.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments Incorporated nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+#include "dload.h"
+#include "elf32.h"
+
+#ifdef C60_TARGET
+#include "c60_dynamic.h"
+#include "c60_reloc.h"
+#endif
+
+#ifdef ARM_TARGET
+#include "arm_dynamic.h"
+#include "arm_reloc.h"
+#endif
+
+/*****************************************************************************/
+/* Define a virtual target class to give access to target specific functions */
+/*****************************************************************************/
+typedef struct vtarget
+{
+ int machine_id;
+
+ BOOL (*relocate_dynamic_tag_info)(DLIMP_Dynamic_Module *dyn_module, int i);
+ BOOL (*process_eiosabi)(DLIMP_Dynamic_Module* dyn_module);
+ BOOL (*process_dynamic_tag)(DLIMP_Dynamic_Module *dyn_module, int i);
+ void (*relocate)(DLOAD_HANDLE handle, LOADER_FILE_DESC *elf_file,
+ DLIMP_Dynamic_Module *dyn_module);
+
+} VIRTUAL_TARGET;
+
+
+
+/*****************************************************************************/
+/* Populate this for each target supported. */
+/*****************************************************************************/
+VIRTUAL_TARGET vt_arr[] = {
+
+#ifdef C60_TARGET
+ {
+ EM_TI_C6000,
+ DLDYN_c60_relocate_dynamic_tag_info,
+ DLDYN_c60_process_eiosabi,
+ DLDYN_c60_process_dynamic_tag,
+ DLREL_c60_relocate
+ },
+#endif
+#ifdef ARM_TARGET
+ {
+ EM_ARM,
+ DLDYN_arm_relocate_dynamic_tag_info,
+ DLDYN_arm_process_eiosabi,
+ DLDYN_arm_process_dynamic_tag,
+ DLREL_arm_relocate
+ },
+#endif
+ {
+ EM_NONE,
+ 0,
+ 0,
+ 0,
+ 0
+ }
+};
+
+
diff --git a/src/core/dsp/ocl_load/DLOAD_API/api_version_change.log b/src/core/dsp/ocl_load/DLOAD_API/api_version_change.log
new file mode 100644
index 0000000..689cfe6
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD_API/api_version_change.log
@@ -0,0 +1,33 @@
+
+ Dynamic Loader API and Loader Core - Version Number Change Log
+ ==============================================================
+
+ Version Number Description
+ --------------------------
+
+ The version number associated with the Dynamic Loader API and the Loader Core
+ sources has three components:
+
+ <major version>.<minor version>.<patch version>
+
+ major version - is incremented if there is a change to the API that creates a
+ compatibility discontinuity.
+
+ minor version - is incremented if functionality is added to the API without
+ causing a compatibility discontinuity.
+
+ patch version - is incremented if a defect has been repaired, a performance
+ enhancement has been added, or the source code has been
+ refactored in some way. There should not be a compatibility
+ discontinuity created by an increment to the patch version.
+
+ Version Number Change Log
+ -------------------------
+
+ 1.0.0 - 17 July 2009 - Initial release of dynamic loader API and loader
+ core sources.
+
+ 2.0.0 - 1 Feb 2013 - Add client handle to several DLIF functions.
+ - Add DLIF_exit() for loader abort.
+
+
diff --git a/src/core/dsp/ocl_load/DLOAD_API/dload_api.h b/src/core/dsp/ocl_load/DLOAD_API/dload_api.h
new file mode 100644
index 0000000..95de10f
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD_API/dload_api.h
@@ -0,0 +1,700 @@
+/*
+* dload_api.h
+*
+* Dynamic Loader API Specification
+* --------------------------------
+*
+* Client-side of API is assumed to be platform dependent, but object file
+* format independent.
+*
+* Core Loader side of API is assumed to be platform independent, but
+* object file format dependent and target dependent.
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef DLOAD_API_H
+#define DLOAD_API_H
+
+#include <inttypes.h>
+#include <stdio.h>
+#include "util.h"
+
+extern int debugging_on;
+
+/*****************************************************************************/
+/* Specification of Loader File Descriptor. If client side of the loader */
+/* supports virtual memory, this may need to be updated to facilitate the */
+/* use of mmap(). */
+/*****************************************************************************/
+typedef FILE LOADER_FILE_DESC;
+
+static const int LOADER_SEEK_SET = SEEK_SET;
+static const int LOADER_SEEK_CUR = SEEK_CUR;
+static const int LOADER_SEEK_END = SEEK_END;
+
+/*****************************************************************************/
+/* TARGET_ADDRESS - type suitable for storing target memory address values. */
+/*****************************************************************************/
+typedef uint32_t TARGET_ADDRESS;
+
+/*****************************************************************************/
+/* Define DLOAD Object Handle */
+/*****************************************************************************/
+typedef void * DLOAD_HANDLE;
+
+/*****************************************************************************/
+/* Core Loader Provided API Functions (Core Loader Entry Points) */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_version() */
+/* */
+/* Return a string constant representation for the version ID of the */
+/* dynamic loader's core loader source code. */
+/* */
+/*---------------------------------------------------------------------------*/
+#include "version.h"
+#define DLOAD_version() VERSION
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_create() */
+/* */
+/* Construct and initialize the dynamic loader core's handle. */
+/* */
+/*---------------------------------------------------------------------------*/
+DLOAD_HANDLE DLOAD_create(void * client_handle);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_destroy() */
+/* */
+/* Destroy and finalize the dynamic loader core's handle. */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLOAD_destroy(DLOAD_HANDLE handle);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_initialize() */
+/* */
+/* Construct and initialize data structures internal to the dynamic */
+/* loader core. */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLOAD_initialize(DLOAD_HANDLE handle);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_finalize() */
+/* */
+/* Destroy and finalize data structures internal to the dynamic */
+/* loader core. */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLOAD_finalize(DLOAD_HANDLE handle);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_load_symbols() */
+/* */
+/* Load externally visible symbols from the specified file so that they */
+/* can be linked against when another object file is subsequntly loaded. */
+/* External symbols will be made available for global symbol linkage. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_load_symbols(DLOAD_HANDLE handle, LOADER_FILE_DESC* fp);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_load() */
+/* */
+/* Dynamically load the specified file and return a file handle for the */
+/* loaded file. If the load fails, this function will return a value */
+/* zero (0). */
+/* */
+/* The core loader must have read access to the file pointed by fp. */
+/* */
+/*---------------------------------------------------------------------------*/
+int DLOAD_load(DLOAD_HANDLE handle, LOADER_FILE_DESC* fp);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_unload() */
+/* */
+/* Given a file handle ID, unload all object segments associated with */
+/* the identified file and any of its dependents that are not still in */
+/* use. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_unload(DLOAD_HANDLE handle, uint32_t pseudopid);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_get_entry_names_info() */
+/* */
+/* Given a file handle, return the number entry points that are */
+/* available in the specified file as well as the max name length. This */
+/* can then be used by the client to allocate the appropriate amount of */
+/* memory needed to call DLOAD_get_entry_names() */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_get_entry_names_info(DLOAD_HANDLE handle, uint32_t file_handle,
+ int32_t *entry_pt_cnt,
+ int32_t *entry_pt_max_name_len);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_get_entry_names() */
+/* */
+/* Given a file handle, build a list of entry point names that are */
+/* available in the specified file. This can be used when querying */
+/* the list of global functions available in a shared library. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_get_entry_names(DLOAD_HANDLE handle, uint32_t file_handle,
+ int32_t* entry_pt_cnt, char*** entry_pt_names);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_query_symbol() */
+/* */
+/* Query the value of a symbol that is defined by an object file that */
+/* has previously been loaded. Boolean return value will be false if */
+/* the symbol is not found. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_query_symbol(DLOAD_HANDLE handle, uint32_t file_handle,
+ const char *sym_name, TARGET_ADDRESS *sym_val);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_get_entry_point() */
+/* */
+/* Given a file handle, return the entry point target address associated */
+/* with that object file. The entry point address value is written to */
+/* *sym_val. The return value of the function indicates whether the */
+/* file with the specified handle was found or not. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_get_entry_point(DLOAD_HANDLE handle, uint32_t file_handle,
+ TARGET_ADDRESS *sym_val);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_load_arguments() */
+/* */
+/* Given a file handle, find the object file assicated with that handle */
+/* and copy the argc/argv information from the client into that object */
+/* file's .args section. The return value indicates whether the operation */
+/* was successful. If there are no loaded object files which match the */
+/* handle or if there is insufficient space in the .args section to hold */
+/* the specified argc/argv information, the function will return false. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_load_arguments(DLOAD_HANDLE handle, uint32_t file_handle,
+ int argc, char** argv);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_prepare_for_execution() */
+/* */
+/* Given a file handle, prepare for execution : */
+/* - Return entry point associated with that module in the *sym_val */
+/* output parameter. */
+/* - Write out the given arguments to the .args section contained in the */
+/* same module. */
+/* - As a test (for the Reference implementation) read the arguments */
+/* using the DLIF_read_arguments() function and set global argc,argv. */
+/* */
+/* The return value of the function indicates whether the file with the */
+/* specified handle was found or not. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_prepare_for_execution(DLOAD_HANDLE handle, uint32_t file_handle,
+ TARGET_ADDRESS *sym_val,
+ int argc, char** argv);
+
+
+/*****************************************************************************/
+/* Client Provided API Functions */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* File I/O */
+/* */
+/* The client side of the dynamic loader must provide basic file I/O */
+/* capabilities so that the core loader has random access into any */
+/* object file that it is asked to load. */
+/* */
+/* The client side of the dynamic loader must provide a definition of */
+/* the LOADER_FILE_DESC in dload_filedefs.h. This allows the core loader */
+/* to be independent of how the client accesses raw data in an object */
+/* file. */
+/* */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_fseek() */
+/* */
+/* Seek to a position in a file (accessed via 'stream') based on the */
+/* values for offset and origin. */
+/* */
+/*---------------------------------------------------------------------------*/
+int DLIF_fseek(LOADER_FILE_DESC *stream, int32_t offset, int origin);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_ftell() */
+/* */
+/* Return the current file position in the file identified in the */
+/* LOADER_FILE_DESC pointed to by 'stream'. */
+/* */
+/*---------------------------------------------------------------------------*/
+int32_t DLIF_ftell(LOADER_FILE_DESC *stream);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_fread() */
+/* */
+/* Read 'size' * 'nmemb' bytes of data from the file identified in the */
+/* LOADER_FILE_DESC object pointed to by 'stream', and write that data */
+/* into the memory accessed via 'ptr'. */
+/* */
+/*---------------------------------------------------------------------------*/
+size_t DLIF_fread(void *ptr, size_t size, size_t nmemb,
+ LOADER_FILE_DESC *stream);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_fclose() */
+/* */
+/* Close a file that was opened on behalf of the core loader. Ownership */
+/* of the file pointer in question belongs to the core loader, but the */
+/* client has exclusive access to the file system. */
+/* */
+/*---------------------------------------------------------------------------*/
+int DLIF_fclose(LOADER_FILE_DESC *fd);
+
+/*---------------------------------------------------------------------------*/
+/* Host Memory Management */
+/* */
+/* Allocate and free host memory as needed for the dynamic loader's */
+/* internal data structures. If the dynamic loader resides on the */
+/* target architecture, then this memory is allocated from a target */
+/* memory heap that must be managed separately from memory that is */
+/* allocated for a dynamically loaded object file. */
+/* */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_malloc() */
+/* */
+/* Allocate 'size' bytes of memory space that is usable as scratch space */
+/* (appropriate for the loader's internal data structures) by the dynamic */
+/* loader. */
+/* */
+/* If allocation fails, this function must not return. */
+/* */
+/*---------------------------------------------------------------------------*/
+void* DLIF_malloc(size_t size);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_free() */
+/* */
+/* Free memory space that was previously allocated by DLIF_malloc(). */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLIF_free(void* ptr);
+
+/*---------------------------------------------------------------------------*/
+/* Target Memory Allocator Interface */
+/* */
+/* The client side of the dynamic loader must create and maintain an */
+/* infrastructure to manage target memory. The client must keep track */
+/* of what target memory is associated with each object segment, */
+/* allocating target memory for newly loaded objects and release target */
+/* memory that is associated with objects that are being unloaded from */
+/* the target architecture. */
+/* */
+/* The two client-supplied functions, DLIF_allocate() and DLIF_release(), */
+/* are used by the core loader to interface into the client side's */
+/* target memory allocator infrastructure. */
+/* */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_SEGMENT_FLAGS - segment characteristics. */
+/*---------------------------------------------------------------------------*/
+typedef uint32_t DLOAD_SEGMENT_FLAGS;
+static const int DLOAD_SF_executable = 0x1; /* Memory must be executable */
+static const int DLOAD_SF_relocatable = 0x2; /* Segment must be relocatable */
+static const int DLOAD_SF_writable = 0x4; /* Memory must be writable */
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_MEMORY_SEGMENT - Define structure to represent placement and size */
+/* details of a segment to be loaded. */
+/*---------------------------------------------------------------------------*/
+struct DLOAD_MEMORY_SEGMENT
+{
+ uint32_t target_page; /* requested/returned memory page */
+ TARGET_ADDRESS target_address; /* requested/returned address */
+ uint32_t objsz_in_bytes; /* size of init'd part of segment */
+ uint32_t memsz_in_bytes; /* size of memory block for segment */
+// DLOAD_SEGMENT_FLAGS flags; /* allocation request flags */
+};
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_MEMORY_REQUEST - Define structure to represent a target memory */
+/* request made by the core loader on behalf of a segment that the */
+/* loader needs to relocate and write into target memory. */
+/*---------------------------------------------------------------------------*/
+struct DLOAD_MEMORY_REQUEST
+{
+ LOADER_FILE_DESC *fp; /* file being loaded */
+ struct DLOAD_MEMORY_SEGMENT *segment; /* obj for req/ret alloc */
+ void *host_address; /* ret hst ptr from DLIF_copy()*/
+ BOOL is_loaded; /* returned as true if segment */
+ /* is already in target memory */
+ uint32_t offset; /* file offset of segment's */
+ /* raw data */
+ uint32_t flip_endian; /* endianness of trg opp host */
+ DLOAD_SEGMENT_FLAGS flags; /* allocation request flags */
+ uint32_t align; /* align of trg memory block */
+};
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_initMem() */
+/* */
+/* Given an address and size, initialize the memory used to load the */
+/* dynamic segments. This should be called by the client before */
+/* beginning dynamic loading. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_initMem(void* client_handle, uint32_t dynMemAddr, uint32_t size);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_deinitMem() */
+/* */
+/* De-initialize the memory used to load the dynamic segments. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_deinitMem(void* client_handle);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_allocate() */
+/* */
+/* Given a DLOAD_MEMORY_REQUEST created by the core loader, allocate */
+/* target memory to fulfill the request using the target memory */
+/* management infrastrucutre on the client side of the dynamic loader. */
+/* The contents of the DLOAD_MEMORY_REQUEST will be updated per the */
+/* details of a successful allocation. The allocated page and address */
+/* can be found in the DLOAD_MEMORY_SEGMENT attached to the request. */
+/* The boolean return value reflects whether the allocation was */
+/* successful or not. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_allocate(void* client_handle, struct DLOAD_MEMORY_REQUEST *req);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_release() */
+/* */
+/* Given a DLOAD_MEMORY_SEGMENT description, free the target memory */
+/* associated with the segment using the target memory management */
+/* infrastructure on the client side of the dynamic loader. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_release(void* client_handle, struct DLOAD_MEMORY_SEGMENT* ptr);
+
+/*---------------------------------------------------------------------------*/
+/* Target Memory Access / Write Services */
+/* */
+/* The client side's target memory allocator infrastructure communicates */
+/* with the core loader through the DLOAD_MEMORY_REQUEST and */
+/* DLOAD_MEMORY_SEGMENT data structures defined above. To complete the */
+/* loading of an object segment, the segment may need to be relocated */
+/* before it is actually written to target memory in the space that was */
+/* allocated for it by DLIF_allocate(). */
+/* */
+/* The client side of the dynamic loader provides two functions to help */
+/* complete the process of loading an object segment, DLIF_copy() and */
+/* DLIF_write(). */
+/* */
+/* These functions help to make the core loader truly independent of */
+/* whether it is running on the host or target architecture and how the */
+/* client provides for reading/writing from/to target memory. */
+/* */
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/* DLIF_copy() */
+/* */
+/* Copy segment data from the object file described in the 'fp' and */
+/* 'offset' of the DLOAD_MEMORY_REQUEST into host accessible memory so */
+/* that it can relocated or otherwise manipulated by the core loader. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_copy(void* client_handle, struct DLOAD_MEMORY_REQUEST* req);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_write() */
+/* */
+/* Once the segment data described in the DLOAD_MEMORY_REQUEST is ready */
+/* (relocated, if needed), write the segment contents to the target */
+/* memory identified in the DLOAD_MEMORY_SEGMENT attached to the request. */
+/* */
+/* After the segment contents have been written to target memory, the */
+/* core loader should discard the DLOAD_MEMORY_REQUEST object, but retain */
+/* the DLOAD_MEMORY_SEGMENT object so that the target memory associated */
+/* with the segment can be releases when the segment is unloaded. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_write(void* client_handle, struct DLOAD_MEMORY_REQUEST* req);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_read() */
+/* */
+/* Given a host accessible buffer, read content of indicated target */
+/* memory address into the buffer. */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_read(void* client_handle,
+ void *ptr, size_t size, size_t nmemb, TARGET_ADDRESS src);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_memcpy() */
+/* */
+/* Given a host accessible buffer, copy content from specified buffer */
+/* into target memory. */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_memcpy(void* client_handle, void *to, void *from, size_t size);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_execute() */
+/* */
+/* Start execution on the target architecture from given 'exec_addr'. */
+/* If the dynamic loader is running on the target architecture, this can */
+/* be effected as a simple function call. */
+/* */
+/*---------------------------------------------------------------------------*/
+int32_t DLIF_execute(void* client_handle, TARGET_ADDRESS exec_addr);
+
+/*---------------------------------------------------------------------------*/
+/* Loading and Unloading of Dependent Files */
+/* */
+/* The dynamic loader core loader must coordinate loading and unloading */
+/* dependent object files with the client side of the dynamic loader. */
+/* This allows the client to keep its bookkeeping information up to date */
+/* with what is currently loaded on the target architecture. */
+/* */
+/* For instance, the client may need to interact with a file system or */
+/* registry. The client may also need to update debug information in */
+/* synch with the loading and unloading of shared objects. */
+/* */
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/* DLIF_load_dependent() */
+/* */
+/* Ask client to find and open a dependent file identified by the */
+/* 'so_name' parameter, then, if necessary, initiate a DLOAD_load() */
+/* call to actually load the shared object onto the target. A */
+/* successful load will return a file handle ID that the client can */
+/* associate with the newly loaded file. */
+/* */
+/*---------------------------------------------------------------------------*/
+int DLIF_load_dependent(void* client_handle, const char* so_name);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_unload_dependent() */
+/* */
+/* Ask client to unload a dependent file identified by the 'file_handle' */
+/* parameter. Initiate a call to DLOAD_unload() to actually free up */
+/* the target memory that was occupied by the object file. */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLIF_unload_dependent(void* client_handle, uint32_t file_handle);
+
+/*---------------------------------------------------------------------------*/
+/* Error/Warning Registration Functions */
+/* */
+/* The client will maintain an error/warning log. This will allow the */
+/* core loader to register errors and warnings in the load during a */
+/* given dynamic load. The client is required to check the log after */
+/* each load attempt to report any problems. */
+/* */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Loader Warning Types */
+/*---------------------------------------------------------------------------*/
+typedef enum {
+ DLWT_MISC = 0, /* Miscellaneous warning */
+ DLWT_FILE /* Warning missing/invalid file information */
+} LOADER_WARNING_TYPE;
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_warning() */
+/* */
+/* Log a warning message with the client's error/warning handling */
+/* infrastructure. */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLIF_warning(LOADER_WARNING_TYPE wtype, const char *fmt, ...);
+
+/*---------------------------------------------------------------------------*/
+/* Loader Error Types */
+/*---------------------------------------------------------------------------*/
+typedef enum {
+ DLET_MISC = 0, /* Miscellaneous error */
+ DLET_FILE, /* Error reading/processing file */
+ DLET_SYMBOL, /* Symbol resolution error */
+ DLET_RELOC, /* Relocation error */
+ DLET_MEMORY, /* Host memory allocation/free error */
+ DLET_TRGMEM, /* Target memory allocation/free error */
+ DLET_DEBUG /* Shared object or DLL debug error */
+} LOADER_ERROR_TYPE;
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_error() */
+/* */
+/* Log an error message with the client's error/warning handling */
+/* infrastructure. */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLIF_error(LOADER_ERROR_TYPE etype, const char *fmt, ...);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_exit() */
+/* */
+/* Abort the loader following a fatal error. */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLIF_exit(int code);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_trace() */
+/* */
+/* Log a message with the client's trace handling infrastructure. */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLIF_trace(const char *fmt, ...);
+
+/*---------------------------------------------------------------------------*/
+/* Dynamic Static Base Table (DSBT) Support Functions */
+/*---------------------------------------------------------------------------*/
+#define DSBT_INDEX_INVALID -1
+#define DSBT_DSBT_BASE_INVALID 0
+#define DSBT_STATIC_BASE_INVALID 0
+
+/*****************************************************************************/
+/* Core Loader Side of DSBT Support */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_get_dsbt_size() */
+/* */
+/* Query the size of the DSBT associated with a specified file. The */
+/* client will check the size of a module's DSBT before it writes a copy */
+/* of the master DSBT to the module's DSBT. If the module's DSBT is not */
+/* big enough, an error will be emitted and the load will fail. */
+/* */
+/*---------------------------------------------------------------------------*/
+uint32_t DLOAD_get_dsbt_size(DLOAD_HANDLE handle, int32_t file_handle);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_get_dsbt_base() */
+/* */
+/* Find DSBT address for specified file. The client will query for this */
+/* address after allocation and symbol relocation has been completed. */
+/* The client will write a copy of the master DSBT to the returned DSBT */
+/* address if the module's DSBT size is big enough. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_get_dsbt_base(DLOAD_HANDLE handle, int32_t file_handle,
+ TARGET_ADDRESS *dsbt_base);
+
+/*---------------------------------------------------------------------------*/
+/* DLOAD_get_static_base() */
+/* */
+/* Find static base for a specified file. The client will query for this */
+/* address after allocation and symbol relocation has been completed. */
+/* The client will use the returned static base value to fill the slot */
+/* in the master DSBT that is associated with this module. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLOAD_get_static_base(DLOAD_HANDLE handle, int32_t file_handle,
+ TARGET_ADDRESS *static_base);
+
+
+/*****************************************************************************/
+/* Client Side of DSBT Support */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_register_dsbt_index_request() */
+/* */
+/* Register a request for a DSBT index with the client. A module can */
+/* make a specific DSBT index request or it can allow the client to */
+/* assign a DSBT index on its behalf (requested_dsbt_index == -1). The */
+/* client implementation of this function must check that a specific DSBT */
+/* index request does not conflict with a previous specific DSBT index */
+/* request. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_register_dsbt_index_request(DLOAD_HANDLE handle,
+ const char *requestor_name,
+ int32_t requestor_file_handle,
+ int32_t requested_dsbt_index);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_assign_dsbt_indices() */
+/* */
+/* Bind each module that registered a request for a DSBT index to a */
+/* specific slot in the DSBT. Specific requests for DSBT indices will be */
+/* honored first. Any general requests that remain will be assigned to */
+/* the first available slot in the DSBT. */
+/* */
+/*---------------------------------------------------------------------------*/
+void DLIF_assign_dsbt_indices(void);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_get_dsbt_index() */
+/* */
+/* Given a module that uses the DSBT model, return the identity of the */
+/* DSBT slot that was assigned to it by the client. This function can */
+/* only be called after the client has assigned DSBT indices to all */
+/* loaded object modules that use the DSBT model. The implementation of */
+/* this function will check that a proper DSBT index has been assigned to */
+/* the specified module and an invalid index (-1) if there is a problem. */
+/* */
+/*---------------------------------------------------------------------------*/
+int32_t DLIF_get_dsbt_index(int32_t file_handle);
+
+/*---------------------------------------------------------------------------*/
+/* DLIF_update_all_dsbts() */
+/* */
+/* Populate the client's model of the master DSBT with the static base */
+/* for each assigned slot in the DSBT, then write a copy of the master */
+/* DSBT to each module's DSBT location. The implementation of this */
+/* function must check the size of each module's DSBT to make sure that */
+/* it is large enough to hold a copy of the master DSBT. The function */
+/* will return FALSE if there is a problem. */
+/* */
+/*---------------------------------------------------------------------------*/
+BOOL DLIF_update_all_dsbts(void);
+
+#endif
diff --git a/src/core/dsp/ocl_load/DLOAD_SYM/symtab.c b/src/core/dsp/ocl_load/DLOAD_SYM/symtab.c
new file mode 100644
index 0000000..fbcdbeb
--- /dev/null
+++ b/src/core/dsp/ocl_load/DLOAD_SYM/symtab.c
@@ -0,0 +1,417 @@
+/*
+* symtab.c
+*
+* Symbol table creation, maintenance, and management. This module also
+* contains implementations of local and global symbol table lookup
+* algorithms, as appropriate for the platform that we are running on
+* (assumed to be DSP Bridge or Linux model, indicated by
+* direct_dependent_only flag in a given Module).
+*
+* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#include "elf32.h"
+#include "ArrayList.h"
+
+/*---------------------------------------------------------------------------*/
+/* Set up a Queue of Int32 type data objects. */
+/*---------------------------------------------------------------------------*/
+#include "Queue.h"
+TYPE_QUEUE_DEFINITION(int32_t, Int32)
+TYPE_QUEUE_IMPLEMENTATION(int32_t, Int32)
+
+#include "symtab.h"
+#include "dload_api.h"
+#include <string.h>
+
+/*---------------------------------------------------------------------------*/
+/* Holds the handle of the ET_EXEC-type mmodule loaded, if any. */
+/*---------------------------------------------------------------------------*/
+int32_t DLIMP_application_handle = 0;
+
+/*---------------------------------------------------------------------------*/
+/* Function prototypes */
+/*---------------------------------------------------------------------------*/
+BOOL DLSYM_lookup_global_symtab(const char *sym_name, struct Elf32_Sym *symtab,
+ Elf32_Word symnum, Elf32_Addr *sym_value);
+
+/*****************************************************************************/
+/* DLSYM_COPY_GLOBALS() - Copy global symbols from the dynamic module's */
+/* symbol table to the loader's global symbol table. */
+/*****************************************************************************/
+void DLSYM_copy_globals(DLIMP_Dynamic_Module *dyn_module)
+{
+ Elf32_Word i, global_index, global_symnum;
+ DLIMP_Loaded_Module *module = dyn_module->loaded_module;
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("DLSYM_copy_globals:\n");
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* The dynamic symbol table is sorted so that the local symbols come */
+ /* before the global symbols. gsymtab_offset points to the address where */
+ /* the first global symbol starts. Only the global symbols need to be */
+ /* copied into the persistent info. */
+ /*------------------------------------------------------------------------*/
+ global_index = dyn_module->gsymtab_offset / sizeof(struct Elf32_Sym);
+ global_symnum = dyn_module->symnum - global_index;
+
+ /*------------------------------------------------------------------------*/
+ /* Create space for the new global symbol table. */
+ /*------------------------------------------------------------------------*/
+ if (module->gsymtab)
+ {
+ DLIF_free(module->gsymtab);
+ module->gsymtab = NULL;
+ }
+
+ if (global_symnum > 0)
+ {
+ module->gsymtab = DLIF_malloc(sizeof(struct Elf32_Sym) * global_symnum);
+
+ memcpy(module->gsymtab,
+ &dyn_module->symtab[global_index],
+ sizeof(struct Elf32_Sym) * global_symnum);
+ }
+ module->gsymnum = global_symnum;
+
+ /*------------------------------------------------------------------------*/
+ /* Copy the string table part that contains the global symbol names. */
+ /*------------------------------------------------------------------------*/
+ if (module->gstrtab)
+ {
+ DLIF_free(module->gstrtab);
+ module->gstrtab = NULL;
+ }
+
+ module->gstrsz = dyn_module->strsz - dyn_module->gstrtab_offset;
+ if (module->gstrsz)
+ {
+ module->gstrtab = DLIF_malloc(module->gstrsz);
+
+ memcpy(module->gstrtab,
+ dyn_module->strtab + dyn_module->gstrtab_offset,
+ module->gstrsz);
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* Update the symbol names of the global symbol entries to point to */
+ /* the symbol names in the string table. */
+ /* NOTE: Note that we don't set the offset into the string table. We */
+ /* instead set the full address so that the st_name field can be accessed */
+ /* as char *. */
+ /*------------------------------------------------------------------------*/
+ for (i = 0; i < global_symnum; i++)
+ {
+
+ Elf32_Word old_offset = dyn_module->symtab[i + global_index].st_name -
+ (Elf32_Addr) dyn_module->strtab;
+ Elf32_Word new_offset = old_offset - dyn_module->gstrtab_offset;
+ struct Elf32_Sym *sym = &((struct Elf32_Sym*)(module->gsymtab))[i];
+ sym->st_name = new_offset + (Elf32_Addr)module->gstrtab;
+
+#if LOADER_DEBUG
+ if (debugging_on) DLIF_trace("Copying symbol: %s\n",
+ (char*)dyn_module->symtab[i + global_index].st_name);
+#endif
+ }
+}
+
+/*****************************************************************************/
+/* BREADTH_FIRST_LOOKUP() - Perform a breadth-first search of the Module */
+/* dependency graph to find specified symbol name (sym_name). */
+/*****************************************************************************/
+static BOOL breadth_first_lookup(DLOAD_HANDLE phandle,
+ const char* sym_name,
+ int handle,
+ Elf32_Addr *sym_value)
+{
+ /*------------------------------------------------------------------------*/
+ /* We start this function by putting the specified file handle on the */
+ /* file_handle_queue. */
+ /*------------------------------------------------------------------------*/
+ LOADER_OBJECT *dHandle = (LOADER_OBJECT *)phandle;
+ Int32_Queue file_handle_queue = TYPE_QUEUE_INITIALIZER;
+ Int32_enqueue(&file_handle_queue, handle);
+
+ /*------------------------------------------------------------------------*/
+ /* While the queue is not empty, keep looking for the symbol. */
+ /*------------------------------------------------------------------------*/
+ while(file_handle_queue.size)
+ {
+ int i;
+
+ /*---------------------------------------------------------------------*/
+ /* Set up a pointer to front of the list of loaded files so that we */
+ /* can be sure that dependent files will be searched in load order. */
+ /*---------------------------------------------------------------------*/
+ loaded_module_ptr_Queue_Node* mod_node =
+ dHandle->DLIMP_loaded_objects.front_ptr;
+ int* dependencies = (int*)(mod_node->value->dependencies.buf);
+
+ /*---------------------------------------------------------------------*/
+ /* Pluck off the file handle at the front of the file_handle_queue. */
+ /* We will search this file next. */
+ /*---------------------------------------------------------------------*/
+ handle = Int32_dequeue(&file_handle_queue);
+
+ /*---------------------------------------------------------------------*/
+ /* Locate the Module associated with the current file handle. */
+ /*---------------------------------------------------------------------*/
+ while (mod_node->value->file_handle != handle) mod_node++;
+
+ /*---------------------------------------------------------------------*/
+ /* Search the symbol table of the current file handle's Module. */
+ /* If the symbol was found, then we're finished. */
+ /*---------------------------------------------------------------------*/
+ if (DLSYM_lookup_global_symtab(sym_name,
+ mod_node->value->gsymtab,
+ mod_node->value->gsymnum,
+ sym_value))
+ return TRUE;
+
+ /*---------------------------------------------------------------------*/
+ /* If our symbol was not in the current Module, then add this Module's */
+ /* dependents to the end of the file_handle_queue. */
+ /*---------------------------------------------------------------------*/
+ for (i = 0; i < mod_node->value->dependencies.size; i++)
+ Int32_enqueue(&file_handle_queue, dependencies[i]);
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* We didn't find our symbol; return FALSE. */
+ /*------------------------------------------------------------------------*/
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLSYM_global_lookup() - Search the global symbol table to find the */
+/* definition of the given symbol name. */
+/*****************************************************************************/
+BOOL DLSYM_global_lookup(DLOAD_HANDLE handle,
+ const char *sym_name,
+ DLIMP_Loaded_Module *loaded_module,
+ Elf32_Addr *sym_value)
+{
+ int i = 0;
+ loaded_module_ptr_Queue_Node* node;
+ LOADER_OBJECT *dHandle = (LOADER_OBJECT *)handle;
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("DLSYM_global_lookup: %s\n", sym_name);
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* We will choose a different lookup algorithm based on what kind of */
+ /* platform we are supporting. In the Braveheart case, the global symbol */
+ /* lookup algorithm searches the base image first, followed by the */
+ /* explicit children of the specified Module. */
+ /*------------------------------------------------------------------------*/
+ if (loaded_module->direct_dependent_only)
+ {
+ int* child_handle = (int*)(loaded_module->dependencies.buf);
+
+ /*---------------------------------------------------------------------*/
+ /* Spin through list of this Module's dependencies (anything on its */
+ /* DT_NEEDED list), searching through each dependent's symbol table */
+ /* to find the symbol we are after. */
+ /*---------------------------------------------------------------------*/
+ for (i = 0; i < loaded_module->dependencies.size; i++)
+ {
+ for (node = dHandle->DLIMP_loaded_objects.front_ptr;
+ node->value->file_handle != child_handle[i];
+ node=node->next_ptr);
+
+ /*------------------------------------------------------------------*/
+ /* Return true if we find the symbol. */
+ /*------------------------------------------------------------------*/
+ if (DLSYM_lookup_global_symtab(sym_name,
+ node->value->gsymtab,
+ node->value->gsymnum,
+ sym_value))
+ return TRUE;
+ }
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* In the LINUX model, we will use a breadth-first global symbol lookup */
+ /* algorithm. First, the application's global symbol table is searched, */
+ /* followed by its children, followed by their children, and so on. */
+ /* It is up to the client of this module to set the application handle. */
+ /*------------------------------------------------------------------------*/
+ else
+ {
+ if (breadth_first_lookup(handle, sym_name, DLIMP_application_handle,
+ sym_value))
+ return TRUE;
+ }
+
+ /*------------------------------------------------------------------------*/
+ /* If we got this far, then symbol was not found. */
+ /*------------------------------------------------------------------------*/
+ DLIF_error(DLET_SYMBOL, "Could not resolve symbol %s!\n", sym_name);
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLSYM_lookup_symtab() - Lookup the symbol name in the given symbol table. */
+/* Symbol must have specified binding. Return the */
+/* value in sym_value and return TRUE if the lookup */
+/* succeeds. */
+/*****************************************************************************/
+static BOOL DLSYM_lookup_symtab(const char *sym_name, struct Elf32_Sym *symtab,
+ Elf32_Word symnum, Elf32_Addr *sym_value,
+ BOOL require_local_binding)
+{
+ Elf32_Addr sym_idx;
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("DLSYM_lookup_symtab, sym to find : %s\n", sym_name);
+#endif
+
+ for (sym_idx = 0; sym_idx < symnum; sym_idx++)
+ {
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("\tPotential symbol match : %s\n",
+ (char*)symtab[sym_idx].st_name);
+#endif
+
+ if ((symtab[sym_idx].st_shndx != SHN_UNDEF) && ((require_local_binding &&
+ (ELF32_ST_BIND(symtab[sym_idx].st_info) == STB_LOCAL)) ||
+ (!require_local_binding &&
+ (ELF32_ST_BIND(symtab[sym_idx].st_info) != STB_LOCAL))) &&
+ !strcmp(sym_name,(char*)(symtab[sym_idx].st_name)))
+ {
+ if (sym_value) *sym_value = symtab[sym_idx].st_value;
+ return TRUE;
+ }
+ }
+ if (sym_value) *sym_value = 0;
+ return FALSE;
+}
+
+/*****************************************************************************/
+/* DLSYM_lookup_global_symtab() - Lookup the symbol name in the given symbol */
+/* table. Symbol must have global binding. */
+/* Return the value in sym_value and return */
+/* TRUE if the lookup succeeds. */
+/*****************************************************************************/
+BOOL DLSYM_lookup_global_symtab(const char *sym_name, struct Elf32_Sym *symtab,
+ Elf32_Word symnum, Elf32_Addr *sym_value)
+{
+ return DLSYM_lookup_symtab(sym_name, symtab, symnum, sym_value, FALSE);
+}
+
+/*****************************************************************************/
+/* DLSYM_lookup_local_symtab() - Lookup the symbol name in the given symbol */
+/* table. Symbol must have local binding. */
+/* Return the value in sym_value and return */
+/* TRUE if the lookup succeeds. */
+/*****************************************************************************/
+BOOL DLSYM_lookup_local_symtab(const char *sym_name, struct Elf32_Sym *symtab,
+ Elf32_Word symnum, Elf32_Addr *sym_value)
+{
+ return DLSYM_lookup_symtab(sym_name, symtab, symnum, sym_value, TRUE);
+}
+
+/*****************************************************************************/
+/* CANONICAL_SYMBOL_LOOKUP() - Find the symbol definition. Look up the local */
+/* symbol table to find the symbol. If it is a */
+/* definition and cannot be pre-empted, return */
+/* it. Otherwise, do a look up in the global */
+/* symbol table that contains the symbol tables */
+/* from all the necessary modules. */
+/*****************************************************************************/
+BOOL DLSYM_canonical_lookup(DLOAD_HANDLE handle, int sym_index,
+ DLIMP_Dynamic_Module *dyn_module,
+ Elf32_Addr *sym_value)
+{
+ /*------------------------------------------------------------------------*/
+ /* Lookup the symbol table to get the symbol characteristics. */
+ /*------------------------------------------------------------------------*/
+ struct Elf32_Sym *sym = &dyn_module->symtab[sym_index];
+ int32_t st_bind = ELF32_ST_BIND(sym->st_info);
+ int32_t st_vis = ELF32_ST_VISIBILITY(sym->st_other);
+ BOOL is_def = (sym->st_shndx != SHN_UNDEF &&
+ (sym->st_shndx < SHN_LORESERVE ||
+ sym->st_shndx == SHN_ABS ||
+ sym->st_shndx == SHN_COMMON ||
+ sym->st_shndx == SHN_XINDEX));
+ const char *sym_name = (char *)sym->st_name;
+
+#if LOADER_DEBUG
+ if (debugging_on)
+ DLIF_trace("DLSYM_canonical_lookup: %d, %s\n", sym_index, sym_name);
+#endif
+
+ /*------------------------------------------------------------------------*/
+ /* Local symbols and symbol definitions that cannot be pre-empted */
+ /* are resolved by the definition in the same module. */
+ /*------------------------------------------------------------------------*/
+ if (st_bind == STB_LOCAL || st_vis != STV_DEFAULT)
+ {
+ /*---------------------------------------------------------------------*/
+ /* If it is a local symbol or non-local that cannot be preempted, */
+ /* the definition should be found in the same module. If we don't */
+ /* find the definition it is an error. */
+ /*---------------------------------------------------------------------*/
+ if (!is_def)
+ {
+ DLIF_error(DLET_SYMBOL,
+ "Local/non-imported symbol %s definition is not found "
+ "in module %s!\n", sym_name, dyn_module->name);
+ return FALSE;
+ }
+ else
+ {
+ if (sym_value) *sym_value = sym->st_value;
+ return TRUE;
+ }
+ }
+ /*------------------------------------------------------------------------*/
+ /* Else we have either pre-emptable defintion or undef symbol. We need */
+ /* to do global look up. */
+ /*------------------------------------------------------------------------*/
+ else
+ {
+ return DLSYM_global_lookup(handle, sym_name, dyn_module->loaded_module,
+ sym_value);
+ }
+}
+
diff --git a/src/core/dsp/ocl_load/README b/src/core/dsp/ocl_load/README
new file mode 100644
index 0000000..19165f6
--- /dev/null
+++ b/src/core/dsp/ocl_load/README
@@ -0,0 +1,8 @@
+
+This program is dependent on these Standard CVS modules
+
+C60_DLOAD_DYN:
+C60_DLOAD_REL:
+DLOAD:
+DLOAD_API:
+DLOAD_SYM:
diff --git a/src/core/dsp/ocl_load/Stack.h b/src/core/dsp/ocl_load/Stack.h
new file mode 100644
index 0000000..e958674
--- /dev/null
+++ b/src/core/dsp/ocl_load/Stack.h
@@ -0,0 +1,182 @@
+/******************************************************************************
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated - http://www.ti.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments Incorporated nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+/*
+* Stack.h
+*
+* Interface to Stack
+* ------------------
+*
+* This is an implementation of a type-independent stack implemented as
+* a signly linked list class for C. It's basically a template class, but
+* uses macros instead, so that it can be compiled with a C-only compiler.
+*
+* To define a Stack class:
+* #include "Stack.h"
+* TYPE_STACK_DEFINITION(object_type,Class_Identifier)
+*
+* In a separate C file:
+* #include "Stack.h"
+* TYPE_STACK_DEFINITION(object_type,Class_Identifier)
+* TYPE_STACK_IMPLEMENTATION(object_type,Class_Identifier)
+*
+* Now, to create a stack:
+* struct Class_Identifier_Stack name;
+* Get it initialized to zero everywhere somehow, maybe like this:
+* initialize_stack_Class_Identifier(&name);
+*
+* To add to the stack:
+* push_Class_Identifier(&name, object);
+*
+* To access the top of the stack:
+* Class_Identifier_Stack_Node *tos = name.top_ptr;
+* do_something_to_(tos->value);
+*
+* To delete from the stack:
+* if (name.size > 0) pop_Class_Identifier(&name);
+*
+* Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+*
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#ifndef STACK_H
+#define STACK_H
+
+#include <inttypes.h>
+#include "dload_api.h"
+
+/*****************************************************************************/
+/* TYPE_STACK_DEFINITION() - Define structure specifications for a last-in, */
+/* first-out linked list of t_name objects. */
+/*****************************************************************************/
+#define TYPE_STACK_DEFINITION(t, t_name) \
+struct t_name##_Stack_Node_ \
+{ \
+ t value; \
+ struct t_name##_Stack_Node_* next_ptr; \
+}; \
+typedef struct t_name##_Stack_Node_ t_name##_Stack_Node; \
+ \
+typedef struct \
+{ \
+ t_name##_Stack_Node* top_ptr; \
+ t_name##_Stack_Node* bottom_ptr; \
+ int size; \
+} t_name##_Stack; \
+ \
+extern void t_name##_initialize_stack(t_name##_Stack* stack); \
+extern void t_name##_push(t_name##_Stack* stack, t to_push); \
+extern t t_name##_pop(t_name##_Stack* stack);
+
+/*****************************************************************************/
+/* TYPE_STACK_DEFINITION() - Define the initializer to initalize Stacks. */
+/*****************************************************************************/
+#define TYPE_STACK_INITIALIZER {NULL, NULL, 0 }
+
+/*****************************************************************************/
+/* TYPE_STACK_IMPLEMENTATION() - Define member functions of new LIFO linked */
+/* list "class" of t_name objects. */
+/* */
+/* <type>_initialize_stack() - clears the stack */
+/* <type>_push() - pushes a <t> type object to the top of the stack */
+/* <type>_pop() - pop a <t> type object from the top of the stack */
+/* and provide access to it to the caller */
+/*****************************************************************************/
+#define TYPE_STACK_IMPLEMENTATION(t, t_name) \
+void t_name##_initialize_stack (t_name##_Stack* stack) \
+{ \
+ stack->top_ptr = stack->bottom_ptr = NULL; \
+ stack->size = 0; \
+} \
+void t_name##_push(t_name##_Stack* stack, t to_push) \
+{ \
+ stack->size++; \
+ \
+ if(!stack->top_ptr) \
+ { \
+ stack->bottom_ptr = stack->top_ptr = \
+ (t_name##_Stack_Node*)(DLIF_malloc(sizeof(t_name##_Stack_Node))); \
+ stack->top_ptr->next_ptr = NULL; \
+ } \
+ else \
+ { \
+ t_name##_Stack_Node* next_ptr = stack->top_ptr; \
+ stack->top_ptr = \
+ (t_name##_Stack_Node*)(DLIF_malloc(sizeof(t_name##_Stack_Node))); \
+ stack->top_ptr->next_ptr = next_ptr; \
+ } \
+ \
+ stack->top_ptr->value = to_push; \
+} \
+ \
+t t_name##_pop(t_name##_Stack* stack) \
+{ \
+ t to_ret; \
+ t_name##_Stack_Node* next_ptr = stack->top_ptr->next_ptr; \
+ \
+ stack->size--; \
+ to_ret = stack->top_ptr->value; \
+ DLIF_free((void*)(stack->top_ptr)); \
+ \
+ if(!stack->size) \
+ stack->top_ptr = stack->bottom_ptr = NULL; \
+ else \
+ stack->top_ptr = next_ptr; \
+ \
+ return to_ret; \
+}
+
+#endif
diff --git a/src/core/dsp/ocl_load/ocl_load.c b/src/core/dsp/ocl_load/ocl_load.c
new file mode 100644
index 0000000..c53a137
--- /dev/null
+++ b/src/core/dsp/ocl_load/ocl_load.c
@@ -0,0 +1,139 @@
+/******************************************************************************
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated - http://www.ti.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments Incorporated nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "dload_api.h"
+
+#define TYPE_STACK_DEFINITION(t, t_name)
+#define TYPE_STACK_IMPLEMENTATION(t, t_name)
+
+int debugging_on = FALSE;
+int profiling_on = FALSE;
+
+int global_argc;
+char **global_argv;
+
+int DLIF_fseek(LOADER_FILE_DESC *stream, int32_t offset, int origin)
+ { return fseek(stream, offset, origin); }
+
+
+size_t DLIF_fread(void *ptr, size_t size, size_t nmemb,
+ LOADER_FILE_DESC *stream)
+ { return fread(ptr, size, nmemb, stream); }
+
+int32_t DLIF_ftell (LOADER_FILE_DESC *stream) { return ftell(stream); }
+int32_t DLIF_fclose(LOADER_FILE_DESC *fd) { return fclose(fd); }
+void* DLIF_malloc(size_t size) { return malloc(size); }
+void DLIF_free (void* ptr) { free(ptr); }
+
+/*****************************************************************************/
+/* DLIF_COPY() - Copy data from file to host-accessible memory. */
+/* Returns a host pointer to the data in the host_address field of the */
+/* DLOAD_MEMORY_REQUEST object. */
+/*****************************************************************************/
+BOOL DLIF_copy(void* client_handle, struct DLOAD_MEMORY_REQUEST* targ_req)
+{
+ struct DLOAD_MEMORY_SEGMENT* obj_desc = targ_req->segment;
+ LOADER_FILE_DESC* f = targ_req->fp;
+ void *buf = calloc(obj_desc->memsz_in_bytes, 1);
+
+ fseek(f, targ_req->offset, SEEK_SET);
+
+ int result = 1;
+ if (obj_desc->objsz_in_bytes)
+ result = fread(buf, obj_desc->objsz_in_bytes, 1, f);
+
+ assert(result == 1);
+
+ targ_req->host_address = buf;
+
+ return 1;
+}
+
+BOOL DLIF_read(void* client_handle,
+ void *ptr, size_t size, size_t nmemb, TARGET_ADDRESS src)
+ { assert(0); }
+
+BOOL DLIF_memcpy(void* client_handle,
+ void *to, void *from, size_t size)
+ { return (!memcpy(to, from, size)) ? 0 : 1; }
+
+int32_t DLIF_execute(void* client_handle,
+ TARGET_ADDRESS exec_addr) { assert(0); return 1; }
+
+
+
+
+BOOL DLIF_register_dsbt_index_request(DLOAD_HANDLE handle,
+ const char *requestor_name,
+ int32_t requestor_file_handle,
+ int32_t requested_dsbt_index)
+ { assert(0); }
+
+void DLIF_assign_dsbt_indices(void) { assert(0); }
+
+int32_t DLIF_get_dsbt_index(int32_t file_handle)
+ { assert(0); return DSBT_INDEX_INVALID; }
+
+BOOL DLIF_update_all_dsbts() { assert(0); return TRUE; }
+
+void DLIF_warning(LOADER_WARNING_TYPE wtype, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap,fmt);
+ printf("<< D L O A D >> WARNING: ");
+ vprintf(fmt,ap);
+ va_end(ap);
+}
+
+void DLIF_error(LOADER_ERROR_TYPE etype, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap,fmt);
+ printf("<< D L O A D >> ERROR: ");
+ vprintf(fmt,ap);
+ va_end(ap);
+}
+
+void DLIF_trace(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap,fmt);
+ vprintf(fmt,ap);
+ va_end(ap);
+}
+
+void DLIF_exit(ecode)
+{
+ exit(ecode);
+}
+