comparison packages/services/objloader/current/src/objloader.c @ 2890:f8dd12428f1d

* 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.
author jld
date Fri, 03 Jul 2009 14:49:44 +0000
parents 74dbf4c3f2e1
children 7cbaadc92c67
comparison
equal deleted inserted replaced
2889:8bd21cd19d19 2890:f8dd12428f1d
6 * 6 *
7 * ================================================================= 7 * =================================================================
8 * ####ECOSGPLCOPYRIGHTBEGIN#### 8 * ####ECOSGPLCOPYRIGHTBEGIN####
9 * ------------------------------------------- 9 * -------------------------------------------
10 * This file is part of eCos, the Embedded Configurable Operating System. 10 * This file is part of eCos, the Embedded Configurable Operating System.
11 * Copyright (C) 2005 Free Software Foundation, Inc. 11 * Copyright (C) 2005, 2008 Free Software Foundation, Inc.
12 * 12 *
13 * eCos is free software; you can redistribute it and/or modify it under 13 * eCos is free software; you can redistribute it and/or modify it under
14 * the terms of the GNU General Public License as published by the Free 14 * the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 or (at your option) any later 15 * Software Foundation; either version 2 or (at your option) any later
16 * version. 16 * version.
58 #include <pkgconf/objloader.h> 58 #include <pkgconf/objloader.h>
59 59
60 #include <cyg/objloader/elf.h> 60 #include <cyg/objloader/elf.h>
61 #include <cyg/objloader/objelf.h> 61 #include <cyg/objloader/objelf.h>
62 #include <cyg/objloader/loader_fs.h> 62 #include <cyg/objloader/loader_fs.h>
63 #include <cyg/objloader/loader_memory.h>
63 64
64 char *cyg_ldr_last_error; 65 char *cyg_ldr_last_error;
65 66
66 void *cyg_ldr_malloc(size_t) CYGBLD_ATTRIB_WEAK; 67 void *cyg_ldr_malloc(size_t) CYGBLD_ATTRIB_WEAK;
67 void 68 void
129 common_size = (common_size + boundary) & ~boundary; 130 common_size = (common_size + boundary) & ~boundary;
130 common_size += p_symtab[i].st_size; 131 common_size += p_symtab[i].st_size;
131 } 132 }
132 133
133 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 134 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
134 diag_printf("common_size = %d\n", common_size); 135 diag_printf("common_size = %d\n\n", common_size);
135 #endif 136 #endif
136 return common_size; 137 return common_size;
137 } 138 }
138 139
139 // Allocates memory and loads the contents of a specific ELF section. 140 // Allocates memory and loads the contents of a specific ELF section.
159 cyg_uint32 160 cyg_uint32
160 *cyg_ldr_section_address(PELF_OBJECT p, cyg_uint32 idx) 161 *cyg_ldr_section_address(PELF_OBJECT p, cyg_uint32 idx)
161 { 162 {
162 if (p->sections[idx] == 0) 163 if (p->sections[idx] == 0)
163 p->sections[idx] = cyg_ldr_load_elf_section(p, idx); 164 p->sections[idx] = cyg_ldr_load_elf_section(p, idx);
164
165 return p->sections[idx]; 165 return p->sections[idx];
166 } 166 }
167 167
168 void 168 void
169 *cyg_ldr_find_symbol(void* handle, char* sym_name) 169 *cyg_ldr_find_symbol(void* handle, char* sym_name)
178 178
179 for (i = 0; i < symtab_entries; i++) 179 for (i = 0; i < symtab_entries; i++)
180 { 180 {
181 char* tmp2 = p_strtab + p_symtab[i].st_name; 181 char* tmp2 = p_strtab + p_symtab[i].st_name;
182 if (!strcmp(tmp2, sym_name)) 182 if (!strcmp(tmp2, sym_name))
183 return cyg_ldr_symbol_address(p, i); 183 {
184 void *const funcPtr = cyg_ldr_symbol_address(p, i);
185
186 // Synch up the caches before calling any function in the library.
187 cyg_ldr_flush_cache();
188 return funcPtr;
189 }
184 } 190 }
185 191
186 // Symbol not found. 192 // Symbol not found.
187 cyg_ldr_last_error = "SYMBOL NOT FOUND"; 193 cyg_ldr_last_error = "SYMBOL NOT FOUND";
188 return 0; 194 return 0;
200 206
201 // We only work with relocatable files. No dynamic linking. 207 // We only work with relocatable files. No dynamic linking.
202 if (p->p_elfhdr->e_type != ET_REL) 208 if (p->p_elfhdr->e_type != ET_REL)
203 return "NOT RELOCATABLE"; 209 return "NOT RELOCATABLE";
204 210
211 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
212 diag_printf("Machine type: %d\n", p->p_elfhdr->e_machine);
213 #endif
214
205 // These #defines are sitting in the hal. 215 // These #defines are sitting in the hal.
206 if (p->p_elfhdr->e_machine != ELF_ARCH_MACHINE_TYPE) 216 if (p->p_elfhdr->e_machine != ELF_ARCH_MACHINE_TYPE)
217 {
207 return "INVALID ARCHITECTURE"; 218 return "INVALID ARCHITECTURE";
219 }
208 220
209 if (p->p_elfhdr->e_ident[EI_DATA] != ELF_ARCH_ENDIANNESS) 221 if (p->p_elfhdr->e_ident[EI_DATA] != ELF_ARCH_ENDIANNESS)
210 return "INVALID ENDIAN"; 222 return "INVALID ENDIAN";
211 return 0; } 223 return 0;
224 }
212 225
213 // Load only the ELF header and the sections header. These are the only 226 // Load only the ELF header and the sections header. These are the only
214 // sections loaded during library initialization. All the other sections 227 // sections loaded during library initialization. All the other sections
215 // will be loaded on demand when needed during the relocation process and, 228 // will be loaded on demand when needed during the relocation process and,
216 // when possible, dumped after use. 229 // when possible, dumped after use.
271 PELF_OBJECT 284 PELF_OBJECT
272 cyg_ldr_open_library(CYG_ADDRWORD ptr, cyg_int32 mode) 285 cyg_ldr_open_library(CYG_ADDRWORD ptr, cyg_int32 mode)
273 { 286 {
274 int (*fn)(void); 287 int (*fn)(void);
275 int i; 288 int i;
289 PELF_OBJECT e_obj = (PELF_OBJECT)0;
276 290
277 // In the future there might be a switch() (against 'mode') that calls an 291 // In the future there might be a switch() (against 'mode') that calls an
278 // open function other than cyg_ldr_open_library_fs(). These function 292 // open function other than cyg_ldr_open_library_fs(). These function
279 // fetch and open a library using ftp, http or libraries that are already 293 // fetch and open a library using ftp, http or libraries that are already
280 // in ROM. 294 // in ROM.
281 PELF_OBJECT e_obj = cyg_ldr_open_library_fs((char*)ptr); 295 switch (mode)
296 {
297 #if defined(CYGOPT_SERVICES_OBJLOADER_LOADERS_FS)
298 case CYG_LDR_MODE_FILESYSTEM:
299 // Here the prt is a path to the library to load.
300 e_obj = cyg_ldr_open_library_fs((char*)ptr);
301 break;
302 #endif
303 #if defined(CYGOPT_SERVICES_OBJLOADER_LOADERS_MEMORY)
304 case CYG_LDR_MODE_MEMORY:
305 // In this case the ptr pointer is the location in ROM memory where the
306 // library has been statically stored.
307 e_obj = cyg_ldr_open_library_memory(ptr);
308 break;
309 #endif
310 default:
311 break;
312 }
313
282 if (e_obj == 0) 314 if (e_obj == 0)
283 return 0; 315 return 0;
284 int rc = cyg_ldr_load_sections(e_obj); 316 int rc = cyg_ldr_load_sections(e_obj);
285 if (rc != 0) 317 if (rc != 0)
286 { 318 {
359 // them point to the newly allocated COM area. 391 // them point to the newly allocated COM area.
360 int symtab_entries = e_obj->p_sechdr[e_obj->hdrndx_symtab].sh_size / 392 int symtab_entries = e_obj->p_sechdr[e_obj->hdrndx_symtab].sh_size /
361 e_obj->p_sechdr[e_obj->hdrndx_symtab].sh_entsize; 393 e_obj->p_sechdr[e_obj->hdrndx_symtab].sh_entsize;
362 Elf32_Sym *p_symtab = (Elf32_Sym*)e_obj->sections[e_obj->hdrndx_symtab]; 394 Elf32_Sym *p_symtab = (Elf32_Sym*)e_obj->sections[e_obj->hdrndx_symtab];
363 395
364 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
365 diag_printf("Num Value Size Ndx Name\n");
366 #endif
367 for (i = 1; i < symtab_entries; i++) 396 for (i = 1; i < symtab_entries; i++)
368 { 397 {
369 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
370 cyg_uint8 *p_strtab = (cyg_uint8*)cyg_ldr_section_address(e_obj,
371 e_obj->hdrndx_strtab);
372 #endif
373 if (p_symtab[i].st_shndx == SHN_COMMON) 398 if (p_symtab[i].st_shndx == SHN_COMMON)
374 { 399 {
375 cyg_uint32 boundary = p_symtab[i].st_value - 1; 400 cyg_uint32 boundary = p_symtab[i].st_value - 1;
376 // Calculate the next byte boundary. 401 // Calculate the next byte boundary.
377 com_offset = (com_offset + boundary) & ~boundary; 402 com_offset = (com_offset + boundary) & ~boundary;
378 p_symtab[i].st_shndx = com_shndx; 403 p_symtab[i].st_shndx = com_shndx;
379 p_symtab[i].st_value = com_offset; 404 p_symtab[i].st_value = com_offset;
380 com_offset += p_symtab[i].st_size; 405 com_offset += p_symtab[i].st_size;
381 } 406 }
382 407 }
383 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 408 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
384 diag_printf("%03d %08X %04X %03d %s\n", 409 diag_printf("\n");
385 i,
386 p_symtab[i].st_value,
387 p_symtab[i].st_size,
388 p_symtab[i].st_shndx,
389 p_strtab + p_symtab[i].st_name);
390 #endif 410 #endif
391 }
392 } 411 }
393 412
394 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 413 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
395 cyg_ldr_print_section_data(e_obj); 414 cyg_ldr_print_section_data(e_obj);
396 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 415 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
406 { 425 {
407 // Load and relocate the section. 426 // Load and relocate the section.
408 rc = cyg_ldr_relocate_section(e_obj, i); 427 rc = cyg_ldr_relocate_section(e_obj, i);
409 if (rc < 0) 428 if (rc < 0)
410 { 429 {
411 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 430 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
412 ELFDEBUG("Relocation unsuccessful\n"); 431 diag_printf("Relocation unsuccessful\n");
413 #endif 432 #endif
414 cyg_ldr_free_elf_object(e_obj); 433 cyg_ldr_free_elf_object(e_obj);
415 return 0; 434 return 0;
416 } 435 }
417 } 436 }