changeset 2011:662e1b34b811

Added OBJLOADER package.
author nickg
date Thu, 07 Jul 2005 10:55:12 +0000
parents 2379473fdc8d
children fa05b44883a4
files packages/ChangeLog packages/ecos.db packages/services/objloader/current/ChangeLog packages/services/objloader/current/cdl/objloader.cdl packages/services/objloader/current/doc/notes.txt packages/services/objloader/current/include/elf.h packages/services/objloader/current/include/loader_fs.h packages/services/objloader/current/include/objelf.h packages/services/objloader/current/include/relocate_ppc.h packages/services/objloader/current/src/loader_fs.c packages/services/objloader/current/src/objelf.c packages/services/objloader/current/src/objloader.c packages/services/objloader/current/src/relocate_ppc.c packages/services/objloader/current/tests/library/hello.c packages/services/objloader/current/tests/test_mods.c
diffstat 15 files changed, 2801 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/packages/ChangeLog
+++ b/packages/ChangeLog
@@ -1,3 +1,7 @@
+2005-06-28  Nick Garnett  <nickg@ecoscentric.com>
+
+	* ecos.db: Added Object Loader package.
+
 2005-06-12   Brandl Harald <Harald.Brandl@fh-joanneum.at>
 
 	* ecos.db: Added a ethernet device driver for the NETARM.
--- a/packages/ecos.db
+++ b/packages/ecos.db
@@ -2136,6 +2136,14 @@ This package provides support for the dy
 library loader."
 }
 
+package CYGPKG_OBJLOADER {
+        alias           { "Object file loader" objloader }
+        directory       services/objloader
+        script          objloader.cdl
+        description "
+This package provides support for the object file loader and relocator."
+}
+
 package CYGPKG_COMPRESS_ZLIB {
         alias           { "Zlib compress/decompress" zlib_compress compress_zlib zlib }
         directory       services/compress/zlib
@@ -5956,3 +5964,4 @@ package CYGPKG_NET_LWIP {
 	description	"Lightweight TCP/IP stack: lwIP"
 }
 
+
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/ChangeLog
@@ -0,0 +1,48 @@
+2005-05-10  Anthony Tonizzo  <atonizzo@lycos.com>
+
+	* include/elf.h: 
+	* include/loader_fs.h: 
+	* include/objelf.h: 
+	* include/relocate_ppc.h: 
+	* src/loader_fs.c: 
+	* src/objelf.c: 
+	* src/objloader.c: 
+	* src/relocate_ppc.c: 
+	* doc/notes.txt: 
+	* cdl/objloader.cdl:
+	* tests/test_mods.c:
+	* tests/library/hello.c: 
+	Created OBJLDR package.
+	
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/cdl/objloader.cdl
@@ -0,0 +1,165 @@
+# ====================================================================
+#
+#      objloader.cdl
+#
+#      Object loader configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2005 eCosCentric Ltd.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License along
+## with eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      atonizzo (atonizzo@lycos.com)
+# Contributors:
+# Date:           2005-05-13
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_OBJLOADER {
+    display       "Object file loader"
+    description   "This package provides support for loading and relocating 
+                   object files within eCos."
+    include_dir   cyg/objloader
+    include_files elf.h objelf.h loader_fs.h relocate_ppc.h
+    compile       objloader.c objelf.c loader_fs.c
+    requires      CYGPKG_MEMALLOC
+    requires      CYGPKG_IO_FILEIO
+# ====================================================================
+
+    cdl_component CYGPKG_SERVICES_OBJLOADER_ARCHITECTURE {
+        display "Architecture dependent settings"
+        flavor  none
+        no_define
+        description   "Each of the options here enables the correct
+                       relocation support for the architectures supported."
+
+        cdl_option CYGBLD_OBJLOADER_ARCHITECTURE_POWERPC {
+           display       "Support loading on PowerPC processors"
+           calculated    CYGPKG_HAL_POWERPC
+           define_proc {
+               puts $::cdl_header "#include <cyg/objloader/relocate_ppc.h>"
+           }
+           compile relocate_ppc.c
+        }
+
+#        cdl_option CYGBLD_OBJLOADER_ARCHITECTURE_ARM {
+#            display       "Support loading on ARM processors"
+#            calculated    CYGPKG_HAL_ARM
+#            define_proc {
+#               puts $::cdl_header "#include <cyg/objloader/relocate_arm.h>"
+#            }
+#            compile relocate_arm.c
+#        }
+        
+    }
+ 
+    cdl_option CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL {
+        display          "Verbosity of debug output"
+        flavor           data
+        legal_values     0 1 2
+        default_value    0
+        description      "This option allows controls over the verbosity of
+                         the debug output. 1 is moderate, 2 is very
+                         verbose, including the symbol name of each relocation
+                         performed. Any value other than 0 will prevent the
+                         unloading of unused library data, thus increasing the
+                         heap memory requirements of the package."
+    }
+   
+    cdl_component CYGPKG_SERVICES_OBJLOADER_OPTIONS {
+        display "Object loader build options"
+        flavor  none
+        description   "
+	    Package specific build options including control over
+	    compiler flags used only in building this package,
+	    and details of which tests are built."
+
+
+        cdl_option CYGPKG_SERVICES_OBJLOADER_CFLAGS_ADD {
+            display "Additional compiler flags"
+            flavor  data
+            no_define
+            default_value { "" }
+            description   "
+                This option modifies the set of compiler flags for
+                building the serial device drivers. These flags are
+                used in addition to the set of global flags."
+        }
+
+        cdl_option CYGPKG_SERVICES_OBJLOADER_CFLAGS_REMOVE {
+            display "Suppressed compiler flags"
+            flavor  data
+            no_define
+            default_value { "" }
+            description   "
+                This option modifies the set of compiler flags for
+                building the serial device drivers. These flags are
+                removed from the set of global flags if present."
+        }
+    }
+
+    cdl_option CYGBLD_SERVICES_OBJLOADER_BUILD_TESTS {
+        display "Build test library"
+        default_value 0
+        no_define
+        description "
+            This option enables the building of a library and an
+            application for testing the loader. These
+            are not built by default since they do not use the dedicated
+            testing infrastructure."
+
+        make -priority 320 {
+            <PREFIX>/bin/test_mods : <PACKAGE>/tests/test_mods.c
+            @sh -c "mkdir -p tests $(dir $@)"
+            $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/test_mods.o $<
+            @echo $@ ": \\" > $(notdir $@).deps
+            @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+            @tail -n +2 deps.tmp >> $(notdir $@).deps
+            @echo >> $(notdir $@).deps
+            @rm deps.tmp
+            $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/test_mods.o
+        }
+
+        make -priority 320 {
+            <PREFIX>/bin/hello.o : <PACKAGE>/tests/library/hello.c
+            @sh -c "mkdir -p tests $(dir $@)"
+            $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(CFLAGS) -o $@ $<
+        }
+    }
+
+    
+}
+
+# ====================================================================
+# EOF objloader.cdl
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/doc/notes.txt
@@ -0,0 +1,156 @@
+These are very preliminary notes on the design and use of the object loader.
+Users should be aware that the package is still undergoing some changes.
+Feedback is appreciated.
+
+--------------------------------------------------------------------------------
+Creating libraries
+--------------------------------------------------------------------------------
+Libraries can be created by simply compiling the sources into .o files.
+The typical command line will look something like this:
+
+<toolchain>-gcc -c -I$(ECOS_DIRECTORY)/include -Wall hello.c
+
+The eCos "include" directory is needed to get the header files for the API.
+Multiple object files can be compiled into a single object with the
+
+<toolchain>-ld -r -o out.o file1.o file2.o file3.o
+
+It must be noted that the use of a linker to collect multiple object files
+into a single one considerably increases the size of the symbol table.
+
+--------------------------------------------------------------------------------
+Init/fini functions
+--------------------------------------------------------------------------------
+When the library is loaded the loader will look for a symbol with the name of 
+"library_open" and, if found, will call the symbol with a prototype of
+
+void library_open( void )
+
+When the cyg_ldr_close_library() function is called, the loader will also 
+look for a function called library close() and call it. The prototype is the 
+same as library_open().
+
+--------------------------------------------------------------------------------
+External references.
+--------------------------------------------------------------------------------
+External references are the calls that the library makes to the eCos. These
+calls are resolved by the loader if the function name is available in a table
+provided by the user which maps a function name with its pointer. The loader
+provides an empty table so that the user need only provide additional entry
+required by the relocator.
+
+In order to keep the size of the table to a minimum, the user can selectively 
+include only those functions that are expected to be used by the loader to 
+resolve all references.
+
+The following is an example of how to add an entry to the external references 
+table:
+
+CYG_LDR_TABLE_ENTRY( diag_printf_entry, "diag_printf", diag_printf );
+
+The first parameter is a unique identifier, the second is a string containing
+the name of the function, and the third is the pointer to the function itself.
+The entries can be added anywhere in the file.
+
+The objelf.h file contains a number of macros that collect groups of
+functions together as a convenient way to include blocks of
+functionality.
+
+
+--------------------------------------------------------------------------------
+Writing the relocator for a new architecture
+--------------------------------------------------------------------------------
+A relocator for a new architecture must provide a function with the following
+prototype:
+
+cyg_int32 
+cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value )
+
+The sym type is the type of relocation to apply. This value is architecture
+dependent and it is obtained from the r_info field of the relocation entry.
+The mem address is the memory location to relocate. The sym_value is the
+value to use for the relocation. The size of the write operation is dependent
+on the sym_type value.
+
+The relocate_xxx.h file must provide definitions for:
+
+1) the machine ELF type
+2) the endianness of the architecture
+           ELFDATA2MSB : Big endian
+           ELFDATA2LSB : Little endian
+3) The relocation type
+           Elf_Rela    : With addend
+           Elf_Rel     : Without addend
+
+An example of the definition for the PowerPC processor is the following:
+
+#define ELF_ARCH_MACHINE_TYPE         20              // PowerPC.
+#define ELF_ARCH_ENDIANNESS           ELFDATA2MSB     // Big Endian.
+#define ELF_ARCH_RELTYPE              Elf_Rela        // With addend.
+
+These definitions can be found in the relocate_ppc.h file.
+
+The user must also provide a way to flush the data and address caches. This
+is architecture dependent and usually the macros to do this are already part
+of the eCos HAL.
+
+--------------------------------------------------------------------------------
+CDL File
+--------------------------------------------------------------------------------
+
+The CDL file allows the selective compilation of the architecture dependent
+file. If a new architecture is added, the CDL file must be updated to
+include the architecture dependent files.
+
+--------------------------------------------------------------------------------
+Test program
+--------------------------------------------------------------------------------
+
+The 'tests' directory contains a simple/sample application that shows how to
+use the object loader. The application loads a couple of symbols and runs
+the functions pointed by those symbols. In particular, the second symbol is
+a function which, in the library, is declared with the CYGBLD_ATTRIB_WEAK. If
+the entry 
+
+CYG_LDR_TABLE_ENTRY( weak_function_entry, "weak_function", weak_function );
+
+is found in the application then the function in the application is called.
+Otherwise, the function in the library is.
+
+The source code for the library used for this example can be found under the 
+'library' directory.
+
+The library shows a number of concepts, including external references and WEAK 
+references. The ubiquitous "twothreads' application is also included, and run
+by the main application. Notice the initialization of the semaphore in the 
+library_open() call.
+
+The library can be compiled with the command
+
+<toolchain>-gcc -c -Wall -o hello.o hello.c
+
+and then be put into some file system and loaded. In the specific example 
+provided, the library was placed in the root directory of a FAT partition.
+JFFS2 is also an option.
+
+If the CDL option CYGBLD_SERVICES_OBJLOADER_BUILD_TESTS is enabled,
+then the test program and the library will be compiled automatically
+and placed in the install tree bin directory.
+
+--------------------------------------------------------------------------------
+Final musings
+--------------------------------------------------------------------------------
+
+The cyg_ldr_open_library() call can be modified so that the user can use a 
+library that is already in memory, or one that must be retrieved via ftp or
+tftp. In order to do this some functions must be added:
+
+- A function to open the file. In the simplest case of a file system, this
+   function would be a wrapper for fopen(). See loader_fs.c for a possible
+   implementation for a file system
+- Function to read, seek and close the library. 
+- In case you have a statically allocated memory pool, you might want to
+  define your own cyg_ldr_malloc() and cyg_ldr_free(). Currently they are
+  defined as weak bindings to wrappers of the malloc() and free() functions
+
+
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/include/elf.h
@@ -0,0 +1,234 @@
+#ifndef __ELF_H__
+#define __ELF_H__
+
+/* =================================================================
+ *
+ *      elf.f
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ *
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+typedef cyg_uint32     Elf32_Addr;
+typedef cyg_uint16     Elf32_Half;
+typedef cyg_uint32     Elf32_Off;
+typedef cyg_int32      Elf32_Sword;
+typedef cyg_uint32     Elf32_Word;
+
+#define EI_NIDENT      16
+typedef struct
+{
+    unsigned char e_ident[EI_NIDENT];
+    Elf32_Half e_type;
+    Elf32_Half e_machine;
+    Elf32_Word e_version;
+    Elf32_Addr e_entry;
+    Elf32_Off  e_phoff;
+    Elf32_Off  e_shoff;
+    Elf32_Word e_flags;
+    Elf32_Half e_ehsize;
+    Elf32_Half e_phentsize;
+    Elf32_Half e_phnum;
+    Elf32_Half e_shentsize;
+    Elf32_Half e_shnum;
+    Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+// The ELFCLASS* macros are the defined values of e_ident[EI_CLASS].
+#define ELFCLASSNONE      0   // Invalid class.
+#define ELFCLASS32        1   // 32-bit objects.
+#define ELFCLASS64        2   // 64-bit objects.
+
+// The ELFDATA* macros are the allowed values of e_ident[EI_DATA].
+#define ELFDATA2LSB     1 // Little Endian
+#define ELFDATA2MSB     2 // Big Endian.
+
+// The ET_* macros define the values of the e_type field of the ElfXX_Ehdr
+//   structure.
+#define ET_NONE         0 // No file type.
+#define ET_REL          1 // Relocatable file.
+#define ET_EXEC         2 // Executable file.
+#define ET_DYN          3 // Shared object file.
+#define ET_CORE         4 // Core file.
+#define ET_LOPROC       0xff00 // Processor-specific.
+
+// The ELFMAG* macros are the values of e_ident[EI_MAG0-4]
+#define ELFMAG0         0x7f      // magic number, byte 0 
+#define ELFMAG1         'E'       // magic number, byte 1 
+#define ELFMAG2         'L'       // magic number, byte 2 
+#define ELFMAG3         'F'       // magic number, byte 3 
+#define ELFMAG          "\177ELF" // magic string 
+#define SELFMAG         4         // magic string length 
+
+#define EI_MAG0         0
+#define EI_MAG1         1
+#define EI_MAG2         2
+#define EI_MAG3         3
+#define EI_CLASS        4
+#define EI_DATA         5 
+#define EI_VERSION      6
+#define EI_PAD          7 
+
+typedef struct 
+{
+    Elf32_Word sh_name; 		// section name.
+    Elf32_Word sh_type;         // SHT_...
+    Elf32_Word sh_flags;        // SHF_...
+    Elf32_Addr sh_addr;         // virtual address
+    Elf32_Off  sh_offset;       // file offset
+    Elf32_Word sh_size;         // section size
+    Elf32_Word sh_link;         // misc info 
+    Elf32_Word sh_info;         // misc info 
+    Elf32_Word sh_addralign;    // memory alignment
+    Elf32_Word sh_entsize;      // entry size if table.
+} Elf32_Shdr;
+
+// Symbols table entry.
+typedef struct
+{
+    Elf32_Word    st_name;                // Symbol name (string tbl index).
+    Elf32_Addr    st_value;               // Symbol value.
+    Elf32_Word    st_size;                // Symbol size.
+    unsigned char st_info;                // Symbol type and binding.
+    unsigned char st_other;               // Symbol visibility.
+    Elf32_Half    st_shndx;               // Section index.
+} Elf32_Sym;
+
+typedef struct 
+{
+    Elf32_Addr r_offset;
+    Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct
+{ 
+    Elf32_Addr  r_offset;
+    Elf32_Word  r_info;
+    Elf32_Sword r_addend;
+} Elf32_Rela;
+
+
+#define SHT_NULL        0
+#define SHT_PROGBITS    1
+#define SHT_SYMTAB      2
+#define SHT_STRTAB      3
+#define SHT_RELA        4
+#define SHT_HASH        5
+#define SHT_DYNAMIC     6
+#define SHT_NOTE        7
+#define SHT_NOBITS      8
+#define SHT_REL         9
+#define SHT_SHLIB      10
+#define SHT_DYNSYM     11
+
+#define SHN_UNDEF       0
+#define SHN_LORESERVE   0xff00
+#define SHN_LOPROC      0xff00
+#define SHN_HIPROC      0xff1f
+#define SHN_ABS         0xfff1
+#define SHN_COMMON      0xfff2
+#define SHN_HIRESERVE   0xffff
+
+#define STT_NOTYPE            0
+#define STT_OBJECT            1
+#define STT_FUNC              2
+#define STT_SECTION           3
+#define STT_FILE              4
+#define STT_LOPROC           13
+#define STT_HIPROC           15
+
+#define STB_LOCAL            0
+#define STB_GLOBAL           1
+#define STB_WEAK             2
+#define STB_LOPROC          13
+#define STB_HIPROC          15
+
+// The ELF_STRING_xxx macros are names of common sections
+#define ELF_STRING_bss          ".bss"
+#define ELF_STRING_hbss         ".hbss"
+#define ELF_STRING_sbss         ".sbss"
+#define ELF_STRING_tbss         ".tbss"
+#define ELF_STRING_data         ".data"
+#define ELF_STRING_hdata        ".hdata"
+#define ELF_STRING_sdata        ".sdata"
+#define ELF_STRING_sdata2       ".sdata2"
+#define ELF_STRING_fini         ".fini"
+#define ELF_STRING_init         ".init"
+#define ELF_STRING_interp       ".interp"
+#define ELF_STRING_rodata       ".rodata"
+#define ELF_STRING_text         ".text"
+#define ELF_STRING_comment      ".comment"
+#define ELF_STRING_dynamic      ".dynamic"
+#define ELF_STRING_dynstr       ".dynstr"
+#define ELF_STRING_dynsym       ".dynsym"
+#define ELF_STRING_dlt          ".dlt"
+#define ELF_STRING_note         ".note"
+#define ELF_STRING_opd          ".opd"
+#define ELF_STRING_plt          ".plt"
+#define ELF_STRING_bss_rela     ".rela.bss"
+#define ELF_STRING_hbss_rela    ".rela.hbss"
+#define ELF_STRING_data_rela    ".rela.data"
+#define ELF_STRING_dlt_rela     ".rela.dlt"
+#define ELF_STRING_plt_rela     ".rela.plt"
+#define ELF_STRING_sdata_rela   ".rela.sdata"
+#define ELF_STRING_strtab       ".strtab"
+#define ELF_STRING_symtab       ".symtab"
+#define ELF_STRING_hash         ".hash"
+#define ELF_STRING_shstrtab     ".shstrtab"
+#define ELF_STRING_shsymtab     ".shsymtab"
+#define ELF_STRING_rela         ".rela"
+#define ELF_STRING_rel          ".rel"
+
+#define ELF32_R_SYM(i)  ((i)>>8)
+#define ELF32_R_TYPE(i) ((unsigned char)(i))
+
+#define ELF32_ST_BIND(i)  ((i)>>4)
+#define ELF32_ST_TYPE(i)  ((i)&0x0F)
+
+
+#endif
+
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/include/loader_fs.h
@@ -0,0 +1,60 @@
+#ifndef __LOADER_FS_H__
+#define __LOADER_FS_H__
+
+/* =================================================================
+ *
+ *      loader_fs.c
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ *
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+size_t    cyg_ldr_fs_read( PELF_OBJECT, size_t, size_t, void* );
+cyg_int32 cyg_ldr_fs_seek( PELF_OBJECT, cyg_uint32 );
+cyg_int32 cyg_ldr_fs_close( PELF_OBJECT );
+
+#endif // __LOADER_FS_H__
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/include/objelf.h
@@ -0,0 +1,557 @@
+#ifndef __OBJELF_H__
+#define __OBJELF_H__
+
+/* =================================================================
+ *
+ *      objelf.h
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ * 
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Contributors: nickg@ecoscentric.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+//==============================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/objloader.h>
+
+//==============================================================================
+
+extern cyg_uint8 *cyg_ldr_last_error;
+
+//==============================================================================
+
+#define CYG_LDR_MODE_FILESYSTEM              0
+#define CYG_LDR_MODE_FTP                     1
+#define CYG_LDR_MODE_TFTP                    2
+#define CYG_LDR_MODE_MEMORY                  3
+#define CYG_LDR_MODE_HTTP                    4
+
+//==============================================================================
+
+typedef struct ELF_OBJECT
+{
+    CYG_ADDRWORD  ptr;
+    cyg_uint32    mode;
+
+    size_t    (*read)( struct ELF_OBJECT*, size_t, size_t, void* );
+    cyg_int32 (*seek)( struct ELF_OBJECT*, cyg_uint32 );
+    cyg_int32 (*close)( struct ELF_OBJECT* );
+
+    // This is the absolute address in memory where the library resides.
+    Elf32_Ehdr*   p_elfhdr;
+
+    // Start of the section header.
+    Elf32_Shdr*   p_sechdr;
+
+    cyg_int32     hdrndx_symtab;
+    cyg_int32     hdrndx_strtab;
+
+    cyg_uint32    **sections;
+
+} ELF_OBJECT, *PELF_OBJECT;
+
+
+//==============================================================================
+// Debug functions.
+
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL != 0
+#define ELFDEBUG(a) diag_printf(a)
+#else
+#define ELFDEBUG(a)
+#endif
+
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
+void       cyg_ldr_print_section_data( PELF_OBJECT );
+void       cyg_ldr_print_symbol_names( PELF_OBJECT );
+void       cyg_ldr_print_rel_names( PELF_OBJECT );
+#endif
+
+//==============================================================================
+// Internal functions
+
+cyg_int32 *cyg_ldr_load_elf_section( PELF_OBJECT, cyg_uint32 );
+void       cyg_ldr_delete_elf_section( PELF_OBJECT, cyg_uint32 );
+cyg_int32 *cyg_ldr_section_address( PELF_OBJECT, cyg_uint32 );
+void*      cyg_ldr_scan_file( PELF_OBJECT );
+cyg_int32  cyg_ldr_relocate_section( PELF_OBJECT, cyg_uint32 );
+void*      cyg_ldr_find_symbol( void*, cyg_uint8* );
+void*      cyg_ldr_symbol_address( PELF_OBJECT, cyg_uint32 );
+void*      cyg_ldr_external_address( PELF_OBJECT, cyg_uint32 );
+
+//==============================================================================
+// User interface.
+
+PELF_OBJECT cyg_ldr_open_library( CYG_ADDRWORD, cyg_int32 );
+void        cyg_ldr_close_library( void* );
+cyg_uint8*  cyg_ldr_error( void );
+void*       cyg_ldr_get_symbol( void*, char* );
+
+PELF_OBJECT cyg_ldr_open_library_fs( cyg_uint8* );
+void        cyg_ldr_close_library_fs( PELF_OBJECT );
+
+//==============================================================================
+
+void *cyg_ldr_malloc( size_t ) CYGBLD_ATTRIB_WEAK;
+void cyg_ldr_free( void * ) CYGBLD_ATTRIB_WEAK;
+
+//==============================================================================
+
+struct cyg_ldr_table_entry
+{
+    char   *symbol_name;
+    void   *handler;
+} CYG_HAL_TABLE_TYPE;
+
+typedef struct cyg_ldr_table_entry cyg_ldr_table_entry;
+
+#define CYG_LDR_TABLE_ENTRY( __name, __symbol_name, __handler )                \
+                cyg_ldr_table_entry __name CYG_HAL_TABLE_ENTRY( ldr_table ) =  \
+                                                 { __symbol_name, __handler } 
+
+//==============================================================================
+
+#define CYG_LDR_TABLE_KAPI_ALARM()                                             \
+CYG_LDR_TABLE_ENTRY( cyg_alarm_create_entry,                                   \
+                     "cyg_alarm_create", cyg_alarm_create );                   \
+CYG_LDR_TABLE_ENTRY( cyg_alarm_delete_entry,                                   \
+                     "cyg_alarm_delete", cyg_alarm_delete );                   \
+CYG_LDR_TABLE_ENTRY( cyg_alarm_initialize_entry,                               \
+                     "cyg_alarm_initialize", cyg_alarm_initialize );           \
+CYG_LDR_TABLE_ENTRY( cyg_alarm_get_times_entry,                                \
+                     "cyg_alarm_get_times", cyg_alarm_get_times );             \
+CYG_LDR_TABLE_ENTRY( cyg_alarm_enable_entry,                                   \
+                     "cyg_alarm_enable", cyg_alarm_enable );                   \
+CYG_LDR_TABLE_ENTRY( cyg_alarm_disable_entry,                                  \
+                     "cyg_alarm_disable", cyg_alarm_disable );
+
+#define CYG_LDR_TABLE_KAPI_CLOCK()                                             \
+CYG_LDR_TABLE_ENTRY( cyg_clock_create_entry,                                   \
+                     "cyg_clock_create", cyg_clock_create );                   \
+CYG_LDR_TABLE_ENTRY( cyg_clock_delete_entry,                                   \
+                     "cyg_clock_delete", cyg_clock_delete );                   \
+CYG_LDR_TABLE_ENTRY( cyg_clock_to_counter_entry,                               \
+                     "cyg_clock_to_counter", cyg_clock_to_counter );           \
+CYG_LDR_TABLE_ENTRY( cyg_clock_set_resolution_entry,                           \
+                     "cyg_clock_set_resolution", cyg_clock_set_resolution );   \
+CYG_LDR_TABLE_ENTRY( cyg_clock_get_resolution_entry,                           \
+                     "cyg_clock_get_resolution",cyg_clock_get_resolution );    \
+CYG_LDR_TABLE_ENTRY( cyg_real_time_clock_entry,                                \
+                     "cyg_real_time_clock", cyg_real_time_clock );             \
+CYG_LDR_TABLE_ENTRY( cyg_current_time_entry,                                   \
+                     "cyg_current_time", cyg_current_time );
+
+#define CYG_LDR_TABLE_KAPI_COND()                                              \
+CYG_LDR_TABLE_ENTRY( cyg_cond_init_entry,                                      \
+                     "cyg_cond_init", cyg_cond_init );                         \
+CYG_LDR_TABLE_ENTRY( cyg_cond_destroy_entry,                                   \
+                     "cyg_cond_destroy", cyg_cond_destroy );                   \
+CYG_LDR_TABLE_ENTRY( cyg_cond_wait_entry,                                      \
+                     "cyg_cond_wait", cyg_cond_wait );                         \
+CYG_LDR_TABLE_ENTRY( cyg_cond_signal_entry,                                    \
+                     "cyg_cond_signal", cyg_cond_signal );                     \
+CYG_LDR_TABLE_ENTRY( cyg_cond_broadcast_entry,                                 \
+                     "cyg_cond_broadcast", cyg_cond_broadcast );               \
+CYG_LDR_TABLE_ENTRY( cyg_cond_timed_wait_entry,                                \
+                     "cyg_cond_timed_wait", cyg_cond_timed_wait );
+
+#define CYG_LDR_TABLE_KAPI_COUNTER()                                           \
+CYG_LDR_TABLE_ENTRY( cyg_counter_create_entry,                                 \
+                     "cyg_counter_create", cyg_counter_create );               \
+CYG_LDR_TABLE_ENTRY( cyg_counter_delete_entry,                                 \
+                     "cyg_counter_delete", cyg_counter_delete );               \
+CYG_LDR_TABLE_ENTRY( cyg_counter_current_value_entry,                          \
+                     "cyg_counter_current_value", cyg_counter_current_value ); \
+CYG_LDR_TABLE_ENTRY( cyg_counter_set_value_entry,                              \
+                     "cyg_counter_set_value", cyg_counter_set_value );         \
+CYG_LDR_TABLE_ENTRY( cyg_counter_tick_entry,                                   \
+                     "cyg_counter_tick", cyg_counter_tick );                   \
+CYG_LDR_TABLE_ENTRY( cyg_counter_multi_tick_entry,                             \
+                     "cyg_counter_multi_tick", cyg_counter_multi_tick );
+
+#define CYG_LDR_TABLE_KAPI_EXCEPTIONS()                                        \
+CYG_LDR_TABLE_ENTRY( cyg_exception_set_handler_entry,                          \
+                     "cyg_exception_set_handler", cyg_exception_set_handler ); \
+CYG_LDR_TABLE_ENTRY( cyg_exception_clear_handler_entry,                        \
+                     "cyg_exception_clear_handler",                            \
+                     cyg_exception_clear_handler );                            \
+CYG_LDR_TABLE_ENTRY( cyg_exception_call_handler_entry,                         \
+                     "cyg_exception_call_handler",                             \
+                     cyg_exception_call_handler );
+
+#define CYG_LDR_TABLE_KAPI_FLAG()                                              \
+CYG_LDR_TABLE_ENTRY( cyg_flag_init_entry,                                      \
+                     "cyg_flag_init", cyg_flag_init );                         \
+CYG_LDR_TABLE_ENTRY( cyg_flag_destroy_entry,                                   \
+                     "cyg_flag_destroy", cyg_flag_destroy );                   \
+CYG_LDR_TABLE_ENTRY( cyg_flag_setbits_entry,                                   \
+                     "cyg_flag_setbits", cyg_flag_setbits );                   \
+CYG_LDR_TABLE_ENTRY( cyg_flag_maskbits_entry,                                  \
+                     "cyg_flag_maskbits", cyg_flag_maskbits );                 \
+CYG_LDR_TABLE_ENTRY( cyg_flag_wait_entry,                                      \
+                     "cyg_flag_wait", cyg_flag_wait );                         \
+CYG_LDR_TABLE_ENTRY( cyg_flag_timed_wait_entry,                                \
+                     "cyg_flag_timed_wait", cyg_flag_timed_wait );             \
+CYG_LDR_TABLE_ENTRY( cyg_flag_poll_entry,                                      \
+                     "cyg_flag_poll", cyg_flag_poll );                         \
+CYG_LDR_TABLE_ENTRY( cyg_flag_peek_entry,                                      \
+                     "cyg_flag_peek", cyg_flag_peek );                         \
+CYG_LDR_TABLE_ENTRY( cyg_flag_waiting_entry,                                   \
+                     "cyg_flag_waiting", cyg_flag_waiting );                   
+
+#define CYG_LDR_TABLE_KAPI_INTERRUPTS()                                        \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_create_entry,                               \
+                     "cyg_interrupt_create", cyg_interrupt_create );           \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_delete_entry,                               \
+                     "cyg_interrupt_delete", cyg_interrupt_delete );           \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_attach_entry,                               \
+                     "cyg_interrupt_attach", cyg_interrupt_attach );           \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_detach_entry,                               \
+                     "cyg_interrupt_detach", cyg_interrupt_detach );           \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_get_vsr_entry,                              \
+                     "cyg_interrupt_get_vsr", cyg_interrupt_get_vsr );         \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_set_vsr_entry,                              \
+                     "cyg_interrupt_set_vsr", cyg_interrupt_set_vsr );         \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_disable_entry,                              \
+                     "cyg_interrupt_disable", cyg_interrupt_disable );         \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_enable_entry,                               \
+                     "cyg_interrupt_enable", cyg_interrupt_enable );           \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_mask_entry,                                 \
+                     "cyg_interrupt_mask", cyg_interrupt_mask );               \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_mask_intunsafe_entry,                       \
+                     "cyg_interrupt_mask_intunsafe",                           \
+                     cyg_interrupt_mask_intunsafe );                           \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_unmask_entry,                               \
+                     "cyg_interrupt_unmask", cyg_interrupt_unmask );           \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_unmask_intunsafe_entry,                     \
+                     "cyg_interrupt_unmask_intunsafe",                         \
+                     cyg_interrupt_unmask_intunsafe );                         \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_acknowledge_entry,                          \
+                     "cyg_interrupt_acknowledge",                              \
+                     cyg_interrupt_acknowledge );                              \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_configure_entry,                            \
+                     "cyg_interrupt_configure", cyg_interrupt_configure );     \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_set_cpu_entry,                              \
+                     "cyg_interrupt_set_cpu", cyg_interrupt_set_cpu );         \
+CYG_LDR_TABLE_ENTRY( cyg_interrupt_get_cpu_entry,                              \
+                     "cyg_interrupt_get_cpu", cyg_interrupt_get_cpu );
+
+#define CYG_LDR_TABLE_KAPI_MBOX()                                              \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_create_entry,                                    \
+                     "cyg_mbox_create", cyg_mbox_create );                     \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_delete_entry,                                    \
+                     "cyg_mbox_delete", cyg_mbox_delete );                     \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_get_entry,                                       \
+                     "cyg_mbox_get", cyg_mbox_get );                           \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_timed_get_entry,                                 \
+                     "cyg_mbox_timed_get", cyg_mbox_timed_get );               \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_tryget_entry,                                    \
+                     "cyg_mbox_tryget", cyg_mbox_tryget );                     \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_peek_item_entry,                                 \
+                     "cyg_mbox_peek_item", cyg_mbox_peek_item );               \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_put_entry,                                       \
+                     "cyg_mbox_put", cyg_mbox_put );                           \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_timed_put_entry,                                 \
+                     "cyg_mbox_timed_put", cyg_mbox_timed_put );               \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_tryput_entry,                                    \
+                     "cyg_mbox_tryput", cyg_mbox_tryput );                     \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_peek_entry,                                      \
+                     "cyg_mbox_peek", cyg_mbox_peek );                         \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_waiting_to_get_entry,                            \
+                     "cyg_mbox_waiting_to_get_item",                           \
+                     cyg_mbox_waiting_to_get_item );                           \
+CYG_LDR_TABLE_ENTRY( cyg_mbox_waiting_to_put_entry,                            \
+                     "cyg_mbox_waiting_to_put_item",                           \
+                     cyg_mbox_waiting_to_put_item );
+
+#define CYG_LDR_TABLE_KAPI_MEMPOOL_FIX()                                       \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_fix_create_entry,                             \
+                     "cyg_mempool_fix_create", cyg_mempool_fix_create );       \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_fix_delete_entry,                             \
+                     "cyg_mempool_fix_delete", cyg_mempool_fix_delete );       \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_fix_alloc_entry,                              \
+                     "cyg_mempool_fix_alloc", cyg_mempool_fix_alloc );         \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_fix_timed_alloc_entry,                        \
+                     "cyg_mempool_fix_timed_alloc",                            \
+                     cyg_mempool_fix_timed_alloc );                            \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_fix_try_alloc_entry,                          \
+                     "cyg_mempool_fix_try_alloc",                              \
+                     cyg_mempool_fix_try_alloc );                              \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_fix_free_entry,                               \
+                     "cyg_mempool_fix_free", cyg_mempool_fix_free );           \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_fix_waiting_entry,                            \
+                     "cyg_mempool_fix_waiting", cyg_mempool_fix_waiting );     \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_fix_get_info_entry,                           \
+                     "cyg_mempool_fix_get_info", cyg_mempool_fix_get_info );
+
+#define CYG_LDR_TABLE_KAPI_MEMPOOL_VAR()                                       \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_var_create_entry,                             \
+                     "cyg_mempool_var_create", cyg_mempool_var_create );       \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_var_delete_entry,                             \
+                     "cyg_mempool_var_delete", cyg_mempool_var_delete );       \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_var_alloc_entry,                              \
+                     "cyg_mempool_var_alloc", cyg_mempool_var_alloc );         \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_var_timed_alloc_entry,                        \
+                     "cyg_mempool_var_timed_alloc",                            \
+                     cyg_mempool_var_timed_alloc );                            \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_var_try_alloc_entry,                          \
+                     "cyg_mempool_var_try_alloc",                              \
+                     cyg_mempool_var_try_alloc );                              \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_var_free_entry,                               \
+                     "cyg_mempool_var_free", cyg_mempool_var_free );           \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_var_waiting_entry,                            \
+                     "cyg_mempool_var_waiting", cyg_mempool_var_waiting );     \
+CYG_LDR_TABLE_ENTRY( cyg_mempool_var_get_info_entry,                           \
+                     "cyg_mempool_var_get_info", cyg_mempool_var_get_info );
+
+#define CYG_LDR_TABLE_KAPI_MUTEX()                                             \
+CYG_LDR_TABLE_ENTRY( cyg_mutex_init_entry,                                     \
+                     "cyg_mutex_init", cyg_mutex_init );                       \
+CYG_LDR_TABLE_ENTRY( cyg_mutex_destroy_entry,                                  \
+                     "cyg_mutex_destroy", cyg_mutex_destroy );                 \
+CYG_LDR_TABLE_ENTRY( cyg_mutex_trylock_entry,                                  \
+                     "cyg_mutex_trylock", cyg_mutex_trylock );                 \
+CYG_LDR_TABLE_ENTRY( cyg_mutex_unlock_entry,                                   \
+                     "cyg_mutex_unlock", cyg_mutex_unlock );                   \
+CYG_LDR_TABLE_ENTRY( cyg_mutex_release_entry,                                  \
+                     "cyg_mutex_release", cyg_mutex_release );                 \
+CYG_LDR_TABLE_ENTRY( cyg_mutex_set_ceiling_entry,                              \
+                     "cyg_mutex_set_ceiling", cyg_mutex_set_ceiling );         \
+CYG_LDR_TABLE_ENTRY( cyg_mutex_set_protocol_entry,                             \
+                     "cyg_mutex_set_protocol", cyg_mutex_set_protocol );
+
+#define CYG_LDR_TABLE_KAPI_SCHEDULER()                                         \
+CYG_LDR_TABLE_ENTRY( cyg_scheduler_start_entry,                                \
+                     "cyg_scheduler_start", cyg_scheduler_start );             \
+CYG_LDR_TABLE_ENTRY( cyg_scheduler_lock_entry,                                 \
+                     "cyg_scheduler_lock", cyg_scheduler_lock );               \
+CYG_LDR_TABLE_ENTRY( cyg_scheduler_safe_lock_entry,                            \
+                     "cyg_scheduler_safe_lock", cyg_scheduler_safe_lock );     \
+CYG_LDR_TABLE_ENTRY( cyg_scheduler_unlock_entry,                               \
+                     "cyg_scheduler_unlock", cyg_scheduler_unlock );           \
+CYG_LDR_TABLE_ENTRY( cyg_scheduler_read_lock_entry,                            \
+                     "cyg_scheduler_read_lock", cyg_scheduler_read_lock );     \
+
+#define CYG_LDR_TABLE_KAPI_SEMAPHORE()                                         \
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_init_entry,                                 \
+                     "cyg_semaphore_init", cyg_semaphore_init );               \
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_destroy_entry,                              \
+                     "cyg_semaphore_destroy", cyg_semaphore_destroy );         \
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_wait_entry,                                 \
+                     "cyg_semaphore_wait", cyg_semaphore_wait );               \
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_timed_wait_entry,                           \
+                     "cyg_semaphore_timed_wait", cyg_semaphore_timed_wait );   \
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_try_wait_entry,                             \
+                     "cyg_semaphore_try_wait", cyg_semaphore_try_wait );       \
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_post_entry,                                 \
+                     "cyg_semaphore_post", cyg_semaphore_post );               \
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_peek_entry,                                 \
+                     "cyg_semaphore_peek", cyg_semaphore_peek );
+
+#define CYG_LDR_TABLE_KAPI_THREAD()                                            \
+CYG_LDR_TABLE_ENTRY( cyg_thread_create_entry,                                  \
+                     "cyg_thread_create", cyg_thread_create );                 \
+CYG_LDR_TABLE_ENTRY( cyg_thread_exit_entry,                                    \
+                     "cyg_thread_exit", cyg_thread_exit );                     \
+CYG_LDR_TABLE_ENTRY( cyg_thread_delete_entry,                                  \
+                     "cyg_thread_delete", cyg_thread_delete );                 \
+CYG_LDR_TABLE_ENTRY( cyg_thread_suspend_entry,                                 \
+                     "cyg_thread_suspend", cyg_thread_suspend );               \
+CYG_LDR_TABLE_ENTRY( cyg_thread_resume_entry,                                  \
+                     "cyg_thread_resume", cyg_thread_resume );                 \
+CYG_LDR_TABLE_ENTRY( cyg_thread_kill_entry,                                    \
+                     "cyg_thread_kill", cyg_thread_kill );                     \
+CYG_LDR_TABLE_ENTRY( cyg_thread_release_entry,                                 \
+                     "cyg_thread_release", cyg_thread_release );               \
+CYG_LDR_TABLE_ENTRY( cyg_thread_yield_entry,                                   \
+                     "cyg_thread_yield", cyg_thread_yield );                   \
+CYG_LDR_TABLE_ENTRY( cyg_thread_self_entry,                                    \
+                     "cyg_thread_self", cyg_thread_self );                     \
+CYG_LDR_TABLE_ENTRY( cyg_thread_idle_thread_entry,                             \
+                     "cyg_thread_idle_thread", cyg_thread_idle_thread );       \
+CYG_LDR_TABLE_ENTRY( cyg_thread_set_priority_entry,                            \
+                     "cyg_thread_set_priority", cyg_thread_set_priority );     \
+CYG_LDR_TABLE_ENTRY( cyg_thread_get_priority_entry,                            \
+                     "cyg_thread_get_priority", cyg_thread_get_priority );     \
+CYG_LDR_TABLE_ENTRY( cyg_thread_get_current_priority_entry,                    \
+                     "cyg_thread_get_current_priority",                        \
+                     cyg_thread_get_current_priority );                        \
+CYG_LDR_TABLE_ENTRY( cyg_thread_delay_entry,                                   \
+                     "cyg_thread_delay", cyg_thread_delay );                   \
+CYG_LDR_TABLE_ENTRY( cyg_thread_get_stack_base_entry,                          \
+                     "cyg_thread_get_stack_base", cyg_thread_get_stack_base ); \
+CYG_LDR_TABLE_ENTRY( cyg_thread_get_stack_size_entry,                          \
+                     "cyg_thread_get_stack_size", cyg_thread_get_stack_size ); \
+CYG_LDR_TABLE_ENTRY( cyg_thread_get_stack_usage_entry,                         \
+                     "cyg_thread_get_stack_usage",                             \
+                     cyg_thread_get_stack_usage );                             \
+CYG_LDR_TABLE_ENTRY( cyg_thread_measure_stack_usage_entry,                     \
+                     "cyg_thread_measure_stack_usage",                         \
+                     cyg_thread_measure_stack_usage );                         \
+CYG_LDR_TABLE_ENTRY( cyg_thread_new_data_index_entry,                          \
+                     "cyg_thread_new_data_index", cyg_thread_new_data_index ); \
+CYG_LDR_TABLE_ENTRY( cyg_thread_free_data_index_entry,                         \
+                     "cyg_thread_free_data_index",                             \
+                     cyg_thread_free_data_index );                             \
+CYG_LDR_TABLE_ENTRY( cyg_thread_get_data_entry,                                \
+                     "cyg_thread_get_data", cyg_thread_get_data );             \
+CYG_LDR_TABLE_ENTRY( cyg_thread_get_data_ptr_entry,                            \
+                     "cyg_thread_get_data_ptr", cyg_thread_get_data_ptr );     \
+CYG_LDR_TABLE_ENTRY( cyg_thread_set_data_entry,                                \
+                     "cyg_thread_set_data", cyg_thread_set_data );             \
+CYG_LDR_TABLE_ENTRY( cyg_thread_add_destructor_entry,                          \
+                     "cyg_thread_add_destructor", cyg_thread_add_destructor ); \
+CYG_LDR_TABLE_ENTRY( cyg_thread_rem_destructor_entry,                          \
+                     "cyg_thread_rem_destructor", cyg_thread_rem_destructor );
+
+#define CYG_LDR_TABLE_STRING()                                                 \
+CYG_LDR_TABLE_ENTRY( memchr_entry,  "memchr",  memchr );                       \
+CYG_LDR_TABLE_ENTRY( memcmp_entry,  "memcmp",  memcmp );                       \
+CYG_LDR_TABLE_ENTRY( memcpy_entry,  "memcpy",  memcpy );                       \
+CYG_LDR_TABLE_ENTRY( memmove_entry, "memmove", memmove );                      \
+CYG_LDR_TABLE_ENTRY( memset_entry,  "memset",  memset );                       \
+CYG_LDR_TABLE_ENTRY( strcpy_entry,  "strcpy",  strcpy );                       \
+CYG_LDR_TABLE_ENTRY( strncpy_entry, "strncpy", strncpy );                      \
+CYG_LDR_TABLE_ENTRY( strcat_entry,  "strcat",  strcat );                       \
+CYG_LDR_TABLE_ENTRY( strncat_entry, "strncat", strncat );                      \
+CYG_LDR_TABLE_ENTRY( strchr_entry,  "strchr",  strchr );                       \
+CYG_LDR_TABLE_ENTRY( strrchr_entry, "strrchr", strrchr );                      \
+CYG_LDR_TABLE_ENTRY( strcoll_entry, "strcoll", strcoll );                      \
+CYG_LDR_TABLE_ENTRY( strlen_entry,  "strlen",  strlen );                       \
+CYG_LDR_TABLE_ENTRY( strcmp_entry,  "strcmp",  strcmp );                       \
+CYG_LDR_TABLE_ENTRY( strncmp_entry, "strncmp", strncmp );                      \
+CYG_LDR_TABLE_ENTRY( strcspn_entry, "strcspn", strcspn );                      \
+CYG_LDR_TABLE_ENTRY( strerror_entry, "strerror", strerror );                   \
+CYG_LDR_TABLE_ENTRY( strpbrk_entry, "strpbrk", strpbrk );                      \
+CYG_LDR_TABLE_ENTRY( strspn_entry,  "strspn",  strspn );                       \
+CYG_LDR_TABLE_ENTRY( strstr_entry,  "strstr",  strstr );                       \
+CYG_LDR_TABLE_ENTRY( strtok_entry,  "strtok",  strtok );                       \
+CYG_LDR_TABLE_ENTRY( strxfrm_entry, "strxfrm", strxfrm ); 
+
+#define CYG_LDR_TABLE_STDIO()                                                  \
+CYG_LDR_TABLE_ENTRY( clearerr_entry,  "clearerr",  clearerr );                 \
+CYG_LDR_TABLE_ENTRY( fclose_entry,  "fclose",  fclose );                       \
+CYG_LDR_TABLE_ENTRY( feof_entry,    "feof",    feof );                         \
+CYG_LDR_TABLE_ENTRY( ferror_entry,  "ferror",  ferror );                       \
+CYG_LDR_TABLE_ENTRY( fflush_entry,  "fflush",  fflush );                       \
+CYG_LDR_TABLE_ENTRY( fgetc_entry,   "fgetc",   fgetc );                        \
+CYG_LDR_TABLE_ENTRY( fgetpos_entry, "fgetpos", fgetpos );                      \
+CYG_LDR_TABLE_ENTRY( fgets_entry,   "fgets",   fgets );                        \
+CYG_LDR_TABLE_ENTRY( fopen_entry,   "fopen",   fopen );                        \
+CYG_LDR_TABLE_ENTRY( fprintf_entry, "fprintf", fprintf );                      \
+CYG_LDR_TABLE_ENTRY( fputc_entry,   "fputc",   fputc );                        \
+CYG_LDR_TABLE_ENTRY( fputchar_entry, "fputchar", fputchar );                   \
+CYG_LDR_TABLE_ENTRY( fputs_entry,   "fputs",   fputs );                        \
+CYG_LDR_TABLE_ENTRY( fread_entry,   "fread",   fread );                        \
+CYG_LDR_TABLE_ENTRY( freopen_entry, "freopen", freopen );                      \
+CYG_LDR_TABLE_ENTRY( fscanf_entry,  "fscanf",  fscanf );                       \
+CYG_LDR_TABLE_ENTRY( fseek_entry,   "fseek",   fseek );                        \
+CYG_LDR_TABLE_ENTRY( fsetpos_entry, "fsetpos", fsetpos );                      \
+CYG_LDR_TABLE_ENTRY( ftell_entry,   "ftell",   ftell );                        \
+CYG_LDR_TABLE_ENTRY( fwrite_entry,  "fwrite",  fwrite );                       \
+CYG_LDR_TABLE_ENTRY( fgetc_entry,   "fgetc",   fgetc );                        \
+CYG_LDR_TABLE_ENTRY( fgetchar_entry, "fgetchar", fgetchar );                   \
+CYG_LDR_TABLE_ENTRY( fgets_entry,   "fgets",   fgets );                        \
+CYG_LDR_TABLE_ENTRY( fgetw_entry,   "fgetw",   fgetw );                        \
+CYG_LDR_TABLE_ENTRY( perror_entry,  "perror",  perror );                       \
+CYG_LDR_TABLE_ENTRY( printf_entry,  "printf",  printf );                       \
+CYG_LDR_TABLE_ENTRY( putc_entry,    "putc",    putc );                         \
+CYG_LDR_TABLE_ENTRY( putchar_entry, "putchar", putchar );                      \
+CYG_LDR_TABLE_ENTRY( puts_entry,    "puts",    puts );                         \
+CYG_LDR_TABLE_ENTRY( putw_entry,    "putw",    putw );                         \
+CYG_LDR_TABLE_ENTRY( remove_entry,  "remove",  remove );                       \
+CYG_LDR_TABLE_ENTRY( rename_entry,  "rename",  rename );                       \
+CYG_LDR_TABLE_ENTRY( rewind_entry,  "rewind",  rewind );                       \
+CYG_LDR_TABLE_ENTRY( scanf_entry,   "scanf",   scanf );                        \
+CYG_LDR_TABLE_ENTRY( setbuf_entry,  "setbuf",  setbuf );                       \
+CYG_LDR_TABLE_ENTRY( setvbuf_entry, "setvbuf", setvbuf );                      \
+CYG_LDR_TABLE_ENTRY( sprintf_entry, "sprintf", sprintf );                      \
+CYG_LDR_TABLE_ENTRY( sscanf_entry,  "sscanf",  sscanf );                       \
+CYG_LDR_TABLE_ENTRY( tmpfile_entry, "tmpfile", tmpfile );                      \
+CYG_LDR_TABLE_ENTRY( tmpnam_entry,  "tmpnam",  tmpnam );                       \
+CYG_LDR_TABLE_ENTRY( ungetc_entry,  "ungetc",  ungetc );
+
+#define CYG_LDR_TABLE_INFRA_DIAG()                                             \
+CYG_LDR_TABLE_ENTRY( diag_init_entry, "diag_init", diag_init );                \
+CYG_LDR_TABLE_ENTRY( diag_write_char_entry,                                    \
+                     "diag_write_char", diag_write_char );                     \
+CYG_LDR_TABLE_ENTRY( diag_write_string_entry,                                  \
+                     "diag_write_string", diag_write_string );                 \
+CYG_LDR_TABLE_ENTRY( diag_write_dec_entry,                                     \
+                     "diag_write_dec", diag_write_dec );                       \
+CYG_LDR_TABLE_ENTRY( diag_write_hex_entry,                                     \
+                     "diag_write_hex", diag_write_hex );                       \
+CYG_LDR_TABLE_ENTRY( diag_dump_buf_entry,                                      \
+                     "diag_dump_buf", diag_dump_buf );                         \
+CYG_LDR_TABLE_ENTRY( diag_dump_buf_32bit_entry,                                \
+                     "diag_dump_buf_32bit", diag_dump_buf_32bit );             \
+CYG_LDR_TABLE_ENTRY( diag_dump_buf_16bit_entry,                                \
+                     "diag_dump_buf_16bit", diag_dump_buf_16bit );             \
+CYG_LDR_TABLE_ENTRY( __printf_fun_entry,                                       \
+                     "__printf_fun", __printf_fun );                           \
+CYG_LDR_TABLE_ENTRY( diag_vdump_buf_with_offset_entry,                         \
+                     "diag_vdump_buf_with_offset",                             \
+                     diag_vdump_buf_with_offset );                             \
+CYG_LDR_TABLE_ENTRY( diag_dump_buf_with_offset_entry,                          \
+                     "diag_dump_buf_with_offset",                              \
+                     diag_dump_buf_with_offset );                              \
+CYG_LDR_TABLE_ENTRY( diag_dump_buf_with_offset_32bit_entry,                    \
+                     "diag_dump_buf_with_offset_32bit",                        \
+                     diag_dump_buf_with_offset_32bit );                        \
+CYG_LDR_TABLE_ENTRY( diag_dump_buf_with_offset_16bit_entry,                    \
+                     "diag_dump_buf_with_offset_16bit",                        \
+                     diag_dump_buf_with_offset_16bit );                        \
+CYG_LDR_TABLE_ENTRY( diag_printf_entry, "diag_printf", diag_printf );          \
+CYG_LDR_TABLE_ENTRY( diag_init_putc_entry, "diag_init_putc", diag_init_putc ); \
+CYG_LDR_TABLE_ENTRY( diag_sprintf_entry, "diag_sprintf", diag_sprintf );       \
+CYG_LDR_TABLE_ENTRY( diag_snprintf_entry, "diag_snprintf", diag_snprintf );    \
+CYG_LDR_TABLE_ENTRY( diag_vsprintf_entry, "diag_vsprintf", diag_vsprintf );    \
+CYG_LDR_TABLE_ENTRY( diag_vprintf_entry, "diag_vprintf", diag_vprintf );
+
+//==============================================================================
+#endif
+
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/include/relocate_ppc.h
@@ -0,0 +1,132 @@
+#ifndef __RELOCATE_PPC_H__
+#define __RELOCATE_PPC_H__
+
+/* =================================================================
+ *
+ *      relocate_ppc.h
+ *
+ *      Architecture dependent relocation routines for the PowerPC
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ * 
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+#define Elf_Rel                0
+#define Elf_Rela               1
+#define ELF_ARCH_MACHINE_TYPE  20    // PowerPC.
+#define ELF_ARCH_ENDIANNESS    ELFDATA2MSB
+#define ELF_ARCH_RELTYPE       Elf_Rela
+
+#define R_PPC_NONE              0
+#define R_PPC_ADDR32            1  // 32bit absolute address 
+#define R_PPC_ADDR24            2  // 26bit address, 2 bits ignored.  
+#define R_PPC_ADDR16            3  // 16bit absolute address 
+#define R_PPC_ADDR16_LO         4  // lower 16bit of absolute address 
+#define R_PPC_ADDR16_HI         5  // high 16bit of absolute address 
+#define R_PPC_ADDR16_HA         6  // adjusted high 16bit 
+#define R_PPC_ADDR14            7  // 16bit address, 2 bits ignored 
+#define R_PPC_ADDR14_BRTAKEN    8
+#define R_PPC_ADDR14_BRNTAKEN   9
+#define R_PPC_REL24            10  // PC relative 26 bit 
+#define R_PPC_REL14            11   // PC relative 16 bit 
+#define R_PPC_REL14_BRTAKEN    12
+#define R_PPC_REL14_BRNTAKEN   13
+#define R_PPC_GOT16            14
+#define R_PPC_GOT16_LO         15
+#define R_PPC_GOT16_HI         16
+#define R_PPC_GOT16_HA         17
+#define R_PPC_PLTREL24         18
+#define R_PPC_COPY             19
+#define R_PPC_GLOB_DAT         20
+#define R_PPC_JMP_SLOT         21
+#define R_PPC_RELATIVE         22
+#define R_PPC_LOCAL24PC        23
+#define R_PPC_UADDR32          24
+#define R_PPC_UADDR16          25
+#define R_PPC_REL32            26
+#define R_PPC_PLT32            27
+#define R_PPC_PLTREL32         28
+#define R_PPC_PLT16_LO         29
+#define R_PPC_PLT16_HI         30
+#define R_PPC_PLT16_HA         31
+#define R_PPC_SDAREL16         32
+#define R_PPC_SECTOFF          33
+#define R_PPC_SECTOFF_LO       34
+#define R_PPC_SECTOFF_HI       35
+#define R_PPC_SECTOFF_HA       36
+
+// Keep this the last entry.  
+#define R_PPC_NUM              37
+
+// The remaining relocs are from the Embedded ELF ABI, and are not
+//  in the SVR4 ELF ABI.  
+#define R_PPC_EMB_NADDR32     101
+#define R_PPC_EMB_NADDR16     102
+#define R_PPC_EMB_NADDR16_LO  103
+#define R_PPC_EMB_NADDR16_HI  104
+#define R_PPC_EMB_NADDR16_HA  105
+#define R_PPC_EMB_SDAI16      106
+#define R_PPC_EMB_SDA2I16     107
+#define R_PPC_EMB_SDA2REL     108
+#define R_PPC_EMB_SDA21       109  // 16 bit offset in SDA 
+#define R_PPC_EMB_MRKREF      110
+#define R_PPC_EMB_RELSEC16    111
+#define R_PPC_EMB_RELST_LO    112
+#define R_PPC_EMB_RELST_HI    113
+#define R_PPC_EMB_RELST_HA    114
+#define R_PPC_EMB_BIT_FLD     115
+#define R_PPC_EMB_RELSDA      116  // 16 bit relative offset in SDA 
+
+// From the Elf PPC spec.
+#define _lo_(x)    (x & 0xFFFF) 
+#define _hi_(x)    ((x >> 16) & 0xFFFF)
+#define _ha_(x)    (((x >> 16)+((x & 0x8000) ? 1 : 0)) & 0xFFFF)
+
+void      cyg_ldr_flush_cache( void );
+cyg_int32 cyg_ldr_relocate( cyg_int32, cyg_uint32, cyg_int32 );
+
+#endif //__RELOCATE_PPC_H__
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/src/loader_fs.c
@@ -0,0 +1,123 @@
+/* =================================================================
+ *
+ *      loader_fs.c
+ *
+ *      Routines to read a library from a file system.
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ * 
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Contributors: nickg@ecoscentric.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+#include <cyg/infra/diag.h>     // For diagnostic printing.
+#include <pkgconf/io_fileio.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <pkgconf/objloader.h>
+#include <cyg/objloader/elf.h>
+#include <cyg/objloader/objelf.h>
+#include <cyg/objloader/loader_fs.h>
+
+size_t 
+cyg_ldr_fs_read( PELF_OBJECT p, size_t s, size_t n, void *mem )
+{
+    return fread( mem, s, n, (FILE*)p->ptr );
+}
+
+cyg_int32 
+cyg_ldr_fs_seek( PELF_OBJECT p, cyg_uint32 offs )
+{
+    return fseek( (FILE*)p->ptr, offs, SEEK_SET );
+}
+
+cyg_int32 
+cyg_ldr_fs_close( PELF_OBJECT p )
+{
+    return fclose( (FILE*)p->ptr );
+}
+
+PELF_OBJECT
+cyg_ldr_open_library_fs( cyg_uint8 *ptr )
+{
+    PELF_OBJECT  e_obj; 
+    FILE        *fp;
+
+    fp = fopen( ptr, "rb" );
+    if ( fp == 0 )
+    {
+        cyg_ldr_last_error = "FILE NOT FOUND";
+        return (void*)0;
+    }
+    
+    // Create a file object to keep track of this library.
+    e_obj = (PELF_OBJECT)malloc( sizeof( ELF_OBJECT ) );
+    CYG_ASSERT( e_obj != 0, "Cannot malloc() e_obj" );
+    if ( e_obj == 0 )
+    {
+        cyg_ldr_last_error = "ERROR IN MALLOC";
+        fclose( fp ); 
+        return (void*)0;
+    }
+    memset( e_obj, 0, sizeof( ELF_OBJECT ) );
+    e_obj->ptr   = (CYG_ADDRWORD)fp;
+    e_obj->mode  = CYG_LDR_MODE_FILESYSTEM;
+
+    // Handlers for the file system open.
+    e_obj->read  = cyg_ldr_fs_read;
+    e_obj->seek  = cyg_ldr_fs_seek;
+    e_obj->close = cyg_ldr_fs_close;
+    return e_obj;
+}
+
+void
+cyg_ldr_close_library_fs( PELF_OBJECT p )
+{
+}
+
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/src/objelf.c
@@ -0,0 +1,397 @@
+/* =================================================================
+ *
+ *      objelf.c
+ *
+ *      Relocation routine for eCos loader.
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ * 
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Contributors: nickg@ecoscentric.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+#include <cyg/infra/diag.h>     // For diagnostic printing.
+#include <pkgconf/io_fileio.h>
+#include <cyg/hal/hal_tables.h>
+#include <stdio.h>
+
+#include <pkgconf/objloader.h>
+#include <cyg/objloader/elf.h>
+#include <cyg/objloader/objelf.h>
+
+CYG_HAL_TABLE_BEGIN( cyg_ldr_table, ldr_table );
+CYG_HAL_TABLE_END( cyg_ldr_table_end, ldr_table );
+
+__externC cyg_ldr_table_entry cyg_ldr_table[];
+__externC cyg_ldr_table_entry cyg_ldr_table_end[];
+
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
+void 
+cyg_ldr_print_section_data( PELF_OBJECT p )
+{
+    cyg_int32  i;
+    cyg_uint8  strname[32];
+    cyg_uint8  *p_strtab = (cyg_uint8*)p->sections[p->p_elfhdr->e_shstrndx];
+    
+    diag_printf( "\n\nSection Headers:\n" ); 
+    diag_printf( "[Nr]  Name                  Addr    Offset    Size     Info\n" );
+    for ( i = 0; i < p->p_elfhdr->e_shnum; i++ )
+    {
+        sprintf( strname, "%s", p_strtab + p->p_sechdr[i].sh_name );
+        while ( strlen( strname ) < 20 )
+            strcat( strname, " " );
+        diag_printf( "[%02d] %s %08X %08X %08X %08X\n",  
+                     i, 
+                     strname,
+                     p->p_sechdr[i].sh_addr,
+                     p->p_sechdr[i].sh_offset,
+                     p->p_sechdr[i].sh_size,
+                     p->p_sechdr[i].sh_info );
+    }                 
+    diag_printf( "\n" ); 
+}
+
+void 
+cyg_ldr_print_symbol_names( PELF_OBJECT p )
+{
+    cyg_int32  i, symtab_entries;
+    Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab];
+    cyg_uint8 *p_strtab = (cyg_uint8*)p->sections[p->hdrndx_strtab];
+    cyg_uint8  strname[32];
+
+    // Total number of entries in the symbol table.
+    symtab_entries = p->p_sechdr[p->hdrndx_symtab].sh_size / 
+                                p->p_sechdr[p->hdrndx_symtab].sh_entsize;
+    diag_printf( "Num  Value     Size Ndx   Name\n" ); 
+    for ( i = 1; i < symtab_entries; i++ )
+    {
+        sprintf( strname, "%d", i );
+        while ( strlen( strname ) < 5 )
+            strcat( strname, " " );
+        diag_printf( strname );         
+        
+        sprintf( strname, 
+                 "%08X  %d", 
+                 p_symtab[i].st_value, 
+                 p_symtab[i].st_size );
+        while ( strlen( strname ) < 15 )
+            strcat( strname, " " );
+        diag_printf( strname );         
+        
+        sprintf( strname, "%d", p_symtab[i].st_shndx );
+        while ( strlen( strname ) < 6 )
+            strcat( strname, " " );
+        diag_printf( strname );         
+        
+        strncpy( strname, 
+                 p_strtab + p_symtab[i].st_name, 
+                 sizeof( strname ) - 1 );
+        strname[strlen( p_strtab + p_symtab[i].st_name )] = '\0';
+        diag_printf( strname );         
+        diag_printf( "\n" );         
+    }
+}
+
+void 
+cyg_ldr_print_rel_names( PELF_OBJECT p )
+{
+    cyg_int32     i, j, r_entries, sym_index;
+    Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab];
+    cyg_uint8 *p_strtab = (cyg_uint8*)p->sections[p->hdrndx_strtab];
+    cyg_uint8 *p_shstrtab = (cyg_uint8*)p->sections[p->p_elfhdr->e_shstrndx];
+#if ELF_ARCH_RELTYPE == Elf_Rela        
+    Elf32_Rela*   p_rela;
+#else
+    Elf32_Rel*    p_rel;
+#endif
+    cyg_uint8  strname[32];
+
+    for ( i = 1; i < p->p_elfhdr->e_shnum; i++ )
+    {
+        if ( ( p->p_sechdr[i].sh_type == SHT_REL ) ||
+                                  ( p->p_sechdr[i].sh_type == SHT_RELA ) )
+        {                                  
+            // Calculate the total number of entries in the .rela section.
+            r_entries = p->p_sechdr[i].sh_size / p->p_sechdr[i].sh_entsize;
+
+            diag_printf( "\n\nSymbols at: %s\n\n", 
+                         p_shstrtab + p->p_sechdr[i].sh_name );
+#if ELF_ARCH_RELTYPE == Elf_Rela        
+            p_rela = (Elf32_Rela*)cyg_ldr_load_elf_section( p, i );
+            printf( "Offset    Info      Name [+ Addend]\n" );
+#else
+            p_rel = (Elf32_Rel*)cyg_ldr_load_elf_section( p, i );
+            printf( "Offset    Info     Name\n" );
+#endif
+
+            for ( j = 0; j < r_entries; j++ )
+            {
+                sprintf( strname, 
+                         "%08X  %08X  ", 
+                         p_rela[j].r_offset,
+                         p_rela[j].r_info );
+
+                diag_printf( strname );         
+                
+                cyg_uint8 sym_type = ELF32_R_SYM( p_rela[j].r_info );
+                if ( strlen ( p_strtab + p_symtab[sym_type].st_name ) > 0 )
+                    diag_printf( p_strtab + p_symtab[sym_type].st_name );         
+                else 
+                {   
+                    // If the symbol name is not available, then print
+                    //  the name of the section.
+                    sym_index = p_symtab[sym_type].st_shndx;                    
+                    diag_printf( p_shstrtab + p->p_sechdr[sym_index].sh_name );         
+                }    
+#if ELF_ARCH_RELTYPE == Elf_Rela        
+                if ( p_rela[j].r_addend != 0 )
+                    diag_printf( " + %08X", p_rela[j].r_addend );
+#endif
+                diag_printf( "\n" );         
+            }            
+            // After all the printing is done, the relocation table can 
+            //  be dumped.
+            cyg_ldr_delete_elf_section( p, i );
+        } 
+    }    
+}
+#endif // DEBUG_PRINT
+
+static void
+*cyg_ldr_local_address( PELF_OBJECT p, cyg_uint32 sym_index )
+{
+    cyg_uint32 data_sec, addr;
+    Elf32_Sym *p_symtab;
+
+    p_symtab = (Elf32_Sym*)cyg_ldr_section_address( p, p->hdrndx_symtab );
+    
+    // Find out the section number in which the data for this symbol is 
+    //  located.
+    data_sec = p_symtab[sym_index].st_shndx;    
+
+    // From the section number we get the start of the memory area in 
+    //  memory.
+    addr = (cyg_uint32)cyg_ldr_section_address( p, data_sec );
+
+    // And now return the address of the data.
+    return (void*)( addr + p_symtab[sym_index].st_value);
+}    
+
+static void
+*cyg_ldr_external_address( PELF_OBJECT p, cyg_uint32 sym_index )
+{
+    cyg_uint8*    tmp2;
+    Elf32_Sym *p_symtab;
+    cyg_uint8 *p_strtab;
+    cyg_ldr_table_entry *entry = cyg_ldr_table;
+  
+  
+    p_symtab = (Elf32_Sym*)cyg_ldr_section_address( p, p->hdrndx_symtab );
+    p_strtab = (cyg_uint8*)cyg_ldr_section_address( p, p->hdrndx_strtab );
+  
+    // This is the name of the external reference to search.
+    tmp2 = p_strtab + p_symtab[sym_index].st_name;
+    while ( entry != cyg_ldr_table_end )
+    {
+        if ( !strcmp( (const char*)tmp2, entry->symbol_name  ) )
+            return entry->handler;
+        entry++;
+    }
+
+    // Symbol not found.
+    return 0;
+}
+
+// input:
+// p          : Pointer to the elf file object
+// sym_index  : Index of the symbol to be searched (in the SYMTAB)
+//
+// out:
+// 0          : Symbol not found
+// Other      : Address of the symbol in absolute memory.
+void 
+*cyg_ldr_symbol_address( PELF_OBJECT p, cyg_uint32 sym_index )
+{
+    cyg_uint32 addr;
+    cyg_uint8  sym_info;
+    Elf32_Sym *p_symtab;
+
+    p_symtab = (Elf32_Sym*)cyg_ldr_section_address( p, p->hdrndx_symtab );
+    sym_info = p_symtab[sym_index].st_info;
+    
+    switch ( ELF32_ST_TYPE( sym_info ) )
+    {
+    case STT_NOTYPE:
+    case STT_FUNC:
+    case STT_OBJECT:
+        switch ( ELF32_ST_BIND( sym_info ) )
+        {
+        case STB_LOCAL:
+        case STB_GLOBAL:
+            if ( p_symtab[sym_index].st_shndx == SHN_UNDEF ) 
+                return cyg_ldr_external_address( p, sym_index );
+            else
+                return cyg_ldr_local_address( p, sym_index );
+        case STB_WEAK:
+            addr = (cyg_uint32)cyg_ldr_external_address( p, sym_index );
+            if ( addr != 0 )
+                return (void*)addr;
+            else    
+                return cyg_ldr_local_address( p, sym_index );
+        default:
+            return 0;
+        }
+        break;
+    case STT_SECTION:
+        // Return the starting address of a section, given its index.
+        return (void*)cyg_ldr_section_address( p, 
+                                               p_symtab[sym_index].st_shndx );
+    default:
+        return 0;
+    }
+}
+
+// Loads the relocation information, relocates, and dumps the relocation
+//  information once the process is complete.
+cyg_int32 
+cyg_ldr_relocate_section( PELF_OBJECT p, cyg_uint32 r_shndx )
+{
+    cyg_int32   i, rc;
+    cyg_uint32  r_entries, r_target_shndx, r_target_addr;
+    cyg_uint32  sym_value, sym_index;
+    Elf32_Addr  r_offset;
+    Elf32_Word  r_type;
+    Elf32_Sword r_addend;
+#if ELF_ARCH_RELTYPE == Elf_Rela        
+    Elf32_Rela* p_rela = (Elf32_Rela*)cyg_ldr_load_elf_section( p, r_shndx );
+#else
+    Elf32_Rel*  p_rel = (Elf32_Rel*)cyg_ldr_load_elf_section( p, r_shndx );
+#endif
+
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
+    Elf32_Sym *p_symtab = (Elf32_Sym*)cyg_ldr_section_address( p, 
+                                                           p->hdrndx_symtab );
+    cyg_uint8 *p_strtab = (cyg_uint8*)cyg_ldr_section_address( p, 
+                                                           p->hdrndx_strtab );
+    cyg_uint8 *p_shstrtab = (cyg_uint8*)cyg_ldr_section_address( p, 
+                                                     p->p_elfhdr->e_shstrndx );
+#endif
+
+    // Now we can get the address of the contents of the section to modify.
+    r_target_shndx = p->p_sechdr[r_shndx].sh_info;
+    r_target_addr  = (cyg_uint32)cyg_ldr_section_address( p, r_target_shndx );
+
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
+    diag_printf( "Relocating section \"%s\"\n",
+            p_shstrtab + p->p_sechdr[r_target_shndx].sh_name );
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
+    diag_printf( "Ndx   Type   Offset    Name\"\n" );
+#endif
+#endif
+
+    // Perform relocatation for each of the members of this table.
+    r_entries = p->p_sechdr[r_shndx].sh_size / p->p_sechdr[r_shndx].sh_entsize;
+    for ( i = 0; i < r_entries; i++ )
+    {
+#if ELF_ARCH_RELTYPE == Elf_Rela        
+        r_offset  = p_rela[i].r_offset; 
+        r_type    = ELF32_R_TYPE( p_rela[i].r_info ); 
+        sym_index = ELF32_R_SYM( p_rela[i].r_info );
+        r_addend  = p_rela[i].r_addend; 
+#else
+        r_offset  = p_rel[i].r_offset; 
+        r_type    = ELF32_R_TYPE( p_rel[i].r_info ); 
+        sym_index = ELF32_R_SYM( p_rel[i].r_info );
+        r_addend  = 0; 
+#endif
+
+        sym_value = (cyg_uint32)cyg_ldr_symbol_address( p, sym_index );
+        if ( sym_value == 0 )
+        {
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
+            diag_printf( "Unknown symbol value: %s Index: %d\n",
+                         p_strtab + p_symtab[sym_index].st_name,
+                         sym_index );
+#endif
+            return -1;
+        }    
+        
+        // This is architecture dependent, and deals with whether we have
+        //  '.rel' or '.rela' sections.
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
+        diag_printf( "%04X  %04X  %08X  ",
+                     sym_index,
+                     r_type,
+                     r_offset );
+        if ( strlen ( p_strtab + p_symtab[sym_index].st_name ) > 0 )
+            diag_printf( p_strtab + p_symtab[sym_index].st_name );         
+        else 
+        {   
+            // If the symbol name is not available, then print
+            //  the name of the section.
+            cyg_uint32 sec_ndx = p_symtab[sym_index].st_shndx;                    
+            diag_printf( p_shstrtab + p->p_sechdr[sec_ndx].sh_name );         
+        }    
+        diag_printf( "\n" );         
+#endif
+        rc = cyg_ldr_relocate( r_type,
+                               r_target_addr + r_offset, 
+                               sym_value + r_addend );
+        if ( rc != 0 )
+        {
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
+            diag_printf( "Relocation error: Cannot find symbol: %s\n",
+                      p_strtab + p_symtab[sym_index].st_name );
+#endif
+            return -1;
+        }    
+    }
+
+    // After the relocation is done, the relocation table can be dumped.
+    cyg_ldr_delete_elf_section( p, r_shndx );
+    return 0;
+}
+
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/src/objloader.c
@@ -0,0 +1,462 @@
+/* =================================================================
+ *
+ *      objelf.c
+ *
+ *      An object loader for eCos
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ * 
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Contributors: nickg@ecoscentric.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+#include <cyg/infra/diag.h>     // For diagnostic printing.
+#include <cyg/infra/cyg_ass.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <pkgconf/objloader.h>
+#include <cyg/objloader/elf.h>
+#include <cyg/objloader/objelf.h>
+#include <cyg/objloader/loader_fs.h>
+
+cyg_uint8 *cyg_ldr_last_error;
+
+void *cyg_ldr_malloc( size_t ) CYGBLD_ATTRIB_WEAK;
+void
+*cyg_ldr_malloc( size_t s )
+{
+    return malloc( s );
+}
+
+void cyg_ldr_free( void * ) CYGBLD_ATTRIB_WEAK;
+void
+cyg_ldr_free( void *s )
+{
+    free( s );
+}
+
+void
+cyg_ldr_delete_elf_section( PELF_OBJECT p, cyg_uint32 idx )
+{
+    cyg_ldr_free( p->sections[idx] );
+    p->sections[idx] = 0; 
+}    
+
+// Frees all the memory allocated for a particular ELF object. Also calls
+//  the close() function to close files or sockets, and finally frees up
+//  the ELF object altogether.
+static void
+cyg_ldr_free_elf_object( PELF_OBJECT p )
+{
+    cyg_int32 i;
+        
+    for ( i = 0; i < p->p_elfhdr->e_shnum + 1; i++ )
+        if ( p->sections[i] )
+            cyg_ldr_delete_elf_section( p, i );
+
+    if ( p->sections != 0 )
+        cyg_ldr_free( p->sections ); 
+
+    if ( p->p_sechdr != 0 )
+        cyg_ldr_free( p->p_sechdr ); 
+
+    if ( p->p_elfhdr != 0 )
+        cyg_ldr_free( p->p_elfhdr ); 
+
+    p->close( p );    
+    cyg_ldr_free( p );
+}        
+
+static cyg_uint32 
+cyg_ldr_find_common_size( PELF_OBJECT p )
+{
+    cyg_int32 i, symtab_entries, common_size = 0;
+    Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab];
+     
+    // Total number of entries in the symbol table.
+    symtab_entries = p->p_sechdr[p->hdrndx_symtab].sh_size / 
+                                p->p_sechdr[p->hdrndx_symtab].sh_entsize;
+    for ( i = 1; i < symtab_entries; i++ )
+        if ( p_symtab[i].st_shndx == SHN_COMMON )
+        {
+            // In the case of an SHN_COMMON symbol the st_value field holds 
+            //  alignment constraints.
+            cyg_uint32 boundary = p_symtab[i].st_value - 1;
+
+            // Calculate the next byte boundary.
+            common_size = ( common_size + boundary ) & ~boundary;
+            common_size += p_symtab[i].st_size;
+        }    
+
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
+    diag_printf( "common_size = %d\n", common_size );
+#endif
+    return common_size;
+}
+
+// Allocates memory and loads the contents of a specific ELF section.
+// Returns the address of the newly allocated memory, of 0 for any error.
+cyg_int32 
+*cyg_ldr_load_elf_section( PELF_OBJECT p, cyg_uint32 idx )
+{
+    cyg_uint32 *addr;
+    
+    addr = cyg_ldr_malloc( p->p_sechdr[idx].sh_size );
+    CYG_ASSERT( addr != 0, "Cannot malloc() section" );
+    if ( addr == 0 )
+    {
+        cyg_ldr_last_error = "ERROR IN MALLOC";
+        return (void*)0;
+    }
+    p->seek( p, p->p_sechdr[idx].sh_offset );
+    p->read( p, sizeof( char ), p->p_sechdr[idx].sh_size, addr );
+    return addr;
+}    
+
+// Returns the starting address of a section. If the section is not already
+//  loaded in memory, area for it will be allocated and the section will be
+//  loaded.
+cyg_int32 
+*cyg_ldr_section_address( PELF_OBJECT p, cyg_uint32 idx )
+{
+    if ( p->sections[idx] == 0 )
+        p->sections[idx] = cyg_ldr_load_elf_section( p, idx );
+
+    return p->sections[idx];
+}
+
+void
+*cyg_ldr_find_symbol( void* handle, cyg_uint8* sym_name )
+{
+    PELF_OBJECT p = (PELF_OBJECT)handle;
+    cyg_uint8* tmp2;
+    cyg_int32  i, symtab_entries;
+    cyg_uint8 *p_strtab = (cyg_uint8*)p->sections[p->hdrndx_strtab];
+    Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab];
+  
+    symtab_entries = p->p_sechdr[p->hdrndx_symtab].sh_size / 
+                               p->p_sechdr[p->hdrndx_symtab].sh_entsize;
+
+    for ( i = 0; i < symtab_entries; i++ )
+    {
+        tmp2 = p_strtab + p_symtab[i].st_name;
+        if ( !strcmp( tmp2, sym_name ) )
+            return cyg_ldr_symbol_address( p, i );
+    }
+
+    // Symbol not found.
+    cyg_ldr_last_error = "SYMBOL NOT FOUND";
+    return 0;
+}
+
+static cyg_uint8
+*cyg_ldr_sanity_check( PELF_OBJECT p )
+{
+    if ( ( p->p_elfhdr->e_ident[EI_MAG0] != ELFMAG0 )  || 
+         ( p->p_elfhdr->e_ident[EI_MAG1] != ELFMAG1 )  ||
+         ( p->p_elfhdr->e_ident[EI_MAG2] != ELFMAG2  ) || 
+         ( p->p_elfhdr->e_ident[EI_MAG3] != ELFMAG3 )  || 
+         ( p->p_elfhdr->e_ident[EI_CLASS] != ELFCLASS32 ) )
+        return "INVALID ELF HEADER";
+
+    // We only work with relocatable files. No dynamic linking.
+    if ( p->p_elfhdr->e_type != ET_REL )
+        return "NOT RELOCATABLE";
+        
+    // These #defines are sitting in the hal.
+    if ( p->p_elfhdr->e_machine != ELF_ARCH_MACHINE_TYPE )
+        return "INVALID ARCHITECTURE";
+
+    if ( p->p_elfhdr->e_ident[EI_DATA] != ELF_ARCH_ENDIANNESS )
+        return "INVALID ENDIAN";
+    return 0;  }     
+
+// Load only the ELF header and the sections header. These are the only
+//  sections loaded during library initialization. All the other sections
+//  will be loaded on demand when needed during the relocation process and,
+//  when possible, dumped after use.
+static cyg_int32 
+cyg_ldr_load_sections( PELF_OBJECT p )
+{
+    cyg_uint8  *error_string;
+    cyg_int32  idx;
+
+    // Load the ELF header.
+    p->p_elfhdr = (Elf32_Ehdr*)cyg_ldr_malloc( sizeof( Elf32_Ehdr ) );
+    CYG_ASSERT( p->p_elfhdr != 0, "Cannot malloc() p->p_elfhdr" );
+    if ( p->p_elfhdr == 0 )
+        return -1;
+    p->seek( p, 0 );
+    p->read( p, sizeof( char ), sizeof( Elf32_Ehdr ), p->p_elfhdr  );
+    error_string = cyg_ldr_sanity_check( p );
+    if ( error_string != 0 )
+    {
+        cyg_ldr_last_error = "ERROR IN ELF HEADER";
+        return -1;
+    }    
+    
+    // Allocate an array that can hold an address to all the section of this
+    //  library. This is not strictly optimal, since some sections do not
+    //  need to be loaded all the time. Allocate an extra pointer for the
+    //  COMMON area. 
+    p->sections = cyg_ldr_malloc( ( p->p_elfhdr->e_shnum + 1 ) * 
+                                                     sizeof( cyg_uint32 ) );
+    CYG_ASSERT( p->sections != 0, "Cannot malloc() p->sections" );
+    if ( p->sections == 0 )
+    {
+        cyg_ldr_last_error = "ERROR IN MALLOC";
+        return -1;
+    }
+    memset( p->sections, 0, ( p->p_elfhdr->e_shnum + 1 ) * 
+                                                     sizeof( cyg_uint32 ) );
+    
+    // Now that the header is loaded, load the sections header.
+    p->p_sechdr = (Elf32_Shdr*)cyg_ldr_malloc( 
+                             p->p_elfhdr->e_shnum * p->p_elfhdr->e_shentsize );
+    CYG_ASSERT( p->p_sechdr != 0, "Cannot malloc() p->p_sechdr" );
+    if ( p->p_sechdr == 0 )
+    {
+        cyg_ldr_last_error = "ERROR IN MALLOC";
+        return -1;
+    }
+    p->seek( p, p->p_elfhdr->e_shoff );
+    p->read( p, p->p_elfhdr->e_shentsize, p->p_elfhdr->e_shnum, p->p_sechdr );
+    
+    // Load the section header string table. This is a byte oriented table,
+    //  so alignment is not an issue.
+    idx = p->p_elfhdr->e_shstrndx;
+    p->sections[idx] = cyg_ldr_load_elf_section( p, idx );
+    return 0;
+}
+
+PELF_OBJECT
+cyg_ldr_open_library( CYG_ADDRWORD ptr, cyg_int32 mode )
+{
+    Elf32_Sym *p_symtab;
+    cyg_uint8 *p_shstrtab;
+    PELF_OBJECT e_obj; 
+    int (*fn)(void);
+    cyg_int32   i, rc, symtab_entries;
+    cyg_uint32  common_size;
+
+    // In the future there might be a switch() (against 'mode') that calls an
+    //  open function other than cyg_ldr_open_library_fs(). These function
+    //  fetch and open a library using ftp, http or libraries that are already 
+    //  in ROM.
+    e_obj = cyg_ldr_open_library_fs( (cyg_uint8*)ptr );
+    if ( e_obj == 0 )
+        return 0;
+    rc = cyg_ldr_load_sections( e_obj );
+    if ( rc != 0 )
+    {
+        cyg_ldr_free_elf_object( e_obj );
+        return 0;
+    }    
+
+    // Find the section index for the .shstrtab section. The names of the 
+    //  sections are held here, and are the only way to identify them.
+    p_shstrtab = (cyg_uint8*)cyg_ldr_section_address( e_obj, 
+                                                 e_obj->p_elfhdr->e_shstrndx );
+    if ( p_shstrtab == 0 )
+    {
+        cyg_ldr_free_elf_object( e_obj );
+        return 0;
+    }    
+
+    // .symtab section and .strtab. We have to go through the section names
+    //  to find where they are.
+    for ( i = 1; i < e_obj->p_elfhdr->e_shnum; i++ )
+    {
+        // Now look for the index of .symtab. These are the symbols needed for 
+        //  the symbol retrieval as well as relocation.
+        if ( !strcmp( p_shstrtab + e_obj->p_sechdr[i].sh_name, 
+                      ELF_STRING_symtab ) )
+        {              
+            e_obj->hdrndx_symtab = i;
+            e_obj->sections[i] = cyg_ldr_load_elf_section( e_obj, i );
+            if ( e_obj->sections[i] == 0 )
+            {
+                cyg_ldr_free_elf_object( e_obj );
+                return 0;
+            }    
+        }    
+        
+        // Load the table with the names of all the symbols. We need this
+        //  to compare the name of external references symbols against the
+        //  names in the in the CYG_HAL_TABLE provided by the user.
+        if ( !strcmp( p_shstrtab + e_obj->p_sechdr[i].sh_name, 
+                      ELF_STRING_strtab ) )
+        {              
+            e_obj->hdrndx_strtab = i;
+            e_obj->sections[i] = cyg_ldr_load_elf_section( e_obj, i );
+            if ( e_obj->sections[i] == 0 )
+            {
+                cyg_ldr_free_elf_object( e_obj );
+                return 0;
+            }    
+        }    
+    }                                              
+
+    CYG_ASSERT( e_obj->hdrndx_symtab != 0, "No symtab index found" );
+    CYG_ASSERT( e_obj->hdrndx_strtab != 0, "No strtab index found" );
+
+    // Now look for symbols in the COMMON area. The COMMON symbols are a 
+    //  special case, because the area they reside in must be sized up
+    //  and allocated separately from the other sections, which appear in
+    //  the sections header and can be read out of the library itself.
+    // Extra room in the 'sections' array has already been allocated to hold 
+    //  the pointer to the commons area.
+    common_size = cyg_ldr_find_common_size( e_obj ); 
+    if ( common_size != 0 )
+    {
+        cyg_uint32 com_shndx = e_obj->p_elfhdr->e_shnum;
+        cyg_int32  com_offset = 0;
+        
+        e_obj->sections[com_shndx] = (cyg_uint32*)cyg_ldr_malloc( common_size );
+        CYG_ASSERT( e_obj->sections[com_shndx] != 0, 
+                    "Cannot malloc() the COMMONS" );
+   
+        if ( e_obj->sections[com_shndx] == 0 )
+        {
+            cyg_ldr_free_elf_object( e_obj );
+            return 0;
+        }    
+
+        // Now find all the symbols in the SHN_COMMON area and make 
+        //  them  point to the newly allocated COM area.
+        symtab_entries = e_obj->p_sechdr[e_obj->hdrndx_symtab].sh_size / 
+                              e_obj->p_sechdr[e_obj->hdrndx_symtab].sh_entsize;
+        p_symtab = (Elf32_Sym*)e_obj->sections[e_obj->hdrndx_symtab];
+    
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
+        diag_printf( "Num   Value   Size Ndx Name\n" ); 
+#endif
+        for ( i = 1; i < symtab_entries; i++ )
+        {
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
+            cyg_uint8 *p_strtab = (cyg_uint8*)cyg_ldr_section_address( e_obj, 
+                                                        e_obj->hdrndx_strtab );
+#endif        
+            if ( p_symtab[i].st_shndx == SHN_COMMON )
+            {             
+                cyg_uint32 boundary = p_symtab[i].st_value - 1;
+                // Calculate the next byte boundary.
+                com_offset = ( com_offset + boundary ) & ~boundary;
+                p_symtab[i].st_shndx = com_shndx;
+                p_symtab[i].st_value = com_offset;
+                com_offset += p_symtab[i].st_size;
+            }
+    
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
+            diag_printf( "%03d  %08X %04X %03d %s\n", 
+                         i, 
+                         p_symtab[i].st_value,
+                         p_symtab[i].st_size,
+                         p_symtab[i].st_shndx,
+                         p_strtab + p_symtab[i].st_name );
+#endif        
+        }    
+    }
+
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
+    cyg_ldr_print_section_data( e_obj );
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
+    cyg_ldr_print_symbol_names( e_obj );
+#endif    
+#endif    
+
+    for ( i = 1; i < e_obj->p_elfhdr->e_shnum; i++ )
+    {
+        // Find all the '.rel' or '.rela' sections and relocate them.
+        if ( ( e_obj->p_sechdr[i].sh_type == SHT_REL ) ||
+                                  ( e_obj->p_sechdr[i].sh_type == SHT_RELA ) )
+        {
+            // Load and relocate the section.
+            rc = cyg_ldr_relocate_section( e_obj, i );
+            if ( rc < 0 )
+            { 
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
+                ELFDEBUG( "Relocation unsuccessful\n" );
+#endif
+                cyg_ldr_free_elf_object( e_obj );
+                return 0;
+            }    
+        }    
+    }    
+
+    // Synch up the caches before calling any function in the library.
+    cyg_ldr_flush_cache();
+
+    // Run the library initialization code.
+    fn = cyg_ldr_find_symbol( e_obj, "library_open" );
+    if ( fn != 0 )
+        fn();
+    return ((void*)e_obj);
+}
+
+cyg_uint8
+*cyg_ldr_error( void )
+{
+    cyg_uint8* p = cyg_ldr_last_error;
+    cyg_ldr_last_error = NULL;
+    return p;
+}
+
+void cyg_ldr_close_library( void* handle )
+{
+    void (*fn)(void);
+
+    PELF_OBJECT p = (PELF_OBJECT)handle;
+    fn = cyg_ldr_find_symbol( p, "library_close" );
+    if ( fn != 0 )
+        fn();
+
+    cyg_ldr_free_elf_object( p );
+    p = 0;
+}
+
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/src/relocate_ppc.c
@@ -0,0 +1,119 @@
+/* =================================================================
+ *
+ *      relocate_ppc.c
+ *
+ *      Relocation types for the PowerPC processor.
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ * 
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+#include <cyg/infra/diag.h>     // For diagnostic printing.
+#include <pkgconf/io_fileio.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_io.h>
+
+#include <pkgconf/objloader.h>
+#include <cyg/objloader/elf.h>
+#include <cyg/objloader/objelf.h>
+
+#ifdef CYGPKG_HAL_POWERPC
+void
+cyg_ldr_flush_cache( void )
+{
+    HAL_DCACHE_SYNC();
+    HAL_ICACHE_SYNC();
+}
+
+// in:
+// 
+// sym_type  Type of relocation to apply,
+// mem       Address in memory to modify (relocate).
+// sym_value 
+cyg_int32 
+cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value )
+{
+    cyg_int32  rel_offset, i;
+
+    // PPC uses rela, so we have to add the addend.
+    switch( sym_type )
+    {
+    case R_PPC_ADDR16_HA:
+        HAL_WRITE_UINT16( mem, _ha_( sym_value ) );
+        return 0;
+    case R_PPC_ADDR16_HI:
+        HAL_WRITE_UINT16( mem, _hi_( sym_value ) );
+        return 0;
+    case R_PPC_ADDR16_LO:
+        HAL_WRITE_UINT16( mem, _lo_( sym_value ) );
+        return 0;
+    case R_PPC_REL24:
+        // Now it is time to seek the destination address of the call.
+        // We need to do something in case the user jumps more than 16MB.
+        rel_offset = ( sym_value - mem ) & 0x03FFFFFC; 
+        HAL_READ_UINT32( mem, i );
+        i &= 0xFC000003;
+        HAL_WRITE_UINT32( mem, rel_offset | i );
+        return 0;
+    case R_PPC_REL32:
+        HAL_WRITE_UINT32( mem, ( sym_value - mem ) );
+        return 0;
+    case R_PPC_ADDR32:
+        HAL_WRITE_UINT32( mem, sym_value );
+        return 0;
+    default:
+        ELFDEBUG( "FIXME: Unknown relocation value!!!\n" );
+        return -1;
+    }
+}
+#endif // CYGPKG_HAL_POWERPC
+
+
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/tests/library/hello.c
@@ -0,0 +1,128 @@
+/* =================================================================
+ *
+ *      hello.c
+ *
+ *      Sample library to test the object loader
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ * 
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+#include <cyg/kernel/kapi.h>    // Kernel API.
+#include <cyg/infra/diag.h>     // For diagnostic printing.
+
+cyg_sem_t sem_signal_thread;
+int thread_a_count;
+
+void weak_function( void ) CYGBLD_ATTRIB_WEAK;
+void weak_function( void )
+{
+    // Store the data value passed in for this thread.
+    diag_printf( "This is the library function\n" );
+}
+
+void library_open( void )
+{
+    // Initialize the count for thread a.
+    thread_a_count = 0;
+
+	// Initialize the semaphore with a count of zero,
+	// prior to creating the threads.
+	cyg_semaphore_init( &sem_signal_thread, 0 );
+    diag_printf( "Library initialized...\n" );
+}
+
+void library_close( void )
+{
+    diag_printf( "Ciao...\n" );
+}
+
+void print_message( void )
+{
+    diag_printf( "Printing a silly message...\n" );
+}
+
+// Thread A - signals thread B via semaphore.
+void thread_a( cyg_addrword_t data )
+{
+    // Store the data value passed in for this thread.
+    int msg = (int)data;
+
+    while( 1 )
+    {
+        // Increment the thread a count.
+        thread_a_count++;
+
+
+        // Send out a message to the diagnostic port.
+        diag_printf( "Thread A, count: %d  message: %d\n", thread_a_count, msg );
+
+        // Delay for 1 second.
+        cyg_thread_delay( 100 );
+
+        // Signal thread B using the semaphore.
+        cyg_semaphore_post( &sem_signal_thread );
+    }
+}
+
+// Thread B - waits for semaphore signal from thread A.
+void thread_b( cyg_addrword_t data )
+{
+    // Store the data value passed in for this thread.
+    int msg = (int)data;
+
+    while( 1 )
+    {
+
+        // Signal thread B using the semaphore.
+        cyg_semaphore_wait( &sem_signal_thread );
+
+        // Send out a message to the diagnostic port.
+        diag_printf( "Thread B, message: %d\n", msg );
+    }
+}
+
new file mode 100644
--- /dev/null
+++ b/packages/services/objloader/current/tests/test_mods.c
@@ -0,0 +1,207 @@
+/* =================================================================
+ *
+ *      test_mods.c
+ *
+ *      Test program for the object loader.
+ *
+ * ================================================================= 
+ * ####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating
+ * System.
+ * Copyright (C) 2005 eCosCentric Ltd.
+ * 
+ * eCos is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 or (at your option)
+ * any later version.
+ * 
+ * eCos is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with eCos; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * As a special exception, if other files instantiate templates or
+ * use macros or inline functions from this file, or you compile this
+ * file and link it with other works to produce a work based on this
+ * file, this file does not by itself cause the resulting work to be
+ * covered by the GNU General Public License. However the source code
+ * for this file must still be made available in accordance with
+ * section (3) of the GNU General Public License.
+ * 
+ * This exception does not invalidate any other reasons why a work
+ * based on this file might be covered by the GNU General Public
+ * License.
+ *
+ * -------------------------------------------
+ * ####ECOSGPLCOPYRIGHTEND####
+ * =================================================================
+ * #####DESCRIPTIONBEGIN####
+ * 
+ *  Author(s):    atonizzo@lycos.com
+ *  Date:         2005-05-13
+ *  Purpose:      
+ *  Description:  
+ *               
+ * ####DESCRIPTIONEND####
+ * 
+ * =================================================================
+ */
+
+#include <cyg/kernel/kapi.h>    // Kernel API.
+#include <cyg/infra/diag.h>     // For diagnostic printing.
+#include <pkgconf/io_fileio.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <dirent.h>
+#include <stdio.h>
+
+#include <cyg/fileio/fileio.h>
+#include <cyg/objloader/elf.h>
+#include <cyg/objloader/objelf.h>
+
+#define THREAD_STACK_SIZE   8192
+#define THREAD_PRIORITY     12
+
+cyg_uint8 thread_a_stack[THREAD_STACK_SIZE] __attribute__((__aligned__ (16)));
+cyg_uint8 thread_b_stack[THREAD_STACK_SIZE] __attribute__((__aligned__ (16)));
+
+cyg_thread thread_a_obj;
+cyg_thread thread_b_obj;
+cyg_handle_t thread_a_hdl;
+cyg_handle_t thread_b_hdl;
+
+#define SHOW_RESULT( _fn, _res ) \
+diag_printf("<FAIL>: " #_fn "() returned %d %s\n", _res, _res<0?strerror(errno):"");
+
+void weak_function( void )
+{
+    // Store the data value passed in for this thread.
+    diag_printf( "This is the application function\n" );
+}
+
+void (*thread_a)( cyg_addrword_t );
+void (*thread_b)( cyg_addrword_t );
+
+// This is the main starting point for our example application.
+void cyg_user_start( void )
+{
+    int err;
+    void* lib_handle;
+    void (*fn)( void );
+    
+    // It wouldn't be much of a basic example if some
+    // kind of hello message wasn't output.
+    diag_printf( "Hello eCos World!!!\n\n" );
+
+    err = mount( "/dev/disk0/1", "/", "fatfs" );
+    if( err < 0 ) 
+        SHOW_RESULT( mount, err );
+
+    err = chdir( "/" );
+    if( err < 0 ) 
+        SHOW_RESULT( chdir, err );
+
+    lib_handle = cyg_ldr_open_library( (CYG_ADDRWORD)"/hello.o", 0 );
+//    cyg_ldr_print_symbol_names( lib_handle );
+//    cyg_ldr_print_rel_names( lib_handle );
+    fn = cyg_ldr_find_symbol( lib_handle, "print_message" );
+    fn();
+    fn = cyg_ldr_find_symbol( lib_handle, "weak_function" );
+    fn();
+
+    thread_a = cyg_ldr_find_symbol( lib_handle, "thread_a" );
+    thread_b = cyg_ldr_find_symbol( lib_handle, "thread_b" );
+
+   // Create our two threads.
+    cyg_thread_create( THREAD_PRIORITY,
+                       thread_a,
+                       (cyg_addrword_t) 75,
+                       "Thread A",
+                       (void *)thread_a_stack,
+                       THREAD_STACK_SIZE,
+                       &thread_a_hdl,
+                       &thread_a_obj );
+
+    cyg_thread_create( THREAD_PRIORITY + 1,
+                       thread_b,
+                       (cyg_addrword_t) 68,
+                       "Thread B",
+                       (void *)thread_b_stack,
+                       THREAD_STACK_SIZE,
+                       &thread_b_hdl,
+                       &thread_b_obj );
+
+    // Resume the threads so they start when the scheduler begins.
+    cyg_thread_resume( thread_a_hdl );
+    cyg_thread_resume( thread_b_hdl );
+}
+
+// -----------------------------------------------------------------------------
+// External symbols.
+// -----------------------------------------------------------------------------
+
+// eCos semaphores
+CYG_LDR_TABLE_ENTRY( cyg_thread_delay_entry,
+                     "cyg_thread_delay",   
+                     cyg_thread_delay );
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_wait_entry,
+                     "cyg_semaphore_wait", 
+                     cyg_semaphore_wait );
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_init_entry,
+                     "cyg_semaphore_init", 
+                     cyg_semaphore_init );
+CYG_LDR_TABLE_ENTRY( cyg_semaphore_post_entry,
+                     "cyg_semaphore_post", 
+                     cyg_semaphore_post );
+
+// eCos mailboxes
+CYG_LDR_TABLE_ENTRY( cyg_mbox_put_entry, "cyg_mbox_put", cyg_mbox_put );
+
+// eCos Flags
+CYG_LDR_TABLE_ENTRY( cyg_flag_poll_entry, "cyg_flag_poll", cyg_flag_poll );
+CYG_LDR_TABLE_ENTRY( cyg_flag_setbits_entry, 
+                     "cyg_flag_setbits", 
+                     cyg_flag_setbits );
+
+// eCos misc
+CYG_LDR_TABLE_ENTRY( hal_delay_us_entry, "hal_delay_us", hal_delay_us );
+CYG_LDR_TABLE_ENTRY( cyg_assert_msg_entry, "cyg_assert_msg", cyg_assert_msg );
+CYG_LDR_TABLE_ENTRY( cyg_assert_fail_entry, 
+                     "cyg_assert_fail", 
+                     cyg_assert_fail );
+
+// memory
+CYG_LDR_TABLE_ENTRY( memcpy_entry, "memcpy", memcpy );
+CYG_LDR_TABLE_ENTRY( memset_entry, "memset", memset );
+CYG_LDR_TABLE_ENTRY( memcmp_entry, "memcmp", memcmp );
+CYG_LDR_TABLE_ENTRY( malloc_entry, "malloc", malloc );
+CYG_LDR_TABLE_ENTRY( free_entry,   "free",   free );
+
+// Strings                     
+CYG_LDR_TABLE_ENTRY( strcpy_entry,  "strcpy",  strcpy );
+CYG_LDR_TABLE_ENTRY( strcat_entry,  "strcat",  strcat );
+CYG_LDR_TABLE_ENTRY( sprintf_entry, "sprintf", sprintf );
+CYG_LDR_TABLE_ENTRY( strlen_entry,  "strlen",  strlen );
+CYG_LDR_TABLE_ENTRY( strcmp_entry,  "strcmp",  strcmp );
+CYG_LDR_TABLE_ENTRY( strncmp_entry, "strncmp", strncmp );
+
+// files
+CYG_LDR_TABLE_ENTRY( fopen_entry,  "fopen",  fopen );
+CYG_LDR_TABLE_ENTRY( fread_entry,  "fread",  fread );
+CYG_LDR_TABLE_ENTRY( fclose_entry, "fclose", fclose );
+CYG_LDR_TABLE_ENTRY( fseek_entry,  "fseek",  fseek );
+CYG_LDR_TABLE_ENTRY( stat_entry,   "stat",   stat );
+
+// Diagnostic printout
+CYG_LDR_TABLE_ENTRY( diag_printf_entry, "diag_printf", diag_printf );
+
+CYG_LDR_TABLE_ENTRY( weak_function_entry, "weak_function", weak_function );