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