00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 #include "bfd.h"
00072 #include "sysdep.h"
00073 #include "libiberty.h"
00074 #include "bfdlink.h"
00075 #include "libbfd.h"
00076 #include "elf-bfd.h"
00077
00078
00079 #define Elf_External_Ehdr NAME(Elf,External_Ehdr)
00080 #define Elf_External_Sym NAME(Elf,External_Sym)
00081 #define Elf_External_Shdr NAME(Elf,External_Shdr)
00082 #define Elf_External_Phdr NAME(Elf,External_Phdr)
00083 #define Elf_External_Rel NAME(Elf,External_Rel)
00084 #define Elf_External_Rela NAME(Elf,External_Rela)
00085 #define Elf_External_Dyn NAME(Elf,External_Dyn)
00086
00087 #define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command)
00088 #define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal)
00089 #define elf_core_file_matches_executable_p \
00090 NAME(bfd_elf,core_file_matches_executable_p)
00091 #define elf_object_p NAME(bfd_elf,object_p)
00092 #define elf_core_file_p NAME(bfd_elf,core_file_p)
00093 #define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound)
00094 #define elf_get_dynamic_symtab_upper_bound \
00095 NAME(bfd_elf,get_dynamic_symtab_upper_bound)
00096 #define elf_swap_reloc_in NAME(bfd_elf,swap_reloc_in)
00097 #define elf_swap_reloca_in NAME(bfd_elf,swap_reloca_in)
00098 #define elf_swap_reloc_out NAME(bfd_elf,swap_reloc_out)
00099 #define elf_swap_reloca_out NAME(bfd_elf,swap_reloca_out)
00100 #define elf_swap_symbol_in NAME(bfd_elf,swap_symbol_in)
00101 #define elf_swap_symbol_out NAME(bfd_elf,swap_symbol_out)
00102 #define elf_swap_phdr_in NAME(bfd_elf,swap_phdr_in)
00103 #define elf_swap_phdr_out NAME(bfd_elf,swap_phdr_out)
00104 #define elf_swap_dyn_in NAME(bfd_elf,swap_dyn_in)
00105 #define elf_swap_dyn_out NAME(bfd_elf,swap_dyn_out)
00106 #define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound)
00107 #define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc)
00108 #define elf_slurp_symbol_table NAME(bfd_elf,slurp_symbol_table)
00109 #define elf_canonicalize_symtab NAME(bfd_elf,canonicalize_symtab)
00110 #define elf_canonicalize_dynamic_symtab \
00111 NAME(bfd_elf,canonicalize_dynamic_symtab)
00112 #define elf_get_synthetic_symtab \
00113 NAME(bfd_elf,get_synthetic_symtab)
00114 #define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol)
00115 #define elf_get_symbol_info NAME(bfd_elf,get_symbol_info)
00116 #define elf_get_lineno NAME(bfd_elf,get_lineno)
00117 #define elf_set_arch_mach NAME(bfd_elf,set_arch_mach)
00118 #define elf_find_nearest_line NAME(bfd_elf,find_nearest_line)
00119 #define elf_sizeof_headers NAME(bfd_elf,sizeof_headers)
00120 #define elf_set_section_contents NAME(bfd_elf,set_section_contents)
00121 #define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto)
00122 #define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel)
00123 #define elf_find_section NAME(bfd_elf,find_section)
00124 #define elf_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr)
00125 #define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs)
00126 #define elf_write_relocs NAME(bfd_elf,write_relocs)
00127 #define elf_slurp_reloc_table NAME(bfd_elf,slurp_reloc_table)
00128
00129 #if ARCH_SIZE == 64
00130 #define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y)
00131 #define ELF_R_SYM(X) ELF64_R_SYM(X)
00132 #define ELF_R_TYPE(X) ELF64_R_TYPE(X)
00133 #define ELFCLASS ELFCLASS64
00134 #define FILE_ALIGN 8
00135 #define LOG_FILE_ALIGN 3
00136 #endif
00137 #if ARCH_SIZE == 32
00138 #define ELF_R_INFO(X,Y) ELF32_R_INFO(X,Y)
00139 #define ELF_R_SYM(X) ELF32_R_SYM(X)
00140 #define ELF_R_TYPE(X) ELF32_R_TYPE(X)
00141 #define ELFCLASS ELFCLASS32
00142 #define FILE_ALIGN 4
00143 #define LOG_FILE_ALIGN 2
00144 #endif
00145
00146 #ifdef DEBUG
00147 static void elf_debug_section (int, Elf_Internal_Shdr *);
00148 static void elf_debug_file (Elf_Internal_Ehdr *);
00149 static char *elf_symbol_flags (flagword);
00150 #endif
00151
00152
00153
00154
00155
00156 #if ARCH_SIZE == 64
00157 #define H_PUT_WORD H_PUT_64
00158 #define H_PUT_SIGNED_WORD H_PUT_S64
00159 #define H_GET_WORD H_GET_64
00160 #define H_GET_SIGNED_WORD H_GET_S64
00161 #endif
00162 #if ARCH_SIZE == 32
00163 #define H_PUT_WORD H_PUT_32
00164 #define H_PUT_SIGNED_WORD H_PUT_S32
00165 #define H_GET_WORD H_GET_32
00166 #define H_GET_SIGNED_WORD H_GET_S32
00167 #endif
00168
00169
00170
00171
00172 void
00173 elf_swap_symbol_in (bfd *abfd,
00174 const void *psrc,
00175 const void *pshn,
00176 Elf_Internal_Sym *dst)
00177 {
00178 const Elf_External_Sym *src = psrc;
00179 const Elf_External_Sym_Shndx *shndx = pshn;
00180 int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
00181
00182 dst->st_name = H_GET_32 (abfd, src->st_name);
00183 if (signed_vma)
00184 dst->st_value = H_GET_SIGNED_WORD (abfd, src->st_value);
00185 else
00186 dst->st_value = H_GET_WORD (abfd, src->st_value);
00187 dst->st_size = H_GET_WORD (abfd, src->st_size);
00188 dst->st_info = H_GET_8 (abfd, src->st_info);
00189 dst->st_other = H_GET_8 (abfd, src->st_other);
00190 dst->st_shndx = H_GET_16 (abfd, src->st_shndx);
00191 if (dst->st_shndx == SHN_XINDEX)
00192 {
00193 if (shndx == NULL)
00194 abort ();
00195 dst->st_shndx = H_GET_32 (abfd, shndx->est_shndx);
00196 }
00197 }
00198
00199
00200
00201
00202 void
00203 elf_swap_symbol_out (bfd *abfd,
00204 const Elf_Internal_Sym *src,
00205 void *cdst,
00206 void *shndx)
00207 {
00208 unsigned int tmp;
00209 Elf_External_Sym *dst = cdst;
00210 H_PUT_32 (abfd, src->st_name, dst->st_name);
00211 H_PUT_WORD (abfd, src->st_value, dst->st_value);
00212 H_PUT_WORD (abfd, src->st_size, dst->st_size);
00213 H_PUT_8 (abfd, src->st_info, dst->st_info);
00214 H_PUT_8 (abfd, src->st_other, dst->st_other);
00215 tmp = src->st_shndx;
00216 if (tmp > SHN_HIRESERVE)
00217 {
00218 if (shndx == NULL)
00219 abort ();
00220 H_PUT_32 (abfd, tmp, shndx);
00221 tmp = SHN_XINDEX;
00222 }
00223 H_PUT_16 (abfd, tmp, dst->st_shndx);
00224 }
00225
00226
00227
00228
00229 static void
00230 elf_swap_ehdr_in (bfd *abfd,
00231 const Elf_External_Ehdr *src,
00232 Elf_Internal_Ehdr *dst)
00233 {
00234 int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
00235 memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
00236 dst->e_type = H_GET_16 (abfd, src->e_type);
00237 dst->e_machine = H_GET_16 (abfd, src->e_machine);
00238 dst->e_version = H_GET_32 (abfd, src->e_version);
00239 if (signed_vma)
00240 dst->e_entry = H_GET_SIGNED_WORD (abfd, src->e_entry);
00241 else
00242 dst->e_entry = H_GET_WORD (abfd, src->e_entry);
00243 dst->e_phoff = H_GET_WORD (abfd, src->e_phoff);
00244 dst->e_shoff = H_GET_WORD (abfd, src->e_shoff);
00245 dst->e_flags = H_GET_32 (abfd, src->e_flags);
00246 dst->e_ehsize = H_GET_16 (abfd, src->e_ehsize);
00247 dst->e_phentsize = H_GET_16 (abfd, src->e_phentsize);
00248 dst->e_phnum = H_GET_16 (abfd, src->e_phnum);
00249 dst->e_shentsize = H_GET_16 (abfd, src->e_shentsize);
00250 dst->e_shnum = H_GET_16 (abfd, src->e_shnum);
00251 dst->e_shstrndx = H_GET_16 (abfd, src->e_shstrndx);
00252 }
00253
00254
00255
00256
00257 static void
00258 elf_swap_ehdr_out (bfd *abfd,
00259 const Elf_Internal_Ehdr *src,
00260 Elf_External_Ehdr *dst)
00261 {
00262 unsigned int tmp;
00263 int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
00264 memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
00265
00266 H_PUT_16 (abfd, src->e_type, dst->e_type);
00267 H_PUT_16 (abfd, src->e_machine, dst->e_machine);
00268 H_PUT_32 (abfd, src->e_version, dst->e_version);
00269 if (signed_vma)
00270 H_PUT_SIGNED_WORD (abfd, src->e_entry, dst->e_entry);
00271 else
00272 H_PUT_WORD (abfd, src->e_entry, dst->e_entry);
00273 H_PUT_WORD (abfd, src->e_phoff, dst->e_phoff);
00274 H_PUT_WORD (abfd, src->e_shoff, dst->e_shoff);
00275 H_PUT_32 (abfd, src->e_flags, dst->e_flags);
00276 H_PUT_16 (abfd, src->e_ehsize, dst->e_ehsize);
00277 H_PUT_16 (abfd, src->e_phentsize, dst->e_phentsize);
00278 H_PUT_16 (abfd, src->e_phnum, dst->e_phnum);
00279 H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize);
00280 tmp = src->e_shnum;
00281 if (tmp >= SHN_LORESERVE)
00282 tmp = SHN_UNDEF;
00283 H_PUT_16 (abfd, tmp, dst->e_shnum);
00284 tmp = src->e_shstrndx;
00285 if (tmp >= SHN_LORESERVE)
00286 tmp = SHN_XINDEX;
00287 H_PUT_16 (abfd, tmp, dst->e_shstrndx);
00288 }
00289
00290
00291
00292
00293 static void
00294 elf_swap_shdr_in (bfd *abfd,
00295 const Elf_External_Shdr *src,
00296 Elf_Internal_Shdr *dst)
00297 {
00298 int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
00299
00300 dst->sh_name = H_GET_32 (abfd, src->sh_name);
00301 dst->sh_type = H_GET_32 (abfd, src->sh_type);
00302 dst->sh_flags = H_GET_WORD (abfd, src->sh_flags);
00303 if (signed_vma)
00304 dst->sh_addr = H_GET_SIGNED_WORD (abfd, src->sh_addr);
00305 else
00306 dst->sh_addr = H_GET_WORD (abfd, src->sh_addr);
00307 dst->sh_offset = H_GET_WORD (abfd, src->sh_offset);
00308 dst->sh_size = H_GET_WORD (abfd, src->sh_size);
00309 dst->sh_link = H_GET_32 (abfd, src->sh_link);
00310 dst->sh_info = H_GET_32 (abfd, src->sh_info);
00311 dst->sh_addralign = H_GET_WORD (abfd, src->sh_addralign);
00312 dst->sh_entsize = H_GET_WORD (abfd, src->sh_entsize);
00313 dst->bfd_section = NULL;
00314 dst->contents = NULL;
00315 }
00316
00317
00318
00319
00320 static void
00321 elf_swap_shdr_out (bfd *abfd,
00322 const Elf_Internal_Shdr *src,
00323 Elf_External_Shdr *dst)
00324 {
00325
00326 H_PUT_32 (abfd, src->sh_name, dst->sh_name);
00327 H_PUT_32 (abfd, src->sh_type, dst->sh_type);
00328 H_PUT_WORD (abfd, src->sh_flags, dst->sh_flags);
00329 H_PUT_WORD (abfd, src->sh_addr, dst->sh_addr);
00330 H_PUT_WORD (abfd, src->sh_offset, dst->sh_offset);
00331 H_PUT_WORD (abfd, src->sh_size, dst->sh_size);
00332 H_PUT_32 (abfd, src->sh_link, dst->sh_link);
00333 H_PUT_32 (abfd, src->sh_info, dst->sh_info);
00334 H_PUT_WORD (abfd, src->sh_addralign, dst->sh_addralign);
00335 H_PUT_WORD (abfd, src->sh_entsize, dst->sh_entsize);
00336 }
00337
00338
00339
00340
00341 void
00342 elf_swap_phdr_in (bfd *abfd,
00343 const Elf_External_Phdr *src,
00344 Elf_Internal_Phdr *dst)
00345 {
00346 int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
00347
00348 dst->p_type = H_GET_32 (abfd, src->p_type);
00349 dst->p_flags = H_GET_32 (abfd, src->p_flags);
00350 dst->p_offset = H_GET_WORD (abfd, src->p_offset);
00351 if (signed_vma)
00352 {
00353 dst->p_vaddr = H_GET_SIGNED_WORD (abfd, src->p_vaddr);
00354 dst->p_paddr = H_GET_SIGNED_WORD (abfd, src->p_paddr);
00355 }
00356 else
00357 {
00358 dst->p_vaddr = H_GET_WORD (abfd, src->p_vaddr);
00359 dst->p_paddr = H_GET_WORD (abfd, src->p_paddr);
00360 }
00361 dst->p_filesz = H_GET_WORD (abfd, src->p_filesz);
00362 dst->p_memsz = H_GET_WORD (abfd, src->p_memsz);
00363 dst->p_align = H_GET_WORD (abfd, src->p_align);
00364 }
00365
00366 void
00367 elf_swap_phdr_out (bfd *abfd,
00368 const Elf_Internal_Phdr *src,
00369 Elf_External_Phdr *dst)
00370 {
00371
00372 H_PUT_32 (abfd, src->p_type, dst->p_type);
00373 H_PUT_WORD (abfd, src->p_offset, dst->p_offset);
00374 H_PUT_WORD (abfd, src->p_vaddr, dst->p_vaddr);
00375 H_PUT_WORD (abfd, src->p_paddr, dst->p_paddr);
00376 H_PUT_WORD (abfd, src->p_filesz, dst->p_filesz);
00377 H_PUT_WORD (abfd, src->p_memsz, dst->p_memsz);
00378 H_PUT_32 (abfd, src->p_flags, dst->p_flags);
00379 H_PUT_WORD (abfd, src->p_align, dst->p_align);
00380 }
00381
00382
00383 void
00384 elf_swap_reloc_in (bfd *abfd,
00385 const bfd_byte *s,
00386 Elf_Internal_Rela *dst)
00387 {
00388 const Elf_External_Rel *src = (const Elf_External_Rel *) s;
00389 dst->r_offset = H_GET_WORD (abfd, src->r_offset);
00390 dst->r_info = H_GET_WORD (abfd, src->r_info);
00391 dst->r_addend = 0;
00392 }
00393
00394 void
00395 elf_swap_reloca_in (bfd *abfd,
00396 const bfd_byte *s,
00397 Elf_Internal_Rela *dst)
00398 {
00399 const Elf_External_Rela *src = (const Elf_External_Rela *) s;
00400 dst->r_offset = H_GET_WORD (abfd, src->r_offset);
00401 dst->r_info = H_GET_WORD (abfd, src->r_info);
00402 dst->r_addend = H_GET_SIGNED_WORD (abfd, src->r_addend);
00403 }
00404
00405
00406 void
00407 elf_swap_reloc_out (bfd *abfd,
00408 const Elf_Internal_Rela *src,
00409 bfd_byte *d)
00410 {
00411 Elf_External_Rel *dst = (Elf_External_Rel *) d;
00412 H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
00413 H_PUT_WORD (abfd, src->r_info, dst->r_info);
00414 }
00415
00416 void
00417 elf_swap_reloca_out (bfd *abfd,
00418 const Elf_Internal_Rela *src,
00419 bfd_byte *d)
00420 {
00421 Elf_External_Rela *dst = (Elf_External_Rela *) d;
00422 H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
00423 H_PUT_WORD (abfd, src->r_info, dst->r_info);
00424 H_PUT_SIGNED_WORD (abfd, src->r_addend, dst->r_addend);
00425 }
00426
00427 void
00428 elf_swap_dyn_in (bfd *abfd,
00429 const void *p,
00430 Elf_Internal_Dyn *dst)
00431 {
00432 const Elf_External_Dyn *src = p;
00433
00434 dst->d_tag = H_GET_WORD (abfd, src->d_tag);
00435 dst->d_un.d_val = H_GET_WORD (abfd, src->d_un.d_val);
00436 }
00437
00438 void
00439 elf_swap_dyn_out (bfd *abfd,
00440 const Elf_Internal_Dyn *src,
00441 void *p)
00442 {
00443 Elf_External_Dyn *dst = p;
00444
00445 H_PUT_WORD (abfd, src->d_tag, dst->d_tag);
00446 H_PUT_WORD (abfd, src->d_un.d_val, dst->d_un.d_val);
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456 static inline bfd_boolean
00457 elf_file_p (Elf_External_Ehdr *x_ehdrp)
00458 {
00459 return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0)
00460 && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1)
00461 && (x_ehdrp->e_ident[EI_MAG2] == ELFMAG2)
00462 && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3));
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 const bfd_target *
00474 elf_object_p (bfd *abfd)
00475 {
00476 Elf_External_Ehdr x_ehdr;
00477 Elf_Internal_Ehdr *i_ehdrp;
00478 Elf_External_Shdr x_shdr;
00479 Elf_Internal_Shdr i_shdr;
00480 Elf_Internal_Shdr *i_shdrp;
00481 unsigned int shindex;
00482 char *shstrtab;
00483 const struct elf_backend_data *ebd;
00484 struct bfd_preserve preserve;
00485 asection *s;
00486 bfd_size_type amt;
00487
00488 preserve.marker = NULL;
00489
00490
00491
00492 if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
00493 {
00494 if (bfd_get_error () != bfd_error_system_call)
00495 goto got_wrong_format_error;
00496 else
00497 goto got_no_match;
00498 }
00499
00500
00501
00502
00503
00504
00505
00506 if (! elf_file_p (&x_ehdr)
00507 || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
00508 || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
00509 goto got_wrong_format_error;
00510
00511
00512 switch (x_ehdr.e_ident[EI_DATA])
00513 {
00514 case ELFDATA2MSB:
00515 if (! bfd_header_big_endian (abfd))
00516 goto got_wrong_format_error;
00517 break;
00518 case ELFDATA2LSB:
00519 if (! bfd_header_little_endian (abfd))
00520 goto got_wrong_format_error;
00521 break;
00522 case ELFDATANONE:
00523 default:
00524 goto got_wrong_format_error;
00525 }
00526
00527 if (!bfd_preserve_save (abfd, &preserve))
00528 goto got_no_match;
00529
00530
00531
00532
00533 if (! (*abfd->xvec->_bfd_set_format[bfd_object]) (abfd))
00534 goto got_no_match;
00535 preserve.marker = elf_tdata (abfd);
00536
00537
00538 i_ehdrp = elf_elfheader (abfd);
00539 elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
00540 #if DEBUG & 1
00541 elf_debug_file (i_ehdrp);
00542 #endif
00543
00544
00545 if (i_ehdrp->e_type == ET_CORE)
00546 goto got_wrong_format_error;
00547
00548
00549
00550 if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_type == ET_REL)
00551 goto got_wrong_format_error;
00552
00553
00554
00555
00556 if (i_ehdrp->e_shentsize != sizeof (x_shdr) && i_ehdrp->e_shnum != 0)
00557 goto got_wrong_format_error;
00558
00559
00560 if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_shnum != 0)
00561 goto got_wrong_format_error;
00562
00563 ebd = get_elf_backend_data (abfd);
00564
00565
00566
00567 if (ebd->elf_machine_code != i_ehdrp->e_machine
00568 && (ebd->elf_machine_alt1 == 0
00569 || i_ehdrp->e_machine != ebd->elf_machine_alt1)
00570 && (ebd->elf_machine_alt2 == 0
00571 || i_ehdrp->e_machine != ebd->elf_machine_alt2))
00572 {
00573 const bfd_target * const *target_ptr;
00574
00575 if (ebd->elf_machine_code != EM_NONE)
00576 goto got_wrong_format_error;
00577
00578
00579
00580 for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
00581 {
00582 const struct elf_backend_data *back;
00583
00584 if ((*target_ptr)->flavour != bfd_target_elf_flavour)
00585 continue;
00586 back = (const struct elf_backend_data *) (*target_ptr)->backend_data;
00587 if (back->elf_machine_code == i_ehdrp->e_machine
00588 || (back->elf_machine_alt1 != 0
00589 && back->elf_machine_alt1 == i_ehdrp->e_machine)
00590 || (back->elf_machine_alt2 != 0
00591 && back->elf_machine_alt2 == i_ehdrp->e_machine))
00592 {
00593
00594
00595 goto got_wrong_format_error;
00596 }
00597 }
00598 }
00599
00600 if (i_ehdrp->e_type == ET_EXEC)
00601 abfd->flags |= EXEC_P;
00602 else if (i_ehdrp->e_type == ET_DYN)
00603 abfd->flags |= DYNAMIC;
00604
00605 if (i_ehdrp->e_phnum > 0)
00606 abfd->flags |= D_PAGED;
00607
00608 if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0))
00609 {
00610
00611 if (ebd->elf_machine_code != EM_NONE)
00612 goto got_no_match;
00613 }
00614
00615
00616 bfd_set_start_address (abfd, i_ehdrp->e_entry);
00617
00618 if (i_ehdrp->e_shoff != 0)
00619 {
00620 bfd_signed_vma where = i_ehdrp->e_shoff;
00621
00622 if (where != (file_ptr) where)
00623 goto got_wrong_format_error;
00624
00625
00626 if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
00627 goto got_no_match;
00628
00629
00630
00631 if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
00632 goto got_no_match;
00633 elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
00634
00635
00636
00637 if (i_ehdrp->e_shnum == SHN_UNDEF)
00638 {
00639 i_ehdrp->e_shnum = i_shdr.sh_size;
00640 if (i_ehdrp->e_shnum != i_shdr.sh_size
00641 || i_ehdrp->e_shnum == 0)
00642 goto got_wrong_format_error;
00643 }
00644
00645
00646 if (i_ehdrp->e_shstrndx == SHN_XINDEX)
00647 {
00648 i_ehdrp->e_shstrndx = i_shdr.sh_link;
00649 if (i_ehdrp->e_shstrndx != i_shdr.sh_link)
00650 goto got_wrong_format_error;
00651 }
00652
00653
00654
00655 if (i_ehdrp->e_shnum != 1)
00656 {
00657
00658 if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr)
00659 || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr))
00660 goto got_wrong_format_error;
00661
00662 where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr);
00663 if (where != (file_ptr) where)
00664 goto got_wrong_format_error;
00665 if ((bfd_size_type) where <= i_ehdrp->e_shoff)
00666 goto got_wrong_format_error;
00667
00668 if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
00669 goto got_no_match;
00670 if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
00671 goto got_no_match;
00672
00673
00674 where = i_ehdrp->e_shoff + sizeof (x_shdr);
00675 if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
00676 goto got_no_match;
00677 }
00678 }
00679
00680
00681
00682 if (i_ehdrp->e_shnum != 0)
00683 {
00684 Elf_Internal_Shdr *shdrp;
00685 unsigned int num_sec;
00686
00687 amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum;
00688 i_shdrp = bfd_alloc (abfd, amt);
00689 if (!i_shdrp)
00690 goto got_no_match;
00691 num_sec = i_ehdrp->e_shnum;
00692 if (num_sec > SHN_LORESERVE)
00693 num_sec += SHN_HIRESERVE + 1 - SHN_LORESERVE;
00694 elf_numsections (abfd) = num_sec;
00695 amt = sizeof (i_shdrp) * num_sec;
00696 elf_elfsections (abfd) = bfd_alloc (abfd, amt);
00697 if (!elf_elfsections (abfd))
00698 goto got_no_match;
00699
00700 memcpy (i_shdrp, &i_shdr, sizeof (*i_shdrp));
00701 shdrp = i_shdrp;
00702 shindex = 0;
00703 if (num_sec > SHN_LORESERVE)
00704 {
00705 for ( ; shindex < SHN_LORESERVE; shindex++)
00706 elf_elfsections (abfd)[shindex] = shdrp++;
00707 for ( ; shindex < SHN_HIRESERVE + 1; shindex++)
00708 elf_elfsections (abfd)[shindex] = i_shdrp;
00709 }
00710 for ( ; shindex < num_sec; shindex++)
00711 elf_elfsections (abfd)[shindex] = shdrp++;
00712
00713
00714
00715 for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)
00716 {
00717 if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
00718 goto got_no_match;
00719 elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
00720
00721
00722 if (i_shdrp[shindex].sh_link >= num_sec
00723 || (i_shdrp[shindex].sh_link >= SHN_LORESERVE
00724 && i_shdrp[shindex].sh_link <= SHN_HIRESERVE))
00725 goto got_wrong_format_error;
00726
00727 if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK)
00728 || i_shdrp[shindex].sh_type == SHT_RELA
00729 || i_shdrp[shindex].sh_type == SHT_REL)
00730 && (i_shdrp[shindex].sh_info >= num_sec
00731 || (i_shdrp[shindex].sh_info >= SHN_LORESERVE
00732 && i_shdrp[shindex].sh_info <= SHN_HIRESERVE)))
00733 goto got_wrong_format_error;
00734
00735
00736
00737 if (i_shdrp[shindex].sh_size != 0
00738 && (i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0
00739 && i_shdrp[shindex].sh_type != SHT_NOBITS
00740 && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset)
00741 % ebd->minpagesize)
00742 != 0))
00743 abfd->flags &= ~D_PAGED;
00744 }
00745 }
00746
00747
00748 if (i_ehdrp->e_shnum != 0)
00749 {
00750 if (i_ehdrp->e_shstrndx >= elf_numsections (abfd)
00751 || (i_ehdrp->e_shstrndx >= SHN_LORESERVE
00752 && i_ehdrp->e_shstrndx <= SHN_HIRESERVE))
00753 goto got_wrong_format_error;
00754 }
00755 else if (i_ehdrp->e_shstrndx != 0)
00756 goto got_wrong_format_error;
00757
00758
00759 if (i_ehdrp->e_phnum == 0)
00760 elf_tdata (abfd)->phdr = NULL;
00761 else
00762 {
00763 Elf_Internal_Phdr *i_phdr;
00764 unsigned int i;
00765
00766 amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr);
00767 elf_tdata (abfd)->phdr = bfd_alloc (abfd, amt);
00768 if (elf_tdata (abfd)->phdr == NULL)
00769 goto got_no_match;
00770 if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
00771 goto got_no_match;
00772 i_phdr = elf_tdata (abfd)->phdr;
00773 for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)
00774 {
00775 Elf_External_Phdr x_phdr;
00776
00777 if (bfd_bread (&x_phdr, sizeof x_phdr, abfd) != sizeof x_phdr)
00778 goto got_no_match;
00779 elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
00780 }
00781 }
00782
00783 if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff != 0)
00784 {
00785 unsigned int num_sec;
00786
00787 shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx);
00788 if (!shstrtab)
00789 goto got_no_match;
00790
00791
00792
00793
00794
00795 num_sec = elf_numsections (abfd);
00796 for (shindex = 1; shindex < num_sec; shindex++)
00797 {
00798 if (! bfd_section_from_shdr (abfd, shindex))
00799 goto got_no_match;
00800 if (shindex == SHN_LORESERVE - 1)
00801 shindex += SHN_HIRESERVE + 1 - SHN_LORESERVE;
00802 }
00803
00804
00805 if (! _bfd_elf_setup_group_pointers (abfd))
00806 goto got_wrong_format_error;
00807 }
00808
00809
00810
00811 if (ebd->elf_backend_object_p)
00812 {
00813 if (! (*ebd->elf_backend_object_p) (abfd))
00814 goto got_wrong_format_error;
00815 }
00816
00817
00818
00819 for (s = abfd->sections; s != NULL; s = s->next)
00820 {
00821 if ((elf_section_data (s)->this_hdr.sh_type == SHT_REL
00822 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)
00823 && elf_section_data (s)->this_hdr.sh_info > 0)
00824 {
00825 unsigned long targ_index;
00826 asection *targ_sec;
00827
00828 targ_index = elf_section_data (s)->this_hdr.sh_info;
00829 targ_sec = bfd_section_from_elf_index (abfd, targ_index);
00830 if (targ_sec != NULL
00831 && (targ_sec->flags & SEC_DEBUGGING) != 0)
00832 s->flags |= SEC_DEBUGGING;
00833 }
00834 }
00835
00836 bfd_preserve_finish (abfd, &preserve);
00837 return abfd->xvec;
00838
00839 got_wrong_format_error:
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 bfd_set_error (bfd_error_wrong_format);
00850
00851 got_no_match:
00852 if (preserve.marker != NULL)
00853 bfd_preserve_restore (abfd, &preserve);
00854 return NULL;
00855 }
00856
00857
00858
00859
00860
00861 void
00862 elf_write_relocs (bfd *abfd, asection *sec, void *data)
00863 {
00864 bfd_boolean *failedp = data;
00865 Elf_Internal_Shdr *rela_hdr;
00866 bfd_vma addr_offset;
00867 void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
00868 size_t extsize;
00869 bfd_byte *dst_rela;
00870 unsigned int idx;
00871 asymbol *last_sym;
00872 int last_sym_idx;
00873
00874
00875 if (*failedp)
00876 return;
00877
00878 if ((sec->flags & SEC_RELOC) == 0)
00879 return;
00880
00881
00882
00883
00884
00885 if (sec->reloc_count == 0)
00886 return;
00887
00888 rela_hdr = &elf_section_data (sec)->rel_hdr;
00889
00890 rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
00891 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
00892 if (rela_hdr->contents == NULL)
00893 {
00894 *failedp = TRUE;
00895 return;
00896 }
00897
00898
00899 if (rela_hdr->sh_type == SHT_RELA)
00900 {
00901 swap_out = elf_swap_reloca_out;
00902 extsize = sizeof (Elf_External_Rela);
00903 }
00904 else if (rela_hdr->sh_type == SHT_REL)
00905 {
00906 swap_out = elf_swap_reloc_out;
00907 extsize = sizeof (Elf_External_Rel);
00908 }
00909 else
00910
00911
00912 abort ();
00913
00914
00915
00916
00917 addr_offset = 0;
00918 if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
00919 addr_offset = sec->vma;
00920
00921
00922 last_sym = 0;
00923 last_sym_idx = 0;
00924 dst_rela = rela_hdr->contents;
00925
00926 for (idx = 0; idx < sec->reloc_count; idx++, dst_rela += extsize)
00927 {
00928 Elf_Internal_Rela src_rela;
00929 arelent *ptr;
00930 asymbol *sym;
00931 int n;
00932
00933 ptr = sec->orelocation[idx];
00934 sym = *ptr->sym_ptr_ptr;
00935 if (sym == last_sym)
00936 n = last_sym_idx;
00937 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
00938 n = STN_UNDEF;
00939 else
00940 {
00941 last_sym = sym;
00942 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
00943 if (n < 0)
00944 {
00945 *failedp = TRUE;
00946 return;
00947 }
00948 last_sym_idx = n;
00949 }
00950
00951 if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
00952 && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
00953 && ! _bfd_elf_validate_reloc (abfd, ptr))
00954 {
00955 *failedp = TRUE;
00956 return;
00957 }
00958
00959 src_rela.r_offset = ptr->address + addr_offset;
00960 src_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
00961 src_rela.r_addend = ptr->addend;
00962 (*swap_out) (abfd, &src_rela, dst_rela);
00963 }
00964 }
00965
00966
00967
00968 int
00969 elf_write_out_phdrs (bfd *abfd,
00970 const Elf_Internal_Phdr *phdr,
00971 unsigned int count)
00972 {
00973 while (count--)
00974 {
00975 Elf_External_Phdr extphdr;
00976 elf_swap_phdr_out (abfd, phdr, &extphdr);
00977 if (bfd_bwrite (&extphdr, sizeof (Elf_External_Phdr), abfd)
00978 != sizeof (Elf_External_Phdr))
00979 return -1;
00980 phdr++;
00981 }
00982 return 0;
00983 }
00984
00985
00986
00987 bfd_boolean
00988 elf_write_shdrs_and_ehdr (bfd *abfd)
00989 {
00990 Elf_External_Ehdr x_ehdr;
00991 Elf_Internal_Ehdr *i_ehdrp;
00992 Elf_External_Shdr *x_shdrp;
00993 Elf_Internal_Shdr **i_shdrp;
00994 unsigned int count;
00995 bfd_size_type amt;
00996
00997 i_ehdrp = elf_elfheader (abfd);
00998 i_shdrp = elf_elfsections (abfd);
00999
01000
01001
01002 #if DEBUG & 1
01003 elf_debug_file (i_ehdrp);
01004 #endif
01005 elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr);
01006 amt = sizeof (x_ehdr);
01007 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
01008 || bfd_bwrite (&x_ehdr, amt, abfd) != amt)
01009 return FALSE;
01010
01011
01012
01013 if (i_ehdrp->e_shnum >= SHN_LORESERVE)
01014 i_shdrp[0]->sh_size = i_ehdrp->e_shnum;
01015 if (i_ehdrp->e_shstrndx >= SHN_LORESERVE)
01016 i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx;
01017
01018
01019 amt = i_ehdrp->e_shnum;
01020 amt *= sizeof (*x_shdrp);
01021 x_shdrp = bfd_alloc (abfd, amt);
01022 if (!x_shdrp)
01023 return FALSE;
01024
01025 for (count = 0; count < i_ehdrp->e_shnum; i_shdrp++, count++)
01026 {
01027 #if DEBUG & 2
01028 elf_debug_section (count, *i_shdrp);
01029 #endif
01030 elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count);
01031
01032 if (count == SHN_LORESERVE - 1)
01033 i_shdrp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
01034 }
01035 if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0
01036 || bfd_bwrite (x_shdrp, amt, abfd) != amt)
01037 return FALSE;
01038
01039
01040
01041 return TRUE;
01042 }
01043
01044 long
01045 elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
01046 {
01047 Elf_Internal_Shdr *hdr;
01048 Elf_Internal_Shdr *verhdr;
01049 unsigned long symcount;
01050 elf_symbol_type *sym;
01051 elf_symbol_type *symbase;
01052 Elf_Internal_Sym *isym;
01053 Elf_Internal_Sym *isymend;
01054 Elf_Internal_Sym *isymbuf = NULL;
01055 Elf_External_Versym *xver;
01056 Elf_External_Versym *xverbuf = NULL;
01057 const struct elf_backend_data *ebd;
01058 bfd_size_type amt;
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070 if (! dynamic)
01071 {
01072 hdr = &elf_tdata (abfd)->symtab_hdr;
01073 verhdr = NULL;
01074 }
01075 else
01076 {
01077 hdr = &elf_tdata (abfd)->dynsymtab_hdr;
01078 if (elf_dynversym (abfd) == 0)
01079 verhdr = NULL;
01080 else
01081 verhdr = &elf_tdata (abfd)->dynversym_hdr;
01082 if ((elf_tdata (abfd)->dynverdef_section != 0
01083 && elf_tdata (abfd)->verdef == NULL)
01084 || (elf_tdata (abfd)->dynverref_section != 0
01085 && elf_tdata (abfd)->verref == NULL))
01086 {
01087 if (!_bfd_elf_slurp_version_tables (abfd, FALSE))
01088 return -1;
01089 }
01090 }
01091
01092 ebd = get_elf_backend_data (abfd);
01093 symcount = hdr->sh_size / sizeof (Elf_External_Sym);
01094 if (symcount == 0)
01095 sym = symbase = NULL;
01096 else
01097 {
01098 isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0,
01099 NULL, NULL, NULL);
01100 if (isymbuf == NULL)
01101 return -1;
01102
01103 amt = symcount;
01104 amt *= sizeof (elf_symbol_type);
01105 symbase = bfd_zalloc (abfd, amt);
01106 if (symbase == (elf_symbol_type *) NULL)
01107 goto error_return;
01108
01109
01110 if (verhdr != NULL
01111 && verhdr->sh_size / sizeof (Elf_External_Versym) != symcount)
01112 {
01113 (*_bfd_error_handler)
01114 (_("%s: version count (%ld) does not match symbol count (%ld)"),
01115 abfd->filename,
01116 (long) (verhdr->sh_size / sizeof (Elf_External_Versym)),
01117 symcount);
01118
01119
01120
01121 verhdr = NULL;
01122 }
01123
01124 if (verhdr != NULL)
01125 {
01126 if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)
01127 goto error_return;
01128
01129 xverbuf = bfd_malloc (verhdr->sh_size);
01130 if (xverbuf == NULL && verhdr->sh_size != 0)
01131 goto error_return;
01132
01133 if (bfd_bread (xverbuf, verhdr->sh_size, abfd) != verhdr->sh_size)
01134 goto error_return;
01135 }
01136
01137
01138 xver = xverbuf;
01139 if (xver != NULL)
01140 ++xver;
01141 isymend = isymbuf + symcount;
01142 for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
01143 {
01144 memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
01145 sym->symbol.the_bfd = abfd;
01146
01147 sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym);
01148
01149 sym->symbol.value = isym->st_value;
01150
01151 if (isym->st_shndx == SHN_UNDEF)
01152 {
01153 sym->symbol.section = bfd_und_section_ptr;
01154 }
01155 else if (isym->st_shndx < SHN_LORESERVE
01156 || isym->st_shndx > SHN_HIRESERVE)
01157 {
01158 sym->symbol.section = bfd_section_from_elf_index (abfd,
01159 isym->st_shndx);
01160 if (sym->symbol.section == NULL)
01161 {
01162
01163
01164
01165 sym->symbol.section = bfd_abs_section_ptr;
01166 }
01167 }
01168 else if (isym->st_shndx == SHN_ABS)
01169 {
01170 sym->symbol.section = bfd_abs_section_ptr;
01171 }
01172 else if (isym->st_shndx == SHN_COMMON)
01173 {
01174 sym->symbol.section = bfd_com_section_ptr;
01175
01176
01177
01178
01179 sym->symbol.value = isym->st_size;
01180 }
01181 else
01182 sym->symbol.section = bfd_abs_section_ptr;
01183
01184
01185
01186 if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
01187 sym->symbol.value -= sym->symbol.section->vma;
01188
01189 switch (ELF_ST_BIND (isym->st_info))
01190 {
01191 case STB_LOCAL:
01192 sym->symbol.flags |= BSF_LOCAL;
01193 break;
01194 case STB_GLOBAL:
01195 if (isym->st_shndx != SHN_UNDEF && isym->st_shndx != SHN_COMMON)
01196 sym->symbol.flags |= BSF_GLOBAL;
01197 break;
01198 case STB_WEAK:
01199 sym->symbol.flags |= BSF_WEAK;
01200 break;
01201 }
01202
01203 switch (ELF_ST_TYPE (isym->st_info))
01204 {
01205 case STT_SECTION:
01206 sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING;
01207 break;
01208 case STT_FILE:
01209 sym->symbol.flags |= BSF_FILE | BSF_DEBUGGING;
01210 break;
01211 case STT_FUNC:
01212 sym->symbol.flags |= BSF_FUNCTION;
01213 break;
01214 case STT_OBJECT:
01215 sym->symbol.flags |= BSF_OBJECT;
01216 break;
01217 case STT_TLS:
01218 sym->symbol.flags |= BSF_THREAD_LOCAL;
01219 break;
01220 }
01221
01222 if (dynamic)
01223 sym->symbol.flags |= BSF_DYNAMIC;
01224
01225 if (xver != NULL)
01226 {
01227 Elf_Internal_Versym iversym;
01228
01229 _bfd_elf_swap_versym_in (abfd, xver, &iversym);
01230 sym->version = iversym.vs_vers;
01231 xver++;
01232 }
01233
01234
01235 if (ebd->elf_backend_symbol_processing)
01236 (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
01237 }
01238 }
01239
01240
01241 if (ebd->elf_backend_symbol_table_processing)
01242 (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
01243
01244
01245
01246 symcount = sym - symbase;
01247
01248
01249 if (symptrs)
01250 {
01251 long l = symcount;
01252
01253 sym = symbase;
01254 while (l-- > 0)
01255 {
01256 *symptrs++ = &sym->symbol;
01257 sym++;
01258 }
01259 *symptrs = 0;
01260 }
01261
01262 if (xverbuf != NULL)
01263 free (xverbuf);
01264 if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
01265 free (isymbuf);
01266 return symcount;
01267
01268 error_return:
01269 if (xverbuf != NULL)
01270 free (xverbuf);
01271 if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
01272 free (isymbuf);
01273 return -1;
01274 }
01275
01276
01277
01278
01279 static bfd_boolean
01280 elf_slurp_reloc_table_from_section (bfd *abfd,
01281 asection *asect,
01282 Elf_Internal_Shdr *rel_hdr,
01283 bfd_size_type reloc_count,
01284 arelent *relents,
01285 asymbol **symbols,
01286 bfd_boolean dynamic)
01287 {
01288 const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
01289 void *allocated = NULL;
01290 bfd_byte *native_relocs;
01291 arelent *relent;
01292 unsigned int i;
01293 int entsize;
01294 unsigned int symcount;
01295
01296 allocated = bfd_malloc (rel_hdr->sh_size);
01297 if (allocated == NULL)
01298 goto error_return;
01299
01300 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
01301 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
01302 != rel_hdr->sh_size))
01303 goto error_return;
01304
01305 native_relocs = allocated;
01306
01307 entsize = rel_hdr->sh_entsize;
01308 BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
01309 || entsize == sizeof (Elf_External_Rela));
01310
01311 if (dynamic)
01312 symcount = bfd_get_dynamic_symcount (abfd);
01313 else
01314 symcount = bfd_get_symcount (abfd);
01315
01316 for (i = 0, relent = relents;
01317 i < reloc_count;
01318 i++, relent++, native_relocs += entsize)
01319 {
01320 Elf_Internal_Rela rela;
01321
01322 if (entsize == sizeof (Elf_External_Rela))
01323 elf_swap_reloca_in (abfd, native_relocs, &rela);
01324 else
01325 elf_swap_reloc_in (abfd, native_relocs, &rela);
01326
01327
01328
01329
01330
01331 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
01332 relent->address = rela.r_offset;
01333 else
01334 relent->address = rela.r_offset - asect->vma;
01335
01336 if (ELF_R_SYM (rela.r_info) == 0)
01337 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
01338 else if (ELF_R_SYM (rela.r_info) > symcount)
01339 {
01340 (*_bfd_error_handler)
01341 (_("%s(%s): relocation %d has invalid symbol index %ld"),
01342 abfd->filename, asect->name, i, ELF_R_SYM (rela.r_info));
01343 relent->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
01344 }
01345 else
01346 {
01347 asymbol **ps, *s;
01348
01349 ps = symbols + ELF_R_SYM (rela.r_info) - 1;
01350 s = *ps;
01351
01352 relent->sym_ptr_ptr = ps;
01353 }
01354
01355 relent->addend = rela.r_addend;
01356
01357 if ((entsize == sizeof (Elf_External_Rela)
01358 && ebd->elf_info_to_howto != NULL)
01359 || ebd->elf_info_to_howto_rel == NULL)
01360 (*ebd->elf_info_to_howto) (abfd, relent, &rela);
01361 else
01362 (*ebd->elf_info_to_howto_rel) (abfd, relent, &rela);
01363 }
01364
01365 if (allocated != NULL)
01366 free (allocated);
01367
01368 return TRUE;
01369
01370 error_return:
01371 if (allocated != NULL)
01372 free (allocated);
01373 return FALSE;
01374 }
01375
01376
01377
01378 bfd_boolean
01379 elf_slurp_reloc_table (bfd *abfd,
01380 asection *asect,
01381 asymbol **symbols,
01382 bfd_boolean dynamic)
01383 {
01384 struct bfd_elf_section_data * const d = elf_section_data (asect);
01385 Elf_Internal_Shdr *rel_hdr;
01386 Elf_Internal_Shdr *rel_hdr2;
01387 bfd_size_type reloc_count;
01388 bfd_size_type reloc_count2;
01389 arelent *relents;
01390 bfd_size_type amt;
01391
01392 if (asect->relocation != NULL)
01393 return TRUE;
01394
01395 if (! dynamic)
01396 {
01397 if ((asect->flags & SEC_RELOC) == 0
01398 || asect->reloc_count == 0)
01399 return TRUE;
01400
01401 rel_hdr = &d->rel_hdr;
01402 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
01403 rel_hdr2 = d->rel_hdr2;
01404 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
01405
01406 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
01407 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
01408 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
01409
01410 }
01411 else
01412 {
01413
01414
01415
01416
01417 if (asect->size == 0)
01418 return TRUE;
01419
01420 rel_hdr = &d->this_hdr;
01421 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
01422 rel_hdr2 = NULL;
01423 reloc_count2 = 0;
01424 }
01425
01426 amt = (reloc_count + reloc_count2) * sizeof (arelent);
01427 relents = bfd_alloc (abfd, amt);
01428 if (relents == NULL)
01429 return FALSE;
01430
01431 if (!elf_slurp_reloc_table_from_section (abfd, asect,
01432 rel_hdr, reloc_count,
01433 relents,
01434 symbols, dynamic))
01435 return FALSE;
01436
01437 if (rel_hdr2
01438 && !elf_slurp_reloc_table_from_section (abfd, asect,
01439 rel_hdr2, reloc_count2,
01440 relents + reloc_count,
01441 symbols, dynamic))
01442 return FALSE;
01443
01444 asect->relocation = relents;
01445 return TRUE;
01446 }
01447
01448 #ifdef DEBUG
01449 static void
01450 elf_debug_section (int num, Elf_Internal_Shdr *hdr)
01451 {
01452 fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num,
01453 hdr->bfd_section != NULL ? hdr->bfd_section->name : "",
01454 (long) hdr);
01455 fprintf (stderr,
01456 "sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n",
01457 (long) hdr->sh_name,
01458 (long) hdr->sh_type,
01459 (long) hdr->sh_flags);
01460 fprintf (stderr,
01461 "sh_addr = %ld\tsh_offset = %ld\tsh_size = %ld\n",
01462 (long) hdr->sh_addr,
01463 (long) hdr->sh_offset,
01464 (long) hdr->sh_size);
01465 fprintf (stderr,
01466 "sh_link = %ld\tsh_info = %ld\tsh_addralign = %ld\n",
01467 (long) hdr->sh_link,
01468 (long) hdr->sh_info,
01469 (long) hdr->sh_addralign);
01470 fprintf (stderr, "sh_entsize = %ld\n",
01471 (long) hdr->sh_entsize);
01472 fflush (stderr);
01473 }
01474
01475 static void
01476 elf_debug_file (Elf_Internal_Ehdr *ehdrp)
01477 {
01478 fprintf (stderr, "e_entry = 0x%.8lx\n", (long) ehdrp->e_entry);
01479 fprintf (stderr, "e_phoff = %ld\n", (long) ehdrp->e_phoff);
01480 fprintf (stderr, "e_phnum = %ld\n", (long) ehdrp->e_phnum);
01481 fprintf (stderr, "e_phentsize = %ld\n", (long) ehdrp->e_phentsize);
01482 fprintf (stderr, "e_shoff = %ld\n", (long) ehdrp->e_shoff);
01483 fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum);
01484 fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize);
01485 }
01486
01487 static char *
01488 elf_symbol_flags (flagword flags)
01489 {
01490 static char buffer[1024];
01491
01492 buffer[0] = '\0';
01493 if (flags & BSF_LOCAL)
01494 strcat (buffer, " local");
01495
01496 if (flags & BSF_GLOBAL)
01497 strcat (buffer, " global");
01498
01499 if (flags & BSF_DEBUGGING)
01500 strcat (buffer, " debug");
01501
01502 if (flags & BSF_FUNCTION)
01503 strcat (buffer, " function");
01504
01505 if (flags & BSF_KEEP)
01506 strcat (buffer, " keep");
01507
01508 if (flags & BSF_KEEP_G)
01509 strcat (buffer, " keep_g");
01510
01511 if (flags & BSF_WEAK)
01512 strcat (buffer, " weak");
01513
01514 if (flags & BSF_SECTION_SYM)
01515 strcat (buffer, " section-sym");
01516
01517 if (flags & BSF_OLD_COMMON)
01518 strcat (buffer, " old-common");
01519
01520 if (flags & BSF_NOT_AT_END)
01521 strcat (buffer, " not-at-end");
01522
01523 if (flags & BSF_CONSTRUCTOR)
01524 strcat (buffer, " constructor");
01525
01526 if (flags & BSF_WARNING)
01527 strcat (buffer, " warning");
01528
01529 if (flags & BSF_INDIRECT)
01530 strcat (buffer, " indirect");
01531
01532 if (flags & BSF_FILE)
01533 strcat (buffer, " file");
01534
01535 if (flags & DYNAMIC)
01536 strcat (buffer, " dynamic");
01537
01538 if (flags & ~(BSF_LOCAL
01539 | BSF_GLOBAL
01540 | BSF_DEBUGGING
01541 | BSF_FUNCTION
01542 | BSF_KEEP
01543 | BSF_KEEP_G
01544 | BSF_WEAK
01545 | BSF_SECTION_SYM
01546 | BSF_OLD_COMMON
01547 | BSF_NOT_AT_END
01548 | BSF_CONSTRUCTOR
01549 | BSF_WARNING
01550 | BSF_INDIRECT
01551 | BSF_FILE
01552 | BSF_DYNAMIC))
01553 strcat (buffer, " unknown-bits");
01554
01555 return buffer;
01556 }
01557 #endif
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572 bfd *
01573 NAME(_bfd_elf,bfd_from_remote_memory)
01574 (bfd *templ,
01575 bfd_vma ehdr_vma,
01576 bfd_vma *loadbasep,
01577 int (*target_read_memory) (bfd_vma, bfd_byte *, int))
01578 {
01579 Elf_External_Ehdr x_ehdr;
01580 Elf_Internal_Ehdr i_ehdr;
01581 Elf_External_Phdr *x_phdrs;
01582 Elf_Internal_Phdr *i_phdrs, *last_phdr;
01583 bfd *nbfd;
01584 struct bfd_in_memory *bim;
01585 int contents_size;
01586 bfd_byte *contents;
01587 int err;
01588 unsigned int i;
01589 bfd_vma loadbase;
01590
01591
01592 err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
01593 if (err)
01594 {
01595 bfd_set_error (bfd_error_system_call);
01596 errno = err;
01597 return NULL;
01598 }
01599
01600
01601
01602
01603
01604 if (! elf_file_p (&x_ehdr)
01605 || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
01606 || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
01607 {
01608 bfd_set_error (bfd_error_wrong_format);
01609 return NULL;
01610 }
01611
01612
01613 switch (x_ehdr.e_ident[EI_DATA])
01614 {
01615 case ELFDATA2MSB:
01616 if (! bfd_header_big_endian (templ))
01617 {
01618 bfd_set_error (bfd_error_wrong_format);
01619 return NULL;
01620 }
01621 break;
01622 case ELFDATA2LSB:
01623 if (! bfd_header_little_endian (templ))
01624 {
01625 bfd_set_error (bfd_error_wrong_format);
01626 return NULL;
01627 }
01628 break;
01629 case ELFDATANONE:
01630 default:
01631 bfd_set_error (bfd_error_wrong_format);
01632 return NULL;
01633 }
01634
01635 elf_swap_ehdr_in (templ, &x_ehdr, &i_ehdr);
01636
01637
01638
01639
01640 if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0)
01641 {
01642 bfd_set_error (bfd_error_wrong_format);
01643 return NULL;
01644 }
01645
01646 x_phdrs = bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs));
01647 if (x_phdrs == NULL)
01648 {
01649 bfd_set_error (bfd_error_no_memory);
01650 return NULL;
01651 }
01652 err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs,
01653 i_ehdr.e_phnum * sizeof x_phdrs[0]);
01654 if (err)
01655 {
01656 free (x_phdrs);
01657 bfd_set_error (bfd_error_system_call);
01658 errno = err;
01659 return NULL;
01660 }
01661 i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum];
01662
01663 contents_size = 0;
01664 last_phdr = NULL;
01665 loadbase = ehdr_vma;
01666 for (i = 0; i < i_ehdr.e_phnum; ++i)
01667 {
01668 elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]);
01669 if (i_phdrs[i].p_type == PT_LOAD)
01670 {
01671 bfd_vma segment_end;
01672 segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
01673 + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
01674 if (segment_end > (bfd_vma) contents_size)
01675 contents_size = segment_end;
01676
01677 if ((i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0)
01678 loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align);
01679
01680 last_phdr = &i_phdrs[i];
01681 }
01682 }
01683 if (last_phdr == NULL)
01684 {
01685
01686 free (x_phdrs);
01687 bfd_set_error (bfd_error_wrong_format);
01688 return NULL;
01689 }
01690
01691
01692
01693
01694 if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz
01695 && (bfd_vma) contents_size >= (i_ehdr.e_shoff
01696 + i_ehdr.e_shnum * i_ehdr.e_shentsize))
01697 {
01698 contents_size = last_phdr->p_offset + last_phdr->p_filesz;
01699 if ((bfd_vma) contents_size < (i_ehdr.e_shoff
01700 + i_ehdr.e_shnum * i_ehdr.e_shentsize))
01701 contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize;
01702 }
01703 else
01704 contents_size = last_phdr->p_offset + last_phdr->p_filesz;
01705
01706
01707 contents = bfd_zmalloc (contents_size);
01708 if (contents == NULL)
01709 {
01710 free (x_phdrs);
01711 bfd_set_error (bfd_error_no_memory);
01712 return NULL;
01713 }
01714
01715 for (i = 0; i < i_ehdr.e_phnum; ++i)
01716 if (i_phdrs[i].p_type == PT_LOAD)
01717 {
01718 bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align;
01719 bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
01720 + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
01721 if (end > (bfd_vma) contents_size)
01722 end = contents_size;
01723 err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr)
01724 & -i_phdrs[i].p_align,
01725 contents + start, end - start);
01726 if (err)
01727 {
01728 free (x_phdrs);
01729 free (contents);
01730 bfd_set_error (bfd_error_system_call);
01731 errno = err;
01732 return NULL;
01733 }
01734 }
01735 free (x_phdrs);
01736
01737
01738
01739 if ((bfd_vma) contents_size < (i_ehdr.e_shoff
01740 + i_ehdr.e_shnum * i_ehdr.e_shentsize))
01741 {
01742 memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff);
01743 memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum);
01744 memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx);
01745 }
01746
01747
01748
01749 memcpy (contents, &x_ehdr, sizeof x_ehdr);
01750
01751
01752 bim = bfd_malloc (sizeof (struct bfd_in_memory));
01753 if (bim == NULL)
01754 {
01755 free (contents);
01756 bfd_set_error (bfd_error_no_memory);
01757 return NULL;
01758 }
01759 nbfd = _bfd_new_bfd ();
01760 if (nbfd == NULL)
01761 {
01762 free (bim);
01763 free (contents);
01764 bfd_set_error (bfd_error_no_memory);
01765 return NULL;
01766 }
01767 nbfd->filename = "<in-memory>";
01768 nbfd->xvec = templ->xvec;
01769 bim->size = contents_size;
01770 bim->buffer = contents;
01771 nbfd->iostream = bim;
01772 nbfd->flags = BFD_IN_MEMORY;
01773 nbfd->direction = read_direction;
01774 nbfd->mtime = time (NULL);
01775 nbfd->mtime_set = TRUE;
01776
01777 if (loadbasep)
01778 *loadbasep = loadbase;
01779 return nbfd;
01780 }
01781
01782 #include "elfcore.h"
01783
01784
01785 const struct elf_size_info NAME(_bfd_elf,size_info) = {
01786 sizeof (Elf_External_Ehdr),
01787 sizeof (Elf_External_Phdr),
01788 sizeof (Elf_External_Shdr),
01789 sizeof (Elf_External_Rel),
01790 sizeof (Elf_External_Rela),
01791 sizeof (Elf_External_Sym),
01792 sizeof (Elf_External_Dyn),
01793 sizeof (Elf_External_Note),
01794 4,
01795 1,
01796 ARCH_SIZE, LOG_FILE_ALIGN,
01797 ELFCLASS, EV_CURRENT,
01798 elf_write_out_phdrs,
01799 elf_write_shdrs_and_ehdr,
01800 elf_write_relocs,
01801 elf_swap_symbol_in,
01802 elf_swap_symbol_out,
01803 elf_slurp_reloc_table,
01804 elf_slurp_symbol_table,
01805 elf_swap_dyn_in,
01806 elf_swap_dyn_out,
01807 elf_swap_reloc_in,
01808 elf_swap_reloc_out,
01809 elf_swap_reloca_in,
01810 elf_swap_reloca_out
01811 };