annotate packages/services/objloader/current/src/objloader.c @ 2013:8bf90d16b837

* include/objelf.h: Include hal_tables.h otherwise we get strange linker errors. * cdl/objloader.cdl: Rearranged the building of the test case. * include/relocate_i386.h (New): * src/relocate_i386.c (New): Added a relocator for i386. * src/objelf.c: Fixed various Elf_Rel vs Elf_Rela issues. * test/load_mods.c: * test/library/hello.c: Modified to make use of the eCos test infrastructure. Uses a romfs to hold the object file to be loaded.
author asl
date Fri, 08 Jul 2005 20:14:13 +0000
parents 662e1b34b811
children 6fd46febe457
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2011
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
1 /* =================================================================
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
2 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
3 * objelf.c
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
4 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
5 * An object loader for eCos
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
6 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
7 * =================================================================
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
8 * ####ECOSGPLCOPYRIGHTBEGIN####
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
9 * -------------------------------------------
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
10 * This file is part of eCos, the Embedded Configurable Operating
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
11 * System.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
12 * Copyright (C) 2005 eCosCentric Ltd.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
13 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
14 * eCos is free software; you can redistribute it and/or modify it
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
15 * under the terms of the GNU General Public License as published by
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
16 * the Free Software Foundation; either version 2 or (at your option)
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
17 * any later version.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
18 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
19 * eCos is distributed in the hope that it will be useful, but
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
22 * General Public License for more details.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
23 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
24 * You should have received a copy of the GNU General Public License
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
25 * along with eCos; if not, write to the Free Software Foundation,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
27 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
28 * As a special exception, if other files instantiate templates or
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
29 * use macros or inline functions from this file, or you compile this
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
30 * file and link it with other works to produce a work based on this
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
31 * file, this file does not by itself cause the resulting work to be
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
32 * covered by the GNU General Public License. However the source code
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
33 * for this file must still be made available in accordance with
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
34 * section (3) of the GNU General Public License.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
35 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
36 * This exception does not invalidate any other reasons why a work
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
37 * based on this file might be covered by the GNU General Public
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
38 * License.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
39 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
40 * -------------------------------------------
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
41 * ####ECOSGPLCOPYRIGHTEND####
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
42 * =================================================================
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
43 * #####DESCRIPTIONBEGIN####
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
44 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
45 * Author(s): atonizzo@lycos.com
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
46 * Contributors: nickg@ecoscentric.com
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
47 * Date: 2005-05-13
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
48 * Purpose:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
49 * Description:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
50 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
51 * ####DESCRIPTIONEND####
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
52 *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
53 * =================================================================
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
54 */
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
55
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
56 #include <cyg/infra/diag.h> // For diagnostic printing.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
57 #include <cyg/infra/cyg_ass.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
58 #include <stdlib.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
59 #include <string.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
60
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
61 #include <pkgconf/objloader.h>
2013
8bf90d16b837 * include/objelf.h: Include hal_tables.h otherwise we get strange
asl
parents: 2011
diff changeset
62
2011
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
63 #include <cyg/objloader/elf.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
64 #include <cyg/objloader/objelf.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
65 #include <cyg/objloader/loader_fs.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
66
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
67 cyg_uint8 *cyg_ldr_last_error;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
68
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
69 void *cyg_ldr_malloc( size_t ) CYGBLD_ATTRIB_WEAK;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
70 void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
71 *cyg_ldr_malloc( size_t s )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
72 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
73 return malloc( s );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
74 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
75
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
76 void cyg_ldr_free( void * ) CYGBLD_ATTRIB_WEAK;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
77 void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
78 cyg_ldr_free( void *s )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
79 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
80 free( s );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
81 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
82
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
83 void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
84 cyg_ldr_delete_elf_section( PELF_OBJECT p, cyg_uint32 idx )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
85 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
86 cyg_ldr_free( p->sections[idx] );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
87 p->sections[idx] = 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
88 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
89
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
90 // Frees all the memory allocated for a particular ELF object. Also calls
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
91 // the close() function to close files or sockets, and finally frees up
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
92 // the ELF object altogether.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
93 static void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
94 cyg_ldr_free_elf_object( PELF_OBJECT p )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
95 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
96 cyg_int32 i;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
97
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
98 for ( i = 0; i < p->p_elfhdr->e_shnum + 1; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
99 if ( p->sections[i] )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
100 cyg_ldr_delete_elf_section( p, i );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
101
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
102 if ( p->sections != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
103 cyg_ldr_free( p->sections );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
104
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
105 if ( p->p_sechdr != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
106 cyg_ldr_free( p->p_sechdr );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
107
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
108 if ( p->p_elfhdr != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
109 cyg_ldr_free( p->p_elfhdr );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
110
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
111 p->close( p );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
112 cyg_ldr_free( p );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
113 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
114
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
115 static cyg_uint32
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
116 cyg_ldr_find_common_size( PELF_OBJECT p )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
117 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
118 cyg_int32 i, symtab_entries, common_size = 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
119 Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
120
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
121 // Total number of entries in the symbol table.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
122 symtab_entries = p->p_sechdr[p->hdrndx_symtab].sh_size /
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
123 p->p_sechdr[p->hdrndx_symtab].sh_entsize;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
124 for ( i = 1; i < symtab_entries; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
125 if ( p_symtab[i].st_shndx == SHN_COMMON )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
126 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
127 // In the case of an SHN_COMMON symbol the st_value field holds
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
128 // alignment constraints.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
129 cyg_uint32 boundary = p_symtab[i].st_value - 1;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
130
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
131 // Calculate the next byte boundary.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
132 common_size = ( common_size + boundary ) & ~boundary;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
133 common_size += p_symtab[i].st_size;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
134 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
135
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
136 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
137 diag_printf( "common_size = %d\n", common_size );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
138 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
139 return common_size;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
140 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
141
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
142 // Allocates memory and loads the contents of a specific ELF section.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
143 // Returns the address of the newly allocated memory, of 0 for any error.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
144 cyg_int32
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
145 *cyg_ldr_load_elf_section( PELF_OBJECT p, cyg_uint32 idx )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
146 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
147 cyg_uint32 *addr;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
148
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
149 addr = cyg_ldr_malloc( p->p_sechdr[idx].sh_size );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
150 CYG_ASSERT( addr != 0, "Cannot malloc() section" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
151 if ( addr == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
152 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
153 cyg_ldr_last_error = "ERROR IN MALLOC";
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
154 return (void*)0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
155 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
156 p->seek( p, p->p_sechdr[idx].sh_offset );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
157 p->read( p, sizeof( char ), p->p_sechdr[idx].sh_size, addr );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
158 return addr;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
159 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
160
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
161 // Returns the starting address of a section. If the section is not already
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
162 // loaded in memory, area for it will be allocated and the section will be
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
163 // loaded.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
164 cyg_int32
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
165 *cyg_ldr_section_address( PELF_OBJECT p, cyg_uint32 idx )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
166 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
167 if ( p->sections[idx] == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
168 p->sections[idx] = cyg_ldr_load_elf_section( p, idx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
169
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
170 return p->sections[idx];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
171 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
172
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
173 void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
174 *cyg_ldr_find_symbol( void* handle, cyg_uint8* sym_name )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
175 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
176 PELF_OBJECT p = (PELF_OBJECT)handle;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
177 cyg_uint8* tmp2;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
178 cyg_int32 i, symtab_entries;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
179 cyg_uint8 *p_strtab = (cyg_uint8*)p->sections[p->hdrndx_strtab];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
180 Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
181
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
182 symtab_entries = p->p_sechdr[p->hdrndx_symtab].sh_size /
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
183 p->p_sechdr[p->hdrndx_symtab].sh_entsize;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
184
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
185 for ( i = 0; i < symtab_entries; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
186 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
187 tmp2 = p_strtab + p_symtab[i].st_name;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
188 if ( !strcmp( tmp2, sym_name ) )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
189 return cyg_ldr_symbol_address( p, i );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
190 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
191
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
192 // Symbol not found.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
193 cyg_ldr_last_error = "SYMBOL NOT FOUND";
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
194 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
195 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
196
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
197 static cyg_uint8
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
198 *cyg_ldr_sanity_check( PELF_OBJECT p )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
199 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
200 if ( ( p->p_elfhdr->e_ident[EI_MAG0] != ELFMAG0 ) ||
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
201 ( p->p_elfhdr->e_ident[EI_MAG1] != ELFMAG1 ) ||
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
202 ( p->p_elfhdr->e_ident[EI_MAG2] != ELFMAG2 ) ||
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
203 ( p->p_elfhdr->e_ident[EI_MAG3] != ELFMAG3 ) ||
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
204 ( p->p_elfhdr->e_ident[EI_CLASS] != ELFCLASS32 ) )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
205 return "INVALID ELF HEADER";
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
206
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
207 // We only work with relocatable files. No dynamic linking.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
208 if ( p->p_elfhdr->e_type != ET_REL )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
209 return "NOT RELOCATABLE";
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
210
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
211 // These #defines are sitting in the hal.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
212 if ( p->p_elfhdr->e_machine != ELF_ARCH_MACHINE_TYPE )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
213 return "INVALID ARCHITECTURE";
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
214
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
215 if ( p->p_elfhdr->e_ident[EI_DATA] != ELF_ARCH_ENDIANNESS )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
216 return "INVALID ENDIAN";
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
217 return 0; }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
218
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
219 // Load only the ELF header and the sections header. These are the only
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
220 // sections loaded during library initialization. All the other sections
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
221 // will be loaded on demand when needed during the relocation process and,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
222 // when possible, dumped after use.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
223 static cyg_int32
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
224 cyg_ldr_load_sections( PELF_OBJECT p )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
225 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
226 cyg_uint8 *error_string;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
227 cyg_int32 idx;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
228
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
229 // Load the ELF header.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
230 p->p_elfhdr = (Elf32_Ehdr*)cyg_ldr_malloc( sizeof( Elf32_Ehdr ) );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
231 CYG_ASSERT( p->p_elfhdr != 0, "Cannot malloc() p->p_elfhdr" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
232 if ( p->p_elfhdr == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
233 return -1;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
234 p->seek( p, 0 );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
235 p->read( p, sizeof( char ), sizeof( Elf32_Ehdr ), p->p_elfhdr );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
236 error_string = cyg_ldr_sanity_check( p );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
237 if ( error_string != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
238 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
239 cyg_ldr_last_error = "ERROR IN ELF HEADER";
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
240 return -1;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
241 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
242
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
243 // Allocate an array that can hold an address to all the section of this
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
244 // library. This is not strictly optimal, since some sections do not
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
245 // need to be loaded all the time. Allocate an extra pointer for the
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
246 // COMMON area.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
247 p->sections = cyg_ldr_malloc( ( p->p_elfhdr->e_shnum + 1 ) *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
248 sizeof( cyg_uint32 ) );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
249 CYG_ASSERT( p->sections != 0, "Cannot malloc() p->sections" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
250 if ( p->sections == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
251 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
252 cyg_ldr_last_error = "ERROR IN MALLOC";
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
253 return -1;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
254 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
255 memset( p->sections, 0, ( p->p_elfhdr->e_shnum + 1 ) *
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
256 sizeof( cyg_uint32 ) );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
257
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
258 // Now that the header is loaded, load the sections header.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
259 p->p_sechdr = (Elf32_Shdr*)cyg_ldr_malloc(
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
260 p->p_elfhdr->e_shnum * p->p_elfhdr->e_shentsize );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
261 CYG_ASSERT( p->p_sechdr != 0, "Cannot malloc() p->p_sechdr" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
262 if ( p->p_sechdr == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
263 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
264 cyg_ldr_last_error = "ERROR IN MALLOC";
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
265 return -1;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
266 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
267 p->seek( p, p->p_elfhdr->e_shoff );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
268 p->read( p, p->p_elfhdr->e_shentsize, p->p_elfhdr->e_shnum, p->p_sechdr );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
269
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
270 // Load the section header string table. This is a byte oriented table,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
271 // so alignment is not an issue.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
272 idx = p->p_elfhdr->e_shstrndx;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
273 p->sections[idx] = cyg_ldr_load_elf_section( p, idx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
274 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
275 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
276
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
277 PELF_OBJECT
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
278 cyg_ldr_open_library( CYG_ADDRWORD ptr, cyg_int32 mode )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
279 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
280 Elf32_Sym *p_symtab;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
281 cyg_uint8 *p_shstrtab;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
282 PELF_OBJECT e_obj;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
283 int (*fn)(void);
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
284 cyg_int32 i, rc, symtab_entries;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
285 cyg_uint32 common_size;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
286
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
287 // In the future there might be a switch() (against 'mode') that calls an
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
288 // open function other than cyg_ldr_open_library_fs(). These function
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
289 // fetch and open a library using ftp, http or libraries that are already
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
290 // in ROM.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
291 e_obj = cyg_ldr_open_library_fs( (cyg_uint8*)ptr );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
292 if ( e_obj == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
293 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
294 rc = cyg_ldr_load_sections( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
295 if ( rc != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
296 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
297 cyg_ldr_free_elf_object( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
298 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
299 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
300
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
301 // Find the section index for the .shstrtab section. The names of the
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
302 // sections are held here, and are the only way to identify them.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
303 p_shstrtab = (cyg_uint8*)cyg_ldr_section_address( e_obj,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
304 e_obj->p_elfhdr->e_shstrndx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
305 if ( p_shstrtab == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
306 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
307 cyg_ldr_free_elf_object( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
308 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
309 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
310
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
311 // .symtab section and .strtab. We have to go through the section names
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
312 // to find where they are.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
313 for ( i = 1; i < e_obj->p_elfhdr->e_shnum; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
314 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
315 // Now look for the index of .symtab. These are the symbols needed for
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
316 // the symbol retrieval as well as relocation.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
317 if ( !strcmp( p_shstrtab + e_obj->p_sechdr[i].sh_name,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
318 ELF_STRING_symtab ) )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
319 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
320 e_obj->hdrndx_symtab = i;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
321 e_obj->sections[i] = cyg_ldr_load_elf_section( e_obj, i );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
322 if ( e_obj->sections[i] == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
323 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
324 cyg_ldr_free_elf_object( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
325 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
326 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
327 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
328
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
329 // Load the table with the names of all the symbols. We need this
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
330 // to compare the name of external references symbols against the
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
331 // names in the in the CYG_HAL_TABLE provided by the user.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
332 if ( !strcmp( p_shstrtab + e_obj->p_sechdr[i].sh_name,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
333 ELF_STRING_strtab ) )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
334 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
335 e_obj->hdrndx_strtab = i;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
336 e_obj->sections[i] = cyg_ldr_load_elf_section( e_obj, i );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
337 if ( e_obj->sections[i] == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
338 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
339 cyg_ldr_free_elf_object( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
340 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
341 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
342 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
343 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
344
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
345 CYG_ASSERT( e_obj->hdrndx_symtab != 0, "No symtab index found" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
346 CYG_ASSERT( e_obj->hdrndx_strtab != 0, "No strtab index found" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
347
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
348 // Now look for symbols in the COMMON area. The COMMON symbols are a
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
349 // special case, because the area they reside in must be sized up
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
350 // and allocated separately from the other sections, which appear in
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
351 // the sections header and can be read out of the library itself.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
352 // Extra room in the 'sections' array has already been allocated to hold
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
353 // the pointer to the commons area.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
354 common_size = cyg_ldr_find_common_size( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
355 if ( common_size != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
356 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
357 cyg_uint32 com_shndx = e_obj->p_elfhdr->e_shnum;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
358 cyg_int32 com_offset = 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
359
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
360 e_obj->sections[com_shndx] = (cyg_uint32*)cyg_ldr_malloc( common_size );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
361 CYG_ASSERT( e_obj->sections[com_shndx] != 0,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
362 "Cannot malloc() the COMMONS" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
363
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
364 if ( e_obj->sections[com_shndx] == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
365 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
366 cyg_ldr_free_elf_object( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
367 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
368 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
369
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
370 // Now find all the symbols in the SHN_COMMON area and make
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
371 // them point to the newly allocated COM area.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
372 symtab_entries = e_obj->p_sechdr[e_obj->hdrndx_symtab].sh_size /
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
373 e_obj->p_sechdr[e_obj->hdrndx_symtab].sh_entsize;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
374 p_symtab = (Elf32_Sym*)e_obj->sections[e_obj->hdrndx_symtab];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
375
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
376 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
377 diag_printf( "Num Value Size Ndx Name\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
378 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
379 for ( i = 1; i < symtab_entries; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
380 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
381 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
382 cyg_uint8 *p_strtab = (cyg_uint8*)cyg_ldr_section_address( e_obj,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
383 e_obj->hdrndx_strtab );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
384 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
385 if ( p_symtab[i].st_shndx == SHN_COMMON )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
386 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
387 cyg_uint32 boundary = p_symtab[i].st_value - 1;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
388 // Calculate the next byte boundary.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
389 com_offset = ( com_offset + boundary ) & ~boundary;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
390 p_symtab[i].st_shndx = com_shndx;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
391 p_symtab[i].st_value = com_offset;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
392 com_offset += p_symtab[i].st_size;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
393 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
394
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
395 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
396 diag_printf( "%03d %08X %04X %03d %s\n",
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
397 i,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
398 p_symtab[i].st_value,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
399 p_symtab[i].st_size,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
400 p_symtab[i].st_shndx,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
401 p_strtab + p_symtab[i].st_name );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
402 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
403 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
404 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
405
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
406 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
407 cyg_ldr_print_section_data( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
408 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
409 cyg_ldr_print_symbol_names( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
410 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
411 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
412
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
413 for ( i = 1; i < e_obj->p_elfhdr->e_shnum; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
414 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
415 // Find all the '.rel' or '.rela' sections and relocate them.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
416 if ( ( e_obj->p_sechdr[i].sh_type == SHT_REL ) ||
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
417 ( e_obj->p_sechdr[i].sh_type == SHT_RELA ) )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
418 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
419 // Load and relocate the section.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
420 rc = cyg_ldr_relocate_section( e_obj, i );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
421 if ( rc < 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
422 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
423 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
424 ELFDEBUG( "Relocation unsuccessful\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
425 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
426 cyg_ldr_free_elf_object( e_obj );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
427 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
428 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
429 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
430 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
431
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
432 // Synch up the caches before calling any function in the library.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
433 cyg_ldr_flush_cache();
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
434
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
435 // Run the library initialization code.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
436 fn = cyg_ldr_find_symbol( e_obj, "library_open" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
437 if ( fn != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
438 fn();
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
439 return ((void*)e_obj);
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
440 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
441
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
442 cyg_uint8
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
443 *cyg_ldr_error( void )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
444 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
445 cyg_uint8* p = cyg_ldr_last_error;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
446 cyg_ldr_last_error = NULL;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
447 return p;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
448 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
449
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
450 void cyg_ldr_close_library( void* handle )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
451 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
452 void (*fn)(void);
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
453
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
454 PELF_OBJECT p = (PELF_OBJECT)handle;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
455 fn = cyg_ldr_find_symbol( p, "library_close" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
456 if ( fn != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
457 fn();
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
458
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
459 cyg_ldr_free_elf_object( p );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
460 p = 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
461 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
462