# HG changeset patch # User jld # Date 1246632584 0 # Node ID f8dd12428f1de24e1eaec44c85aea3b1c707503b # Parent 8bd21cd19d192f8b6cf7dfd60a0d8890033e84dd * cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c, src/relocate_arm.c: Eliminate dependency on CYGPKG_IO_FILEIO when the filesystem loader is not required. * src/relocate_arm.c : Added relocation software for the ARM . * src/relocate_i386.c : Added a structure containing the relocation names for every architecture. Only used (and compiled in) for pretty printing. * src/relocate_ppc.c : * include/relocate_arm.h : New header file for src/relocate_arm.c * cdl/objloader.cdl: Added the option to relocate for the ARM. * src/objloader.c : * src/objelf.c : Erased some redundant debug printout and improved the readability of the rest. * src/loader_memory.c : Added the code to allow the objloader package to load libraries from ROM memory, instead from a file system. The various sections of the library are the copied from ROM to RAM and relocated. * include/loader_memory.h : New header file for src/loader_memory.c * src/objloader.c : Added a line to include the loader_memory header file and code to flush the cache when calling cyg_ldr_find_symbol(). * cdl/objloader.cdl: Added one check boxe for each of the supported ways of loading libraries (two for now) so that the user can compile out the loading methods not used. diff --git a/packages/services/objloader/current/ChangeLog b/packages/services/objloader/current/ChangeLog --- a/packages/services/objloader/current/ChangeLog +++ b/packages/services/objloader/current/ChangeLog @@ -1,9 +1,36 @@ +2009-07-03 John Dallaway + + * cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c, + src/relocate_arm.c: Eliminate dependency on CYGPKG_IO_FILEIO when + the filesystem loader is not required. + 2009-02-07 John Dallaway - * cdl/objloader.tcl: Pass file2c.tcl to tclsh directly. + * cdl/objloader.cdl: Pass file2c.tcl to tclsh directly. + +2008-12-01 Anthony Tonizzo + * src/relocate_arm.c : Added relocation software for the ARM . + * src/relocate_i386.c : Added a structure containing the relocation names + for every architecture. Only used (and compiled in) for pretty printing. + * src/relocate_ppc.c : + * include/relocate_arm.h : New header file for src/relocate_arm.c + * cdl/objloader.cdl: Added the option to relocate for the ARM. + * src/objloader.c : + * src/objelf.c : Erased some redundant debug printout and improved the + readability of the rest. + +2008-12-01 Gernot Zankl + * src/loader_memory.c : Added the code to allow the objloader package + to load libraries from ROM memory, instead from a file system. The various + sections of the library are the copied from ROM to RAM and relocated. + * include/loader_memory.h : New header file for src/loader_memory.c + * src/objloader.c : Added a line to include the loader_memory header + file and code to flush the cache when calling cyg_ldr_find_symbol(). + * cdl/objloader.cdl: Added one check boxe for each of the supported ways + of loading libraries (two for now) so that the user can compile out the + loading methods not used. 2006-06-27 Anthony Tonizzo - * src/loader_fs.c : Minor cosmetic and formatting changes on all files. Also got rid of some signed/unsigned comparison which did not show up using the PPC toolchain but do when compiled with gcc under the synthetic target. @@ -51,7 +78,7 @@ 2005-05-10 Anthony Tonizzo " -# } -# compile relocate_arm.c -# } + cdl_option CYGBLD_OBJLOADER_ARCHITECTURE_ARM { + display "Support loading on ARM processors" + calculated CYGPKG_HAL_ARM + implements CYGINT_SERVICES_OBJLOADER_RELOCATOR + define_proc { + puts $::cdl_header "#include " + } + compile relocate_arm.c + } } + cdl_component CYGOPT_SERVICES_OBJLOADER_LOADERS { + display "Loaders to compile" + flavor none + no_define + description "Options to select which types of loaders (e.g. from file + system, memory, http etc. to compile." + + cdl_option CYGOPT_SERVICES_OBJLOADER_LOADERS_FS { + display "Load module from file system" + flavor bool + default_value 1 + requires CYGPKG_IO_FILEIO + description "This option will compile the code required to load an + object library from a generic file system." + compile loader_fs.c + } + + cdl_option CYGOPT_SERVICES_OBJLOADER_LOADERS_MEMORY { + display "Load module from memory" + flavor bool + default_value 1 + description "This option will compile the module required to load an + object library from a ROM memory." + compile loader_memory.c + } + } + cdl_option CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL { display "Verbosity of debug output" flavor data diff --git a/packages/services/objloader/current/doc/notes.txt b/packages/services/objloader/current/doc/notes.txt --- a/packages/services/objloader/current/doc/notes.txt +++ b/packages/services/objloader/current/doc/notes.txt @@ -24,7 +24,7 @@ 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 ) +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 @@ -46,7 +46,7 @@ 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 ); +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. @@ -64,7 +64,7 @@ A relocator for a new architecture must prototype: cyg_int32 -cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value ) +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. @@ -86,21 +86,25 @@ An example of the definition for the Pow #define ELF_ARCH_MACHINE_TYPE 20 // PowerPC. #define ELF_ARCH_ENDIANNESS ELFDATA2MSB // Big Endian. -#define ELF_ARCH_RELTYPE Elf_Rela // With addend. +#define ELF_ARCH_RELTYPE Elf_Rela // With explicit 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. +The user must also provide a function with the following prototype: + +void cyg_ldr_flush_cache(void) + +tha is used 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. +An empty function can be used is caches are not available. -------------------------------------------------------------------------------- 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. +file. If a new architecture is added or a new loader is added, the CDL file +must be updated to include the architecture dependent files. -------------------------------------------------------------------------------- Test program @@ -152,5 +156,12 @@ tftp. In order to do this some functions - 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 +- The relocator for the ARM architecture only works for ARMv4T cores and + later ones. The problem arises from the fact that without the Thumb + instruction set the loader should replace every "BX Rm" in the library + with "MOV PC, Rm". This assumes that the library can find out what core it + is running on at runtime, which is not possible at the moment. Given that + ARMv4T cores are the ones used by most IC suppliers (Atmel, NXP, ST just + to name a few) it is expected that the current code will work for nearly + everyone. - diff --git a/packages/services/objloader/current/include/elf.h b/packages/services/objloader/current/include/elf.h --- a/packages/services/objloader/current/include/elf.h +++ b/packages/services/objloader/current/include/elf.h @@ -9,7 +9,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008 Free Software Foundation, Inc. * * 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 diff --git a/packages/services/objloader/current/include/loader_fs.h b/packages/services/objloader/current/include/loader_fs.h --- a/packages/services/objloader/current/include/loader_fs.h +++ b/packages/services/objloader/current/include/loader_fs.h @@ -9,7 +9,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008 Free Software Foundation, Inc. * * 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 @@ -50,9 +50,6 @@ * ================================================================= */ -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); PELF_OBJECT cyg_ldr_open_library_fs(char *); void cyg_ldr_close_library_fs(PELF_OBJECT); diff --git a/packages/services/objloader/current/include/loader_memory.h b/packages/services/objloader/current/include/loader_memory.h new file mode 100644 --- /dev/null +++ b/packages/services/objloader/current/include/loader_memory.h @@ -0,0 +1,59 @@ +#ifndef __LOADER_MEMORY_H__ +#define __LOADER_MEMORY_H__ + +/* ================================================================= + * + * loader_memory.h + * + * ================================================================= + * ####ECOSGPLCOPYRIGHTBEGIN#### + * ------------------------------------------- + * This file is part of eCos, the Embedded Configurable Operating + * System. + * Copyright (C) 2006, 2008 Free Software Foundation, Inc. + * + * 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): Gernot Zankl zankl@decomsys.com + * Date: 2006-11-21 + * Purpose: + * Description: + * + * ####DESCRIPTIONEND#### + * + * ================================================================= + */ + +PELF_OBJECT cyg_ldr_open_library_memory(CYG_ADDRWORD); +void cyg_ldr_close_library_memory(PELF_OBJECT); + +#endif // __LOADER_MEMORY_H__ diff --git a/packages/services/objloader/current/include/objelf.h b/packages/services/objloader/current/include/objelf.h --- a/packages/services/objloader/current/include/objelf.h +++ b/packages/services/objloader/current/include/objelf.h @@ -9,7 +9,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008 Free Software Foundation, Inc. * * 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 @@ -97,12 +97,6 @@ typedef struct ELF_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); diff --git a/packages/services/objloader/current/include/relocate_arm.h b/packages/services/objloader/current/include/relocate_arm.h new file mode 100644 --- /dev/null +++ b/packages/services/objloader/current/include/relocate_arm.h @@ -0,0 +1,75 @@ +#ifndef __RELOCATE_ARM_H__ +#define __RELOCATE_ARM_H__ + +/* ================================================================= + * + * relocate_arm.h + * + * Architecture dependent relocation routines for the ARM + * + * ================================================================= + * ####ECOSGPLCOPYRIGHTBEGIN#### + * ------------------------------------------- + * This file is part of eCos, the Embedded Configurable Operating System. + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * 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): Anthony Tonizzo (atonizzo@gmail.com) + * Contributors: Sergei Gavrikov (sergei.gavrikov@gmail.com) + * Date: 2008-12-01 + * Purpose: + * Description: + * + * ####DESCRIPTIONEND#### + * + * ================================================================= + */ + +#define Elf_Rel 0 +#define Elf_Rela 1 + +#define ELF_ARCH_MACHINE_TYPE 40 // ARM +#define ELF_ARCH_ENDIANNESS ELFDATA2LSB +#define ELF_ARCH_RELTYPE Elf_Rel + +#define R_ARM_PC24 1 // PC relative 26 bit branch. +#define R_ARM_ABS32 2 // Direct 32 bit. +#define R_ARM_CALL 28 // PC relative 26 bit call (EABI). +#define R_ARM_JUMP24 29 // PC relative 26 bit branch (EABI). +#define R_ARM_V4BX 40 // Fix of interworking for ARMv4 cores. + +void cyg_ldr_flush_cache(void); +cyg_int32 cyg_ldr_relocate(cyg_int32, cyg_uint32, cyg_int32); +extern char *relocation_name[]; + +#endif //__RELOCATE_ARM_H__ diff --git a/packages/services/objloader/current/include/relocate_i386.h b/packages/services/objloader/current/include/relocate_i386.h --- a/packages/services/objloader/current/include/relocate_i386.h +++ b/packages/services/objloader/current/include/relocate_i386.h @@ -11,7 +11,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008 Free Software Foundation, Inc. * * 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 @@ -64,5 +64,6 @@ void cyg_ldr_flush_cache(void); cyg_int32 cyg_ldr_relocate(cyg_int32, cyg_uint32, cyg_int32); +extern char *relocation_name[]; #endif //__RELOCATE_I386_H__ diff --git a/packages/services/objloader/current/include/relocate_ppc.h b/packages/services/objloader/current/include/relocate_ppc.h --- a/packages/services/objloader/current/include/relocate_ppc.h +++ b/packages/services/objloader/current/include/relocate_ppc.h @@ -11,7 +11,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008 Free Software Foundation, Inc. * * 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 @@ -125,5 +125,6 @@ void cyg_ldr_flush_cache( void ); cyg_int32 cyg_ldr_relocate( cyg_int32, cyg_uint32, cyg_int32 ); +extern char *relocation_name[]; #endif //__RELOCATE_PPC_H__ diff --git a/packages/services/objloader/current/src/loader_fs.c b/packages/services/objloader/current/src/loader_fs.c --- a/packages/services/objloader/current/src/loader_fs.c +++ b/packages/services/objloader/current/src/loader_fs.c @@ -8,7 +8,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008 Free Software Foundation, Inc. * * 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 @@ -62,19 +62,19 @@ #include #include -size_t +static 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 +static cyg_int32 cyg_ldr_fs_seek(PELF_OBJECT p, cyg_uint32 offs) { return fseek((FILE*)p->ptr, offs, SEEK_SET); } -cyg_int32 +static cyg_int32 cyg_ldr_fs_close(PELF_OBJECT p) { return fclose((FILE*)p->ptr); diff --git a/packages/services/objloader/current/src/loader_memory.c b/packages/services/objloader/current/src/loader_memory.c new file mode 100644 --- /dev/null +++ b/packages/services/objloader/current/src/loader_memory.c @@ -0,0 +1,147 @@ +/* ================================================================= + * + * loader_memory.c + * + * Routines to read a library from memory. + * + * ================================================================= + * ####ECOSGPLCOPYRIGHTBEGIN#### + * ------------------------------------------- + * This file is part of eCos, the Embedded Configurable Operating + * System. + * Copyright (C) 2006, 2008 Free Software Foundation, Inc. + * + * 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): Gernot Zankl zankl@decomsys.com + * Contributors: + * Date: 2006-11-21 + * Purpose: + * Description: + * + * ####DESCRIPTIONEND#### + * + * ================================================================= + */ + +#include // For diagnostic printing. +#include // CYG_ASSERT + +#include +#include + +#include +#include +#include +#include + +typedef struct +{ + CYG_ADDRWORD nBufferBase; + cyg_uint32 nOffset; +} ObjLoader_MemInfoType; + +static size_t +cyg_ldr_memory_read(PELF_OBJECT p, size_t s, size_t n, void *mem) +{ + ObjLoader_MemInfoType * const pMemInfo = (ObjLoader_MemInfoType *)p->ptr; + + cyg_uint8 * const pSource = + (cyg_uint8 *)pMemInfo->nBufferBase + pMemInfo->nOffset; + + memcpy(mem, (void*)pSource, s*n); + return n; +} + +static cyg_int32 +cyg_ldr_memory_seek(PELF_OBJECT p, cyg_uint32 offs) +{ + ObjLoader_MemInfoType * const pMemInfo = (ObjLoader_MemInfoType *)p->ptr; + pMemInfo->nOffset = offs; + return 0; +} + +static cyg_int32 +cyg_ldr_memory_close(PELF_OBJECT p) +{ + return 0; +} + +PELF_OBJECT +cyg_ldr_open_library_memory(CYG_ADDRWORD ptr) +{ + PELF_OBJECT e_obj; + ObjLoader_MemInfoType * pMemInfo; + + if (ptr == 0) + { + cyg_ldr_last_error = "ERROR INVALID POINTER"; + 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"; + return (void*)0; + } + memset(e_obj, 0, sizeof(ELF_OBJECT)); + + pMemInfo = (ObjLoader_MemInfoType *)malloc(sizeof(ObjLoader_MemInfoType)); + CYG_ASSERT(pMemInfo != 0, "Cannot malloc() pMemInfo"); + if (pMemInfo == 0) + { + cyg_ldr_last_error = "ERROR IN MALLOC"; + return (void*)0; + } + + pMemInfo->nBufferBase = ptr; + pMemInfo->nOffset = 0; + + e_obj->ptr = (CYG_ADDRWORD)pMemInfo; + e_obj->mode = CYG_LDR_MODE_MEMORY; + + // Handlers for the file system open. + e_obj->read = cyg_ldr_memory_read; + e_obj->seek = cyg_ldr_memory_seek; + e_obj->close = cyg_ldr_memory_close; + return e_obj; +} + +void +cyg_ldr_close_library_memory(PELF_OBJECT p) +{ + free((ObjLoader_MemInfoType *) p->ptr); +} + diff --git a/packages/services/objloader/current/src/objelf.c b/packages/services/objloader/current/src/objelf.c --- a/packages/services/objloader/current/src/objelf.c +++ b/packages/services/objloader/current/src/objelf.c @@ -8,7 +8,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. * * 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 @@ -51,7 +51,6 @@ */ #include // For diagnostic printing. -#include #include #include @@ -73,14 +72,16 @@ cyg_ldr_print_section_data(PELF_OBJECT p char strname[32]; char *p_strtab = (char*)p->sections[p->p_elfhdr->e_shstrndx]; - diag_printf("\n\nSection Headers:\n"); - diag_printf("[Nr] Name Addr Offset Size Info\n"); + diag_printf("Section Headers:\n"); + diag_printf("----------------------------------------------------------\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", + diag_printf("[%2d] %s %08X %08X %08X %08X\n", i, strname, p->p_sechdr[i].sh_addr, @@ -97,39 +98,22 @@ cyg_ldr_print_symbol_names(PELF_OBJECT p int i; Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab]; char *p_strtab = (char*)p->sections[p->hdrndx_strtab]; - char strname[32]; +// char strname[32]; // Total number of entries in the symbol table. int 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"); + diag_printf("Symbol Table Entries\n"); + diag_printf("----------------------------------------\n"); + diag_printf("[Nr] 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"); - } + diag_printf("[%3d] %08X %04d %5d %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); + diag_printf("\n"); } void @@ -325,8 +309,9 @@ cyg_ldr_relocate_section(PELF_OBJECT p, #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 diag_printf("Relocating section \"%s\"\n", p_shstrtab + p->p_sechdr[r_target_shndx].sh_name); + diag_printf("----------------------------------------\n"); #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 - diag_printf("Ndx Type Offset Name\"\n"); + diag_printf(" Ndx Type Offset Name\"\n"); #endif #endif @@ -348,22 +333,13 @@ cyg_ldr_relocate_section(PELF_OBJECT p, #endif cyg_uint32 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 ", + diag_printf("%5d %s %08X ", sym_index, - r_type, + relocation_name[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); @@ -377,15 +353,15 @@ cyg_ldr_relocate_section(PELF_OBJECT p, diag_printf("\n"); #endif rc = cyg_ldr_relocate(r_type, - r_target_addr + r_offset, - sym_value + r_addend); + 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); +#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 + diag_printf("Error while relocating symbol: %s\n", + p_strtab + p_symtab[sym_index].st_name); + return -1; #endif - return -1; } } diff --git a/packages/services/objloader/current/src/objloader.c b/packages/services/objloader/current/src/objloader.c --- a/packages/services/objloader/current/src/objloader.c +++ b/packages/services/objloader/current/src/objloader.c @@ -8,7 +8,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008 Free Software Foundation, Inc. * * 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 @@ -60,6 +60,7 @@ #include #include #include +#include char *cyg_ldr_last_error; @@ -131,7 +132,7 @@ cyg_ldr_find_common_size(PELF_OBJECT p) } #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 - diag_printf("common_size = %d\n", common_size); + diag_printf("common_size = %d\n\n", common_size); #endif return common_size; } @@ -161,7 +162,6 @@ cyg_uint32 { if (p->sections[idx] == 0) p->sections[idx] = cyg_ldr_load_elf_section(p, idx); - return p->sections[idx]; } @@ -180,7 +180,13 @@ void { char* tmp2 = p_strtab + p_symtab[i].st_name; if (!strcmp(tmp2, sym_name)) - return cyg_ldr_symbol_address(p, i); + { + void *const funcPtr = cyg_ldr_symbol_address(p, i); + + // Synch up the caches before calling any function in the library. + cyg_ldr_flush_cache(); + return funcPtr; + } } // Symbol not found. @@ -202,13 +208,20 @@ static char if (p->p_elfhdr->e_type != ET_REL) return "NOT RELOCATABLE"; +#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 + diag_printf("Machine type: %d\n", p->p_elfhdr->e_machine); +#endif + // 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; } + return 0; +} // Load only the ELF header and the sections header. These are the only // sections loaded during library initialization. All the other sections @@ -273,12 +286,31 @@ cyg_ldr_open_library(CYG_ADDRWORD ptr, c { int (*fn)(void); int i; + PELF_OBJECT e_obj = (PELF_OBJECT)0; // 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. - PELF_OBJECT e_obj = cyg_ldr_open_library_fs((char*)ptr); + switch (mode) + { +#if defined(CYGOPT_SERVICES_OBJLOADER_LOADERS_FS) + case CYG_LDR_MODE_FILESYSTEM: + // Here the prt is a path to the library to load. + e_obj = cyg_ldr_open_library_fs((char*)ptr); + break; +#endif +#if defined(CYGOPT_SERVICES_OBJLOADER_LOADERS_MEMORY) + case CYG_LDR_MODE_MEMORY: + // In this case the ptr pointer is the location in ROM memory where the + // library has been statically stored. + e_obj = cyg_ldr_open_library_memory(ptr); + break; +#endif + default: + break; + } + if (e_obj == 0) return 0; int rc = cyg_ldr_load_sections(e_obj); @@ -361,15 +393,8 @@ cyg_ldr_open_library(CYG_ADDRWORD ptr, c e_obj->p_sechdr[e_obj->hdrndx_symtab].sh_entsize; Elf32_Sym *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; @@ -379,16 +404,10 @@ cyg_ldr_open_library(CYG_ADDRWORD ptr, c 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); + diag_printf("\n"); #endif - } } #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 @@ -408,8 +427,8 @@ cyg_ldr_open_library(CYG_ADDRWORD ptr, c rc = cyg_ldr_relocate_section(e_obj, i); if (rc < 0) { -#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 - ELFDEBUG("Relocation unsuccessful\n"); +#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 + diag_printf("Relocation unsuccessful\n"); #endif cyg_ldr_free_elf_object(e_obj); return 0; diff --git a/packages/services/objloader/current/src/relocate_arm.c b/packages/services/objloader/current/src/relocate_arm.c new file mode 100644 --- /dev/null +++ b/packages/services/objloader/current/src/relocate_arm.c @@ -0,0 +1,133 @@ +/* ================================================================= + * + * relocate_arm.c + * + * Relocation types for the ARM processor (Little Endian). + * + * ================================================================= + * ####ECOSGPLCOPYRIGHTBEGIN#### + * ------------------------------------------- + * This file is part of eCos, the Embedded Configurable Operating System. + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * + * 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): Anthony Tonizzo (atonizzo@gmail.com) + * Contributors: Sergei Gavrikov (sergei.gavrikov@gmail.com) + * Date: 2008-12-01 + * Purpose: + * Description: + * + * ####DESCRIPTIONEND#### + * + * ================================================================= + */ + +#include // For diagnostic printing. +#include +#include +#include + +#include +#include + +#include +#include +#include + +#ifdef CYGPKG_HAL_ARM +void +cyg_ldr_flush_cache(void) +{ + HAL_DCACHE_SYNC(); + HAL_ICACHE_SYNC(); +} + +#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 +// Always 16 characters long, with blank padding is necessary, so +// the printing is pretty. If the name is longer than 16, shorten it. +// We print the relocation symbols only is +// CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL is set to 2. +char *relocation_name[] = +{ + "", "R_ARM_PC24 ", "R_ARM_ABS32 ", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "R_ARM_CALL ", "R_ARM_JUMP24 ", "", "", "", "", + "", "", "", "", "", "", "R_ARM_V4BX " +}; +#endif + +// sym_type Type of relocation to apply, +// mem Address in memory to modify (relocate). +// sym_value The value of the symbol to use for the relocation. +// The proper relocation to apply (i.e. the proper use of mem and sym_value) +// depend on the relocation to apply. The number and types of relocations +// that must be supported by any given architecture is spelled in the ELF/EABI +// guide for that architecture. +cyg_int32 +cyg_ldr_relocate(cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value) +{ + cyg_int32 offset; + volatile cyg_uint32 *mem_addr = (cyg_uint32 *)mem; + + switch(sym_type) + { + case R_ARM_ABS32: + offset = *mem_addr; + *mem_addr = offset + sym_value; + break; + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + offset = (*mem_addr & 0x00FFFFFF) << 2; + if (offset & 0x02000000) + offset -= 0x04000000; // Sign extend. + *mem_addr &= 0xff000000; // Mask off the entire offset bits. + offset = sym_value - mem + offset; // This is the new offset. + if ((offset & 0x03) || (offset >= (cyg_int32)0x04000000) || + (offset <= (cyg_int32)0xFC000000)) + return -1; + *mem_addr |= (offset >> 2) & 0x00FFFFFF; + break; + case R_ARM_V4BX: + // For now only ARMv4T and later cores (with Thumb) are supported. + break; + default: + CYG_ASSERT(0, ("FIXME: Unknown relocation value!!!\r\n")); + return -1; + } + return 0; +} + +#endif // CYGPKG_HAL_ARM + + diff --git a/packages/services/objloader/current/src/relocate_i386.c b/packages/services/objloader/current/src/relocate_i386.c --- a/packages/services/objloader/current/src/relocate_i386.c +++ b/packages/services/objloader/current/src/relocate_i386.c @@ -8,7 +8,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008 Free Software Foundation, Inc. * * 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 @@ -57,6 +57,17 @@ #include #include +#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 +// Always 16 characters long, with blank padding is necessary, so +// the printing is pretty. If the name is longer than 16, shorten it. +// We print the relocation symbols only is +// CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL is set to 2. +char *relocation_name[] = +{ + "", "R_386_32 ", "R_386_PC32 " +}; +#endif + #if defined(CYGPKG_HAL_I386) || defined(CYGPKG_HAL_SYNTH_I386) void cyg_ldr_flush_cache(void) @@ -87,7 +98,7 @@ cyg_ldr_relocate(cyg_int32 sym_type, cyg HAL_WRITE_UINT32(mem, i + sym_value - mem); return 0; default: - ELFDEBUG("FIXME: Unknown relocation value!!!\n"); + diag_printf("FIXME: Unknown relocation value!!!\n"); return -1; } } diff --git a/packages/services/objloader/current/src/relocate_ppc.c b/packages/services/objloader/current/src/relocate_ppc.c --- a/packages/services/objloader/current/src/relocate_ppc.c +++ b/packages/services/objloader/current/src/relocate_ppc.c @@ -8,7 +8,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. * * 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 @@ -50,7 +50,6 @@ */ #include // For diagnostic printing. -#include #include #include #include @@ -70,6 +69,19 @@ cyg_ldr_flush_cache(void) HAL_ICACHE_SYNC(); } +#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 +// Always 16 characters long, with blank padding is necessary, so +// the printing is pretty. If the name is longer than 16, shorten it. +// We print the relocation symbols only is +// CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL is set to 2. +char *relocation_name[] = +{ + "", "R_PPC_ADDR32 ", "", "", "R_PPC_ADDR16_LO ", "R_PPC_ADDR16_HI ", + "R_PPC_ADDR16_HA ", "", "", "", "R_PPC_REL24 ", "", "", "", "", "", + "", "", "", "", "R_PPC_REL32 " +}; +#endif + // in: // // sym_type Type of relocation to apply, diff --git a/packages/services/objloader/current/tests/test_mods.c b/packages/services/objloader/current/tests/test_mods.c --- a/packages/services/objloader/current/tests/test_mods.c +++ b/packages/services/objloader/current/tests/test_mods.c @@ -8,7 +8,7 @@ * ####ECOSGPLCOPYRIGHTBEGIN#### * ------------------------------------------- * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2005 Free Software Foundation, Inc. + * Copyright (C) 2005, 2008 Free Software Foundation, Inc. * * 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 @@ -129,7 +129,8 @@ void cyg_user_start(void) if(err < 0) SHOW_RESULT(chdir, err); - lib_handle = cyg_ldr_open_library((CYG_ADDRWORD)"/hello.o", 0); + lib_handle = cyg_ldr_open_library((CYG_ADDRWORD)"/hello.o", + CYG_LDR_MODE_FILESYSTEM); CYG_TEST_CHECK(lib_handle , "Unable to load object file to load"); fn = cyg_ldr_find_symbol(lib_handle, "print_message");