annotate packages/services/objloader/current/src/objelf.c @ 2011:662e1b34b811

Added OBJLOADER package.
author nickg
date Thu, 07 Jul 2005 10:55:12 +0000
parents
children 8bf90d16b837
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 * Relocation routine for eCos loader.
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 <pkgconf/io_fileio.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
58 #include <cyg/hal/hal_tables.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
59 #include <stdio.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
60
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
61 #include <pkgconf/objloader.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
62 #include <cyg/objloader/elf.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
63 #include <cyg/objloader/objelf.h>
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
64
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
65 CYG_HAL_TABLE_BEGIN( cyg_ldr_table, ldr_table );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
66 CYG_HAL_TABLE_END( cyg_ldr_table_end, ldr_table );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
67
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
68 __externC cyg_ldr_table_entry cyg_ldr_table[];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
69 __externC cyg_ldr_table_entry cyg_ldr_table_end[];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
70
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
71 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
72 void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
73 cyg_ldr_print_section_data( PELF_OBJECT p )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
74 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
75 cyg_int32 i;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
76 cyg_uint8 strname[32];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
77 cyg_uint8 *p_strtab = (cyg_uint8*)p->sections[p->p_elfhdr->e_shstrndx];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
78
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
79 diag_printf( "\n\nSection Headers:\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
80 diag_printf( "[Nr] Name Addr Offset Size Info\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
81 for ( i = 0; i < p->p_elfhdr->e_shnum; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
82 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
83 sprintf( strname, "%s", p_strtab + p->p_sechdr[i].sh_name );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
84 while ( strlen( strname ) < 20 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
85 strcat( strname, " " );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
86 diag_printf( "[%02d] %s %08X %08X %08X %08X\n",
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
87 i,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
88 strname,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
89 p->p_sechdr[i].sh_addr,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
90 p->p_sechdr[i].sh_offset,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
91 p->p_sechdr[i].sh_size,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
92 p->p_sechdr[i].sh_info );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
93 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
94 diag_printf( "\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
95 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
96
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
97 void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
98 cyg_ldr_print_symbol_names( PELF_OBJECT p )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
99 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
100 cyg_int32 i, symtab_entries;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
101 Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
102 cyg_uint8 *p_strtab = (cyg_uint8*)p->sections[p->hdrndx_strtab];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
103 cyg_uint8 strname[32];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
104
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
105 // Total number of entries in the symbol table.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
106 symtab_entries = p->p_sechdr[p->hdrndx_symtab].sh_size /
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
107 p->p_sechdr[p->hdrndx_symtab].sh_entsize;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
108 diag_printf( "Num Value Size Ndx Name\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
109 for ( i = 1; i < symtab_entries; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
110 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
111 sprintf( strname, "%d", i );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
112 while ( strlen( strname ) < 5 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
113 strcat( strname, " " );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
114 diag_printf( strname );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
115
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
116 sprintf( strname,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
117 "%08X %d",
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
118 p_symtab[i].st_value,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
119 p_symtab[i].st_size );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
120 while ( strlen( strname ) < 15 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
121 strcat( strname, " " );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
122 diag_printf( strname );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
123
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
124 sprintf( strname, "%d", p_symtab[i].st_shndx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
125 while ( strlen( strname ) < 6 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
126 strcat( strname, " " );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
127 diag_printf( strname );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
128
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
129 strncpy( strname,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
130 p_strtab + p_symtab[i].st_name,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
131 sizeof( strname ) - 1 );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
132 strname[strlen( p_strtab + p_symtab[i].st_name )] = '\0';
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
133 diag_printf( strname );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
134 diag_printf( "\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
135 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
136 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
137
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
138 void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
139 cyg_ldr_print_rel_names( PELF_OBJECT p )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
140 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
141 cyg_int32 i, j, r_entries, sym_index;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
142 Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
143 cyg_uint8 *p_strtab = (cyg_uint8*)p->sections[p->hdrndx_strtab];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
144 cyg_uint8 *p_shstrtab = (cyg_uint8*)p->sections[p->p_elfhdr->e_shstrndx];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
145 #if ELF_ARCH_RELTYPE == Elf_Rela
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
146 Elf32_Rela* p_rela;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
147 #else
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
148 Elf32_Rel* p_rel;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
149 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
150 cyg_uint8 strname[32];
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
151
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
152 for ( i = 1; i < p->p_elfhdr->e_shnum; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
153 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
154 if ( ( p->p_sechdr[i].sh_type == SHT_REL ) ||
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
155 ( p->p_sechdr[i].sh_type == SHT_RELA ) )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
156 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
157 // Calculate the total number of entries in the .rela section.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
158 r_entries = p->p_sechdr[i].sh_size / p->p_sechdr[i].sh_entsize;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
159
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
160 diag_printf( "\n\nSymbols at: %s\n\n",
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
161 p_shstrtab + p->p_sechdr[i].sh_name );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
162 #if ELF_ARCH_RELTYPE == Elf_Rela
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
163 p_rela = (Elf32_Rela*)cyg_ldr_load_elf_section( p, i );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
164 printf( "Offset Info Name [+ Addend]\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
165 #else
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
166 p_rel = (Elf32_Rel*)cyg_ldr_load_elf_section( p, i );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
167 printf( "Offset Info Name\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
168 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
169
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
170 for ( j = 0; j < r_entries; j++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
171 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
172 sprintf( strname,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
173 "%08X %08X ",
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
174 p_rela[j].r_offset,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
175 p_rela[j].r_info );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
176
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
177 diag_printf( strname );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
178
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
179 cyg_uint8 sym_type = ELF32_R_SYM( p_rela[j].r_info );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
180 if ( strlen ( p_strtab + p_symtab[sym_type].st_name ) > 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
181 diag_printf( p_strtab + p_symtab[sym_type].st_name );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
182 else
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
183 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
184 // If the symbol name is not available, then print
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
185 // the name of the section.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
186 sym_index = p_symtab[sym_type].st_shndx;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
187 diag_printf( p_shstrtab + p->p_sechdr[sym_index].sh_name );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
188 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
189 #if ELF_ARCH_RELTYPE == Elf_Rela
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
190 if ( p_rela[j].r_addend != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
191 diag_printf( " + %08X", p_rela[j].r_addend );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
192 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
193 diag_printf( "\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
194 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
195 // After all the printing is done, the relocation table can
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
196 // be dumped.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
197 cyg_ldr_delete_elf_section( p, i );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
198 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
199 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
200 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
201 #endif // DEBUG_PRINT
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
202
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
203 static void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
204 *cyg_ldr_local_address( PELF_OBJECT p, cyg_uint32 sym_index )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
205 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
206 cyg_uint32 data_sec, addr;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
207 Elf32_Sym *p_symtab;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
208
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
209 p_symtab = (Elf32_Sym*)cyg_ldr_section_address( p, p->hdrndx_symtab );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
210
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
211 // Find out the section number in which the data for this symbol is
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
212 // located.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
213 data_sec = p_symtab[sym_index].st_shndx;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
214
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
215 // From the section number we get the start of the memory area in
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
216 // memory.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
217 addr = (cyg_uint32)cyg_ldr_section_address( p, data_sec );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
218
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
219 // And now return the address of the data.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
220 return (void*)( addr + p_symtab[sym_index].st_value);
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
221 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
222
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
223 static void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
224 *cyg_ldr_external_address( PELF_OBJECT p, cyg_uint32 sym_index )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
225 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
226 cyg_uint8* tmp2;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
227 Elf32_Sym *p_symtab;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
228 cyg_uint8 *p_strtab;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
229 cyg_ldr_table_entry *entry = cyg_ldr_table;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
230
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
231
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
232 p_symtab = (Elf32_Sym*)cyg_ldr_section_address( p, p->hdrndx_symtab );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
233 p_strtab = (cyg_uint8*)cyg_ldr_section_address( p, p->hdrndx_strtab );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
234
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
235 // This is the name of the external reference to search.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
236 tmp2 = p_strtab + p_symtab[sym_index].st_name;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
237 while ( entry != cyg_ldr_table_end )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
238 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
239 if ( !strcmp( (const char*)tmp2, entry->symbol_name ) )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
240 return entry->handler;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
241 entry++;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
242 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
243
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
244 // Symbol not found.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
245 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
246 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
247
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
248 // input:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
249 // p : Pointer to the elf file object
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
250 // sym_index : Index of the symbol to be searched (in the SYMTAB)
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
251 //
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
252 // out:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
253 // 0 : Symbol not found
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
254 // Other : Address of the symbol in absolute memory.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
255 void
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
256 *cyg_ldr_symbol_address( PELF_OBJECT p, cyg_uint32 sym_index )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
257 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
258 cyg_uint32 addr;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
259 cyg_uint8 sym_info;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
260 Elf32_Sym *p_symtab;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
261
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
262 p_symtab = (Elf32_Sym*)cyg_ldr_section_address( p, p->hdrndx_symtab );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
263 sym_info = p_symtab[sym_index].st_info;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
264
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
265 switch ( ELF32_ST_TYPE( sym_info ) )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
266 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
267 case STT_NOTYPE:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
268 case STT_FUNC:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
269 case STT_OBJECT:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
270 switch ( ELF32_ST_BIND( sym_info ) )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
271 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
272 case STB_LOCAL:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
273 case STB_GLOBAL:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
274 if ( p_symtab[sym_index].st_shndx == SHN_UNDEF )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
275 return cyg_ldr_external_address( p, sym_index );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
276 else
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
277 return cyg_ldr_local_address( p, sym_index );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
278 case STB_WEAK:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
279 addr = (cyg_uint32)cyg_ldr_external_address( p, sym_index );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
280 if ( addr != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
281 return (void*)addr;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
282 else
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
283 return cyg_ldr_local_address( p, sym_index );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
284 default:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
285 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
286 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
287 break;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
288 case STT_SECTION:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
289 // Return the starting address of a section, given its index.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
290 return (void*)cyg_ldr_section_address( p,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
291 p_symtab[sym_index].st_shndx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
292 default:
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
293 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
294 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
295 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
296
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
297 // Loads the relocation information, relocates, and dumps the relocation
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
298 // information once the process is complete.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
299 cyg_int32
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
300 cyg_ldr_relocate_section( PELF_OBJECT p, cyg_uint32 r_shndx )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
301 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
302 cyg_int32 i, rc;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
303 cyg_uint32 r_entries, r_target_shndx, r_target_addr;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
304 cyg_uint32 sym_value, sym_index;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
305 Elf32_Addr r_offset;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
306 Elf32_Word r_type;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
307 Elf32_Sword r_addend;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
308 #if ELF_ARCH_RELTYPE == Elf_Rela
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
309 Elf32_Rela* p_rela = (Elf32_Rela*)cyg_ldr_load_elf_section( p, r_shndx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
310 #else
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
311 Elf32_Rel* p_rel = (Elf32_Rel*)cyg_ldr_load_elf_section( p, r_shndx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
312 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
313
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
314 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
315 Elf32_Sym *p_symtab = (Elf32_Sym*)cyg_ldr_section_address( p,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
316 p->hdrndx_symtab );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
317 cyg_uint8 *p_strtab = (cyg_uint8*)cyg_ldr_section_address( p,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
318 p->hdrndx_strtab );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
319 cyg_uint8 *p_shstrtab = (cyg_uint8*)cyg_ldr_section_address( p,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
320 p->p_elfhdr->e_shstrndx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
321 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
322
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
323 // Now we can get the address of the contents of the section to modify.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
324 r_target_shndx = p->p_sechdr[r_shndx].sh_info;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
325 r_target_addr = (cyg_uint32)cyg_ldr_section_address( p, r_target_shndx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
326
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
327 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
328 diag_printf( "Relocating section \"%s\"\n",
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
329 p_shstrtab + p->p_sechdr[r_target_shndx].sh_name );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
330 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
331 diag_printf( "Ndx Type Offset Name\"\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
332 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
333 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
334
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
335 // Perform relocatation for each of the members of this table.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
336 r_entries = p->p_sechdr[r_shndx].sh_size / p->p_sechdr[r_shndx].sh_entsize;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
337 for ( i = 0; i < r_entries; i++ )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
338 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
339 #if ELF_ARCH_RELTYPE == Elf_Rela
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
340 r_offset = p_rela[i].r_offset;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
341 r_type = ELF32_R_TYPE( p_rela[i].r_info );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
342 sym_index = ELF32_R_SYM( p_rela[i].r_info );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
343 r_addend = p_rela[i].r_addend;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
344 #else
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
345 r_offset = p_rel[i].r_offset;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
346 r_type = ELF32_R_TYPE( p_rel[i].r_info );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
347 sym_index = ELF32_R_SYM( p_rel[i].r_info );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
348 r_addend = 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
349 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
350
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
351 sym_value = (cyg_uint32)cyg_ldr_symbol_address( p, sym_index );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
352 if ( sym_value == 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
353 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
354 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
355 diag_printf( "Unknown symbol value: %s Index: %d\n",
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
356 p_strtab + p_symtab[sym_index].st_name,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
357 sym_index );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
358 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
359 return -1;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
360 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
361
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
362 // This is architecture dependent, and deals with whether we have
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
363 // '.rel' or '.rela' sections.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
364 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
365 diag_printf( "%04X %04X %08X ",
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
366 sym_index,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
367 r_type,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
368 r_offset );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
369 if ( strlen ( p_strtab + p_symtab[sym_index].st_name ) > 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
370 diag_printf( p_strtab + p_symtab[sym_index].st_name );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
371 else
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
372 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
373 // If the symbol name is not available, then print
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
374 // the name of the section.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
375 cyg_uint32 sec_ndx = p_symtab[sym_index].st_shndx;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
376 diag_printf( p_shstrtab + p->p_sechdr[sec_ndx].sh_name );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
377 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
378 diag_printf( "\n" );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
379 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
380 rc = cyg_ldr_relocate( r_type,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
381 r_target_addr + r_offset,
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
382 sym_value + r_addend );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
383 if ( rc != 0 )
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
384 {
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
385 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
386 diag_printf( "Relocation error: Cannot find symbol: %s\n",
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
387 p_strtab + p_symtab[sym_index].st_name );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
388 #endif
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
389 return -1;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
390 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
391 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
392
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
393 // After the relocation is done, the relocation table can be dumped.
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
394 cyg_ldr_delete_elf_section( p, r_shndx );
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
395 return 0;
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
396 }
662e1b34b811 Added OBJLOADER package.
nickg
parents:
diff changeset
397