Mercurial > ecos
annotate packages/services/objloader/current/src/objelf.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 |
| rev | line source |
|---|---|
| 2011 | 1 /* ================================================================= |
| 2 * | |
| 3 * objelf.c | |
| 4 * | |
| 5 * Relocation routine for eCos loader. | |
| 6 * | |
| 7 * ================================================================= | |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
8 * ####ECOSGPLCOPYRIGHTBEGIN#### |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
9 * ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
10 * This file is part of eCos, the Embedded Configurable Operating System. |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
11 * Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
12 * |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
13 * eCos is free software; you can redistribute it and/or modify it under |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
14 * the terms of the GNU General Public License as published by the Free |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
15 * Software Foundation; either version 2 or (at your option) any later |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
16 * version. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
17 * |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
18 * eCos is distributed in the hope that it will be useful, but WITHOUT |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
21 * for more details. |
| 2011 | 22 * |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
23 * You should have received a copy of the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
24 * along with eCos; if not, write to the Free Software Foundation, Inc., |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
26 * |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
27 * As a special exception, if other files instantiate templates or use |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
28 * macros or inline functions from this file, or you compile this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
29 * and link it with other works to produce a work based on this file, |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
30 * this file does not by itself cause the resulting work to be covered by |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
31 * the GNU General Public License. However the source code for this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
32 * must still be made available in accordance with section (3) of the GNU |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
33 * General Public License v2. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
34 * |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
35 * This exception does not invalidate any other reasons why a work based |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
36 * on this file might be covered by the GNU General Public License. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
37 * ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2243
diff
changeset
|
38 * ####ECOSGPLCOPYRIGHTEND#### |
| 2011 | 39 * ================================================================= |
| 40 * #####DESCRIPTIONBEGIN#### | |
| 41 * | |
| 2243 | 42 * Author(s): Anthony Tonizzo (atonizzo@gmail.com) |
| 2011 | 43 * Contributors: nickg@ecoscentric.com |
| 44 * Date: 2005-05-13 | |
| 45 * Purpose: | |
| 46 * Description: | |
| 47 * | |
| 48 * ####DESCRIPTIONEND#### | |
| 49 * | |
| 50 * ================================================================= | |
| 51 */ | |
| 52 | |
| 53 #include <cyg/infra/diag.h> // For diagnostic printing. | |
| 54 #include <cyg/hal/hal_tables.h> | |
| 55 #include <stdio.h> | |
| 56 | |
| 57 #include <pkgconf/objloader.h> | |
| 58 #include <cyg/objloader/elf.h> | |
| 59 #include <cyg/objloader/objelf.h> | |
| 60 | |
| 2243 | 61 CYG_HAL_TABLE_BEGIN(cyg_ldr_table, ldr_table); |
| 62 CYG_HAL_TABLE_END(cyg_ldr_table_end, ldr_table); | |
| 2011 | 63 |
| 64 __externC cyg_ldr_table_entry cyg_ldr_table[]; | |
| 65 __externC cyg_ldr_table_entry cyg_ldr_table_end[]; | |
| 66 | |
| 67 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 | |
| 68 void | |
| 2243 | 69 cyg_ldr_print_section_data(PELF_OBJECT p) |
| 2011 | 70 { |
| 2243 | 71 int i; |
| 72 char strname[32]; | |
| 73 char *p_strtab = (char*)p->sections[p->p_elfhdr->e_shstrndx]; | |
| 2011 | 74 |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
75 diag_printf("Section Headers:\n"); |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
76 diag_printf("----------------------------------------------------------\n"); |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
77 diag_printf("[Nr] Name Addr Offset" |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
78 " Size Info\n"); |
| 2243 | 79 for (i = 0; i < p->p_elfhdr->e_shnum; i++) |
| 2011 | 80 { |
| 2243 | 81 sprintf(strname, "%s", p_strtab + p->p_sechdr[i].sh_name); |
| 82 while (strlen(strname) < 20) | |
| 83 strcat(strname, " "); | |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
84 diag_printf("[%2d] %s %08X %08X %08X %08X\n", |
| 2011 | 85 i, |
| 86 strname, | |
| 87 p->p_sechdr[i].sh_addr, | |
| 88 p->p_sechdr[i].sh_offset, | |
| 89 p->p_sechdr[i].sh_size, | |
| 2243 | 90 p->p_sechdr[i].sh_info); |
| 2011 | 91 } |
| 2243 | 92 diag_printf("\n"); |
| 2011 | 93 } |
| 94 | |
| 95 void | |
| 2243 | 96 cyg_ldr_print_symbol_names(PELF_OBJECT p) |
| 2011 | 97 { |
| 2243 | 98 int i; |
| 2011 | 99 Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab]; |
| 2243 | 100 char *p_strtab = (char*)p->sections[p->hdrndx_strtab]; |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
101 // char strname[32]; |
| 2011 | 102 |
| 103 // Total number of entries in the symbol table. | |
| 2243 | 104 int symtab_entries = p->p_sechdr[p->hdrndx_symtab].sh_size / |
| 2011 | 105 p->p_sechdr[p->hdrndx_symtab].sh_entsize; |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
106 diag_printf("Symbol Table Entries\n"); |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
107 diag_printf("----------------------------------------\n"); |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
108 diag_printf("[Nr] Value Size Ndx Name\n"); |
| 2243 | 109 for (i = 1; i < symtab_entries; i++) |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
110 diag_printf("[%3d] %08X %04d %5d %s\n", |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
111 i, |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
112 p_symtab[i].st_value, |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
113 p_symtab[i].st_size, |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
114 p_symtab[i].st_shndx, |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
115 p_strtab + p_symtab[i].st_name); |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
116 diag_printf("\n"); |
| 2011 | 117 } |
| 118 | |
| 119 void | |
| 2243 | 120 cyg_ldr_print_rel_names(PELF_OBJECT p) |
| 2011 | 121 { |
| 2243 | 122 int i, j, r_entries, sym_index; |
| 2011 | 123 Elf32_Sym *p_symtab = (Elf32_Sym*)p->sections[p->hdrndx_symtab]; |
| 2243 | 124 char *p_strtab = (char*)p->sections[p->hdrndx_strtab]; |
| 125 char *p_shstrtab = (char*)p->sections[p->p_elfhdr->e_shstrndx]; | |
| 2011 | 126 #if ELF_ARCH_RELTYPE == Elf_Rela |
| 127 Elf32_Rela* p_rela; | |
| 128 #else | |
| 129 Elf32_Rel* p_rel; | |
| 130 #endif | |
| 2243 | 131 char strname[32]; |
| 2011 | 132 |
| 2243 | 133 for (i = 1; i < p->p_elfhdr->e_shnum; i++) |
| 2011 | 134 { |
| 2243 | 135 if ((p->p_sechdr[i].sh_type == SHT_REL) || |
| 136 (p->p_sechdr[i].sh_type == SHT_RELA)) | |
| 2011 | 137 { |
| 138 // Calculate the total number of entries in the .rela section. | |
| 139 r_entries = p->p_sechdr[i].sh_size / p->p_sechdr[i].sh_entsize; | |
| 140 | |
| 2243 | 141 diag_printf("\n\nSymbols at: %s\n\n", |
| 142 p_shstrtab + p->p_sechdr[i].sh_name); | |
| 2011 | 143 #if ELF_ARCH_RELTYPE == Elf_Rela |
| 2243 | 144 p_rela = (Elf32_Rela*)cyg_ldr_load_elf_section(p, i); |
| 145 printf("Offset Info Name [+ Addend]\n"); | |
| 2011 | 146 #else |
| 2243 | 147 p_rel = (Elf32_Rel*)cyg_ldr_load_elf_section(p, i); |
| 148 printf("Offset Info Name\n"); | |
| 2011 | 149 #endif |
| 150 | |
| 2243 | 151 for (j = 0; j < r_entries; j++) |
| 2011 | 152 { |
| 2243 | 153 sprintf(strname, |
| 2011 | 154 "%08X %08X ", |
|
2013
8bf90d16b837
* include/objelf.h: Include hal_tables.h otherwise we get strange
asl
parents:
2011
diff
changeset
|
155 #if ELF_ARCH_RELTYPE == Elf_Rela |
| 2243 | 156 p_rela[j].r_offset, |
| 157 p_rela[j].r_info | |
|
2013
8bf90d16b837
* include/objelf.h: Include hal_tables.h otherwise we get strange
asl
parents:
2011
diff
changeset
|
158 #else |
| 2243 | 159 p_rel[j].r_offset, |
| 160 p_rel[j].r_info | |
|
2013
8bf90d16b837
* include/objelf.h: Include hal_tables.h otherwise we get strange
asl
parents:
2011
diff
changeset
|
161 #endif |
| 2243 | 162 ); |
| 2011 | 163 |
| 2243 | 164 diag_printf(strname); |
|
2013
8bf90d16b837
* include/objelf.h: Include hal_tables.h otherwise we get strange
asl
parents:
2011
diff
changeset
|
165 |
|
8bf90d16b837
* include/objelf.h: Include hal_tables.h otherwise we get strange
asl
parents:
2011
diff
changeset
|
166 #if ELF_ARCH_RELTYPE == Elf_Rela |
| 2243 | 167 cyg_uint8 sym_type = ELF32_R_SYM(p_rela[j].r_info); |
|
2013
8bf90d16b837
* include/objelf.h: Include hal_tables.h otherwise we get strange
asl
parents:
2011
diff
changeset
|
168 #else |
| 2243 | 169 cyg_uint8 sym_type = ELF32_R_SYM(p_rel[j].r_info); |
|
2013
8bf90d16b837
* include/objelf.h: Include hal_tables.h otherwise we get strange
asl
parents:
2011
diff
changeset
|
170 #endif |
| 2243 | 171 if (strlen (p_strtab + p_symtab[sym_type].st_name) > 0) |
| 172 diag_printf(p_strtab + p_symtab[sym_type].st_name); | |
| 2011 | 173 else |
| 174 { | |
| 175 // If the symbol name is not available, then print | |
| 176 // the name of the section. | |
| 177 sym_index = p_symtab[sym_type].st_shndx; | |
| 2243 | 178 diag_printf(p_shstrtab + p->p_sechdr[sym_index].sh_name); |
| 2011 | 179 } |
| 180 #if ELF_ARCH_RELTYPE == Elf_Rela | |
| 2243 | 181 if (p_rela[j].r_addend != 0) |
| 182 diag_printf(" + %08X", p_rela[j].r_addend); | |
| 2011 | 183 #endif |
| 2243 | 184 diag_printf("\n"); |
| 2011 | 185 } |
| 186 // After all the printing is done, the relocation table can | |
| 187 // be dumped. | |
| 2243 | 188 cyg_ldr_delete_elf_section(p, i); |
| 2011 | 189 } |
| 190 } | |
| 191 } | |
| 192 #endif // DEBUG_PRINT | |
| 193 | |
| 194 static void | |
| 2243 | 195 *cyg_ldr_local_address(PELF_OBJECT p, cyg_uint32 sym_index) |
| 2011 | 196 { |
| 197 cyg_uint32 data_sec, addr; | |
| 198 Elf32_Sym *p_symtab; | |
| 199 | |
| 2243 | 200 p_symtab = (Elf32_Sym*)cyg_ldr_section_address(p, p->hdrndx_symtab); |
| 2011 | 201 |
| 202 // Find out the section number in which the data for this symbol is | |
| 203 // located. | |
| 204 data_sec = p_symtab[sym_index].st_shndx; | |
| 205 | |
| 206 // From the section number we get the start of the memory area in | |
| 207 // memory. | |
| 2243 | 208 addr = (cyg_uint32)cyg_ldr_section_address(p, data_sec); |
| 2011 | 209 |
| 210 // And now return the address of the data. | |
| 2243 | 211 return (void*)(addr + p_symtab[sym_index].st_value); |
| 2011 | 212 } |
| 213 | |
|
2013
8bf90d16b837
* include/objelf.h: Include hal_tables.h otherwise we get strange
asl
parents:
2011
diff
changeset
|
214 void |
| 2243 | 215 *cyg_ldr_external_address(PELF_OBJECT p, cyg_uint32 sym_index) |
| 2011 | 216 { |
| 217 cyg_uint8* tmp2; | |
| 218 Elf32_Sym *p_symtab; | |
| 219 cyg_uint8 *p_strtab; | |
| 220 cyg_ldr_table_entry *entry = cyg_ldr_table; | |
| 221 | |
| 222 | |
| 2243 | 223 p_symtab = (Elf32_Sym*)cyg_ldr_section_address(p, p->hdrndx_symtab); |
| 224 p_strtab = (cyg_uint8*)cyg_ldr_section_address(p, p->hdrndx_strtab); | |
| 2011 | 225 |
| 226 // This is the name of the external reference to search. | |
| 227 tmp2 = p_strtab + p_symtab[sym_index].st_name; | |
| 2243 | 228 while (entry != cyg_ldr_table_end) |
| 2011 | 229 { |
| 2243 | 230 if (!strcmp((const char*)tmp2, entry->symbol_name )) |
| 2011 | 231 return entry->handler; |
| 232 entry++; | |
| 233 } | |
| 234 | |
| 235 // Symbol not found. | |
| 236 return 0; | |
| 237 } | |
| 238 | |
| 239 // input: | |
| 240 // p : Pointer to the elf file object | |
| 241 // sym_index : Index of the symbol to be searched (in the SYMTAB) | |
| 242 // | |
| 243 // out: | |
| 244 // 0 : Symbol not found | |
| 245 // Other : Address of the symbol in absolute memory. | |
| 246 void | |
| 2243 | 247 *cyg_ldr_symbol_address(PELF_OBJECT p, cyg_uint32 sym_index) |
| 2011 | 248 { |
| 249 cyg_uint32 addr; | |
| 2243 | 250 Elf32_Sym *p_symtab = (Elf32_Sym*)cyg_ldr_section_address(p, |
| 251 p->hdrndx_symtab); | |
| 252 cyg_uint8 sym_info = p_symtab[sym_index].st_info; | |
| 253 switch (ELF32_ST_TYPE(sym_info)) | |
| 2011 | 254 { |
| 255 case STT_NOTYPE: | |
| 256 case STT_FUNC: | |
| 257 case STT_OBJECT: | |
| 2243 | 258 switch (ELF32_ST_BIND(sym_info)) |
| 2011 | 259 { |
| 260 case STB_LOCAL: | |
| 261 case STB_GLOBAL: | |
| 2243 | 262 if (p_symtab[sym_index].st_shndx == SHN_UNDEF) |
| 263 return cyg_ldr_external_address(p, sym_index); | |
| 2011 | 264 else |
| 2243 | 265 return cyg_ldr_local_address(p, sym_index); |
| 2011 | 266 case STB_WEAK: |
| 2243 | 267 addr = (cyg_uint32)cyg_ldr_external_address(p, sym_index); |
| 268 if (addr != 0) | |
| 2011 | 269 return (void*)addr; |
| 270 else | |
| 2243 | 271 return cyg_ldr_local_address(p, sym_index); |
| 2011 | 272 default: |
| 273 return 0; | |
| 274 } | |
| 275 break; | |
| 276 case STT_SECTION: | |
| 277 // Return the starting address of a section, given its index. | |
| 2243 | 278 return (void*)cyg_ldr_section_address(p, p_symtab[sym_index].st_shndx); |
| 2011 | 279 default: |
| 280 return 0; | |
| 281 } | |
| 282 } | |
| 283 | |
| 284 // Loads the relocation information, relocates, and dumps the relocation | |
| 285 // information once the process is complete. | |
| 286 cyg_int32 | |
| 2243 | 287 cyg_ldr_relocate_section(PELF_OBJECT p, cyg_uint32 r_shndx) |
| 2011 | 288 { |
| 2243 | 289 int i, rc; |
| 2011 | 290 #if ELF_ARCH_RELTYPE == Elf_Rela |
| 2243 | 291 Elf32_Rela* p_rela = (Elf32_Rela*)cyg_ldr_load_elf_section(p, r_shndx); |
| 2011 | 292 #else |
| 2243 | 293 Elf32_Rel* p_rel = (Elf32_Rel*)cyg_ldr_load_elf_section(p, r_shndx); |
| 2011 | 294 #endif |
| 295 | |
| 296 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 | |
| 2243 | 297 Elf32_Sym *p_symtab = (Elf32_Sym*)cyg_ldr_section_address(p, |
| 298 p->hdrndx_symtab); | |
| 299 char *p_strtab = (char*)cyg_ldr_section_address(p, p->hdrndx_strtab); | |
| 300 char *p_shstrtab = (char*)cyg_ldr_section_address(p, | |
| 301 p->p_elfhdr->e_shstrndx); | |
| 2011 | 302 #endif |
| 303 | |
| 304 // Now we can get the address of the contents of the section to modify. | |
| 2243 | 305 cyg_uint32 r_target_shndx = p->p_sechdr[r_shndx].sh_info; |
| 306 cyg_uint32 r_target_addr = (cyg_uint32)cyg_ldr_section_address(p, | |
| 307 r_target_shndx); | |
| 2011 | 308 |
| 309 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0 | |
| 2243 | 310 diag_printf("Relocating section \"%s\"\n", |
| 311 p_shstrtab + p->p_sechdr[r_target_shndx].sh_name); | |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
312 diag_printf("----------------------------------------\n"); |
| 2011 | 313 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
314 diag_printf(" Ndx Type Offset Name\"\n"); |
| 2011 | 315 #endif |
| 316 #endif | |
| 317 | |
| 318 // Perform relocatation for each of the members of this table. | |
| 2243 | 319 cyg_uint32 r_entries = p->p_sechdr[r_shndx].sh_size / |
| 320 p->p_sechdr[r_shndx].sh_entsize; | |
| 321 for (i = 0; i < r_entries; i++) | |
| 2011 | 322 { |
| 323 #if ELF_ARCH_RELTYPE == Elf_Rela | |
| 2243 | 324 Elf32_Addr r_offset = p_rela[i].r_offset; |
| 325 Elf32_Word r_type = ELF32_R_TYPE(p_rela[i].r_info); | |
| 326 cyg_uint32 sym_index = ELF32_R_SYM(p_rela[i].r_info); | |
| 327 Elf32_Sword r_addend = p_rela[i].r_addend; | |
| 2011 | 328 #else |
| 2243 | 329 Elf32_Addr r_offset = p_rel[i].r_offset; |
| 330 Elf32_Word r_type = ELF32_R_TYPE(p_rel[i].r_info); | |
| 331 cyg_uint32 sym_index = ELF32_R_SYM(p_rel[i].r_info); | |
| 332 Elf32_Sword r_addend = 0; | |
| 2011 | 333 #endif |
| 334 | |
| 2243 | 335 cyg_uint32 sym_value = (cyg_uint32)cyg_ldr_symbol_address(p, sym_index); |
| 2011 | 336 |
| 337 // This is architecture dependent, and deals with whether we have | |
| 338 // '.rel' or '.rela' sections. | |
| 339 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 | |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
340 diag_printf("%5d %s %08X ", |
| 2011 | 341 sym_index, |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
342 relocation_name[r_type], |
| 2243 | 343 r_offset); |
| 344 if (strlen(p_strtab + p_symtab[sym_index].st_name) > 0) | |
| 345 diag_printf(p_strtab + p_symtab[sym_index].st_name); | |
| 2011 | 346 else |
| 347 { | |
| 348 // If the symbol name is not available, then print | |
| 349 // the name of the section. | |
| 350 cyg_uint32 sec_ndx = p_symtab[sym_index].st_shndx; | |
| 2243 | 351 diag_printf(p_shstrtab + p->p_sechdr[sec_ndx].sh_name); |
| 2011 | 352 } |
| 2243 | 353 diag_printf("\n"); |
| 2011 | 354 #endif |
| 2243 | 355 rc = cyg_ldr_relocate(r_type, |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
356 r_target_addr + r_offset, |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
357 sym_value + r_addend); |
| 2243 | 358 if (rc != 0) |
| 2011 | 359 { |
|
2890
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
360 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 1 |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
361 diag_printf("Error while relocating symbol: %s\n", |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
362 p_strtab + p_symtab[sym_index].st_name); |
|
f8dd12428f1d
* cdl/objloader.cdl, src/objelf.c, src/relocate_ppc.c,
jld
parents:
2729
diff
changeset
|
363 return -1; |
| 2011 | 364 #endif |
| 365 } | |
| 366 } | |
| 367 | |
| 368 // After the relocation is done, the relocation table can be dumped. | |
| 2243 | 369 cyg_ldr_delete_elf_section(p, r_shndx); |
| 2011 | 370 return 0; |
| 371 } | |
| 372 |
