X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felfcode.h;h=fd0dacad5c6679f654cfad5b4fd1bfa0c61a6270;hb=f075ee0c61d4b9982a7390d3760f764185f5d36e;hp=c1ef912d727529993404d02e118c43eb18df7ead;hpb=947216bf8f343c1440e85633b5bf2f2394f87bc4;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfcode.h b/bfd/elfcode.h index c1ef912d72..fd0dacad5c 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1,6 +1,6 @@ /* ELF executable support for BFD. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Written by Fred Fish @ Cygnus Support, from information published in "UNIX System V Release 4, Programmers Guide: ANSI C and @@ -102,9 +102,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound) #define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc) #define elf_slurp_symbol_table NAME(bfd_elf,slurp_symbol_table) -#define elf_get_symtab NAME(bfd_elf,get_symtab) +#define elf_canonicalize_symtab NAME(bfd_elf,canonicalize_symtab) #define elf_canonicalize_dynamic_symtab \ NAME(bfd_elf,canonicalize_dynamic_symtab) +#define elf_get_synthetic_symtab \ + NAME(bfd_elf,get_synthetic_symtab) #define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol) #define elf_get_symbol_info NAME(bfd_elf,get_symbol_info) #define elf_get_lineno NAME(bfd_elf,get_lineno) @@ -115,28 +117,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto) #define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel) #define elf_find_section NAME(bfd_elf,find_section) -#define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols) -#define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry) #define elf_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr) #define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs) #define elf_write_relocs NAME(bfd_elf,write_relocs) #define elf_slurp_reloc_table NAME(bfd_elf,slurp_reloc_table) -#define elf_link_create_dynamic_sections \ - NAME(bfd_elf,link_create_dynamic_sections) -#define elf_bfd_discard_info NAME(bfd_elf,discard_info) -#define elf_reloc_symbol_deleted_p NAME(_bfd_elf,reloc_symbol_deleted_p) -#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol -#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link) -#define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section) -#define elf_finish_pointer_linker_section NAME(bfd_elf,finish_pointer_linker_section) -#define elf_gc_sections NAME(_bfd_elf,gc_sections) -#define elf_gc_common_finalize_got_offsets \ - NAME(_bfd_elf,gc_common_finalize_got_offsets) -#define elf_gc_common_final_link NAME(_bfd_elf,gc_common_final_link) -#define elf_gc_record_vtinherit NAME(_bfd_elf,gc_record_vtinherit) -#define elf_gc_record_vtentry NAME(_bfd_elf,gc_record_vtentry) -#define elf_link_record_local_dynamic_symbol \ - NAME(_bfd_elf,link_record_local_dynamic_symbol) #if ARCH_SIZE == 64 #define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y) @@ -155,31 +139,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define LOG_FILE_ALIGN 2 #endif -/* Static functions */ - -static void elf_swap_ehdr_in - PARAMS ((bfd *, const Elf_External_Ehdr *, Elf_Internal_Ehdr *)); -static void elf_swap_ehdr_out - PARAMS ((bfd *, const Elf_Internal_Ehdr *, Elf_External_Ehdr *)); -static void elf_swap_shdr_in - PARAMS ((bfd *, const Elf_External_Shdr *, Elf_Internal_Shdr *)); -static void elf_swap_shdr_out - PARAMS ((bfd *, const Elf_Internal_Shdr *, Elf_External_Shdr *)); - -#define elf_stringtab_init _bfd_elf_stringtab_init - -#define section_from_elf_index bfd_section_from_elf_index - -static boolean elf_slurp_reloc_table_from_section - PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, - arelent *, asymbol **, boolean)); - -static boolean elf_file_p PARAMS ((Elf_External_Ehdr *)); - #ifdef DEBUG -static void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *)); -static void elf_debug_file PARAMS ((Elf_Internal_Ehdr *)); -static char *elf_symbol_flags PARAMS ((flagword)); +static void elf_debug_section (int, Elf_Internal_Shdr *); +static void elf_debug_file (Elf_Internal_Ehdr *); +static char *elf_symbol_flags (flagword); #endif /* Structure swapping routines */ @@ -203,14 +166,13 @@ static char *elf_symbol_flags PARAMS ((flagword)); format. */ void -elf_swap_symbol_in (abfd, psrc, pshn, dst) - bfd *abfd; - const PTR psrc; - const PTR pshn; - Elf_Internal_Sym *dst; +elf_swap_symbol_in (bfd *abfd, + const void *psrc, + const void *pshn, + Elf_Internal_Sym *dst) { - const Elf_External_Sym *src = (const Elf_External_Sym *) psrc; - const Elf_External_Sym_Shndx *shndx = (const Elf_External_Sym_Shndx *) pshn; + const Elf_External_Sym *src = psrc; + const Elf_External_Sym_Shndx *shndx = pshn; int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; dst->st_name = H_GET_32 (abfd, src->st_name); @@ -234,14 +196,13 @@ elf_swap_symbol_in (abfd, psrc, pshn, dst) format. */ void -elf_swap_symbol_out (abfd, src, cdst, shndx) - bfd *abfd; - const Elf_Internal_Sym *src; - PTR cdst; - PTR shndx; +elf_swap_symbol_out (bfd *abfd, + const Elf_Internal_Sym *src, + void *cdst, + void *shndx) { unsigned int tmp; - Elf_External_Sym *dst = (Elf_External_Sym *) cdst; + Elf_External_Sym *dst = cdst; H_PUT_32 (abfd, src->st_name, dst->st_name); H_PUT_WORD (abfd, src->st_value, dst->st_value); H_PUT_WORD (abfd, src->st_size, dst->st_size); @@ -262,10 +223,9 @@ elf_swap_symbol_out (abfd, src, cdst, shndx) internal format. */ static void -elf_swap_ehdr_in (abfd, src, dst) - bfd *abfd; - const Elf_External_Ehdr *src; - Elf_Internal_Ehdr *dst; +elf_swap_ehdr_in (bfd *abfd, + const Elf_External_Ehdr *src, + Elf_Internal_Ehdr *dst) { int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; memcpy (dst->e_ident, src->e_ident, EI_NIDENT); @@ -291,10 +251,9 @@ elf_swap_ehdr_in (abfd, src, dst) external format. */ static void -elf_swap_ehdr_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Ehdr *src; - Elf_External_Ehdr *dst; +elf_swap_ehdr_out (bfd *abfd, + const Elf_Internal_Ehdr *src, + Elf_External_Ehdr *dst) { unsigned int tmp; int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; @@ -328,10 +287,9 @@ elf_swap_ehdr_out (abfd, src, dst) ELF section header table entry in internal format. */ static void -elf_swap_shdr_in (abfd, src, dst) - bfd *abfd; - const Elf_External_Shdr *src; - Elf_Internal_Shdr *dst; +elf_swap_shdr_in (bfd *abfd, + const Elf_External_Shdr *src, + Elf_Internal_Shdr *dst) { int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; @@ -356,10 +314,9 @@ elf_swap_shdr_in (abfd, src, dst) ELF section header table entry in external format. */ static void -elf_swap_shdr_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Shdr *src; - Elf_External_Shdr *dst; +elf_swap_shdr_out (bfd *abfd, + const Elf_Internal_Shdr *src, + Elf_External_Shdr *dst) { /* note that all elements of dst are *arrays of unsigned char* already... */ H_PUT_32 (abfd, src->sh_name, dst->sh_name); @@ -378,10 +335,9 @@ elf_swap_shdr_out (abfd, src, dst) ELF program header table entry in internal format. */ void -elf_swap_phdr_in (abfd, src, dst) - bfd *abfd; - const Elf_External_Phdr *src; - Elf_Internal_Phdr *dst; +elf_swap_phdr_in (bfd *abfd, + const Elf_External_Phdr *src, + Elf_Internal_Phdr *dst) { int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; @@ -404,10 +360,9 @@ elf_swap_phdr_in (abfd, src, dst) } void -elf_swap_phdr_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Phdr *src; - Elf_External_Phdr *dst; +elf_swap_phdr_out (bfd *abfd, + const Elf_Internal_Phdr *src, + Elf_External_Phdr *dst) { /* note that all elements of dst are *arrays of unsigned char* already... */ H_PUT_32 (abfd, src->p_type, dst->p_type); @@ -422,10 +377,9 @@ elf_swap_phdr_out (abfd, src, dst) /* Translate an ELF reloc from external format to internal format. */ void -elf_swap_reloc_in (abfd, s, dst) - bfd *abfd; - const bfd_byte *s; - Elf_Internal_Rela *dst; +elf_swap_reloc_in (bfd *abfd, + const bfd_byte *s, + Elf_Internal_Rela *dst) { const Elf_External_Rel *src = (const Elf_External_Rel *) s; dst->r_offset = H_GET_WORD (abfd, src->r_offset); @@ -434,10 +388,9 @@ elf_swap_reloc_in (abfd, s, dst) } void -elf_swap_reloca_in (abfd, s, dst) - bfd *abfd; - const bfd_byte *s; - Elf_Internal_Rela *dst; +elf_swap_reloca_in (bfd *abfd, + const bfd_byte *s, + Elf_Internal_Rela *dst) { const Elf_External_Rela *src = (const Elf_External_Rela *) s; dst->r_offset = H_GET_WORD (abfd, src->r_offset); @@ -447,10 +400,9 @@ elf_swap_reloca_in (abfd, s, dst) /* Translate an ELF reloc from internal format to external format. */ void -elf_swap_reloc_out (abfd, src, d) - bfd *abfd; - const Elf_Internal_Rela *src; - bfd_byte *d; +elf_swap_reloc_out (bfd *abfd, + const Elf_Internal_Rela *src, + bfd_byte *d) { Elf_External_Rel *dst = (Elf_External_Rel *) d; H_PUT_WORD (abfd, src->r_offset, dst->r_offset); @@ -458,10 +410,9 @@ elf_swap_reloc_out (abfd, src, d) } void -elf_swap_reloca_out (abfd, src, d) - bfd *abfd; - const Elf_Internal_Rela *src; - bfd_byte *d; +elf_swap_reloca_out (bfd *abfd, + const Elf_Internal_Rela *src, + bfd_byte *d) { Elf_External_Rela *dst = (Elf_External_Rela *) d; H_PUT_WORD (abfd, src->r_offset, dst->r_offset); @@ -469,25 +420,23 @@ elf_swap_reloca_out (abfd, src, d) H_PUT_SIGNED_WORD (abfd, src->r_addend, dst->r_addend); } -INLINE void -elf_swap_dyn_in (abfd, p, dst) - bfd *abfd; - const PTR p; - Elf_Internal_Dyn *dst; +void +elf_swap_dyn_in (bfd *abfd, + const void *p, + Elf_Internal_Dyn *dst) { - const Elf_External_Dyn *src = (const Elf_External_Dyn *) p; + const Elf_External_Dyn *src = p; dst->d_tag = H_GET_WORD (abfd, src->d_tag); dst->d_un.d_val = H_GET_WORD (abfd, src->d_un.d_val); } -INLINE void -elf_swap_dyn_out (abfd, src, p) - bfd *abfd; - const Elf_Internal_Dyn *src; - PTR p; +void +elf_swap_dyn_out (bfd *abfd, + const Elf_Internal_Dyn *src, + void *p) { - Elf_External_Dyn *dst = (Elf_External_Dyn *) p; + Elf_External_Dyn *dst = p; H_PUT_WORD (abfd, src->d_tag, dst->d_tag); H_PUT_WORD (abfd, src->d_un.d_val, dst->d_un.d_val); @@ -500,9 +449,8 @@ elf_swap_dyn_out (abfd, src, p) First we validate the file by reading in the ELF header and checking the magic number. */ -static INLINE boolean -elf_file_p (x_ehdrp) - Elf_External_Ehdr *x_ehdrp; +static inline bfd_boolean +elf_file_p (Elf_External_Ehdr *x_ehdrp) { return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0) && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1) @@ -519,8 +467,7 @@ elf_file_p (x_ehdrp) file does not match the target vector. */ const bfd_target * -elf_object_p (abfd) - bfd *abfd; +elf_object_p (bfd *abfd) { Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ @@ -528,8 +475,7 @@ elf_object_p (abfd) Elf_Internal_Shdr i_shdr; Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ unsigned int shindex; - char *shstrtab; /* Internal copy of section header stringtab */ - struct elf_backend_data *ebd; + const struct elf_backend_data *ebd; struct bfd_preserve preserve; asection *s; bfd_size_type amt; @@ -538,8 +484,7 @@ elf_object_p (abfd) /* Read in the ELF header in external format. */ - if (bfd_bread ((PTR) & x_ehdr, (bfd_size_type) sizeof (x_ehdr), abfd) - != sizeof (x_ehdr)) + if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr)) { if (bfd_get_error () != bfd_error_system_call) goto got_wrong_format_error; @@ -574,17 +519,15 @@ elf_object_p (abfd) goto got_wrong_format_error; } + if (!bfd_preserve_save (abfd, &preserve)) + goto got_no_match; + /* Allocate an instance of the elf_obj_tdata structure and hook it up to the tdata pointer in the bfd. */ - amt = sizeof (struct elf_obj_tdata); - preserve.marker = bfd_zalloc (abfd, amt); - if (preserve.marker == NULL) - goto got_no_match; - if (!bfd_preserve_save (abfd, &preserve)) + if (! (*abfd->xvec->_bfd_set_format[bfd_object]) (abfd)) goto got_no_match; - - elf_tdata (abfd) = preserve.marker; + preserve.marker = elf_tdata (abfd); /* Now that we know the byte order, swap in the rest of the header */ i_ehdrp = elf_elfheader (abfd); @@ -631,11 +574,11 @@ elf_object_p (abfd) for which we do not have a specific backend. */ for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++) { - struct elf_backend_data *back; + const struct elf_backend_data *back; if ((*target_ptr)->flavour != bfd_target_elf_flavour) continue; - back = (struct elf_backend_data *) (*target_ptr)->backend_data; + back = (const struct elf_backend_data *) (*target_ptr)->backend_data; if (back->elf_machine_code == i_ehdrp->e_machine || (back->elf_machine_alt1 != 0 && back->elf_machine_alt1 == i_ehdrp->e_machine) @@ -675,8 +618,7 @@ elf_object_p (abfd) /* Read the first section header at index 0, and convert to internal form. */ - if (bfd_bread ((PTR) & x_shdr, (bfd_size_type) sizeof x_shdr, abfd) - != sizeof (x_shdr)) + if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) goto got_no_match; elf_swap_shdr_in (abfd, &x_shdr, &i_shdr); @@ -698,7 +640,7 @@ elf_object_p (abfd) unsigned int num_sec; amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum; - i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt); + i_shdrp = bfd_alloc (abfd, amt); if (!i_shdrp) goto got_no_match; num_sec = i_ehdrp->e_shnum; @@ -706,7 +648,7 @@ elf_object_p (abfd) num_sec += SHN_HIRESERVE + 1 - SHN_LORESERVE; elf_numsections (abfd) = num_sec; amt = sizeof (i_shdrp) * num_sec; - elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt); + elf_elfsections (abfd) = bfd_alloc (abfd, amt); if (!elf_elfsections (abfd)) goto got_no_match; @@ -727,8 +669,7 @@ elf_object_p (abfd) to internal form. */ for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++) { - if (bfd_bread ((PTR) & x_shdr, (bfd_size_type) sizeof x_shdr, abfd) - != sizeof (x_shdr)) + if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) goto got_no_match; elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); @@ -738,18 +679,12 @@ elf_object_p (abfd) && (i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0 && i_shdrp[shindex].sh_type != SHT_NOBITS && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset) - % ebd->maxpagesize) + % ebd->minpagesize) != 0)) abfd->flags &= ~D_PAGED; } } - if (i_ehdrp->e_shstrndx && i_ehdrp->e_shoff) - { - if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx)) - goto got_no_match; - } - /* Read in the program headers. */ if (i_ehdrp->e_phnum == 0) elf_tdata (abfd)->phdr = NULL; @@ -759,7 +694,7 @@ elf_object_p (abfd) unsigned int i; amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr); - elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt); + elf_tdata (abfd)->phdr = bfd_alloc (abfd, amt); if (elf_tdata (abfd)->phdr == NULL) goto got_no_match; if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0) @@ -769,27 +704,16 @@ elf_object_p (abfd) { Elf_External_Phdr x_phdr; - if (bfd_bread ((PTR) &x_phdr, (bfd_size_type) sizeof x_phdr, abfd) - != sizeof x_phdr) + if (bfd_bread (&x_phdr, sizeof x_phdr, abfd) != sizeof x_phdr) goto got_no_match; elf_swap_phdr_in (abfd, &x_phdr, i_phdr); } } - /* Read in the string table containing the names of the sections. We - will need the base pointer to this table later. */ - /* We read this inline now, so that we don't have to go through - bfd_section_from_shdr with it (since this particular strtab is - used to find all of the ELF section names.) */ - - if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff) + if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff != 0) { unsigned int num_sec; - shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx); - if (!shstrtab) - goto got_no_match; - /* Once all of the section headers have been read and converted, we can start processing them. Note that the first section header is a dummy placeholder entry, so we ignore it. */ @@ -801,6 +725,10 @@ elf_object_p (abfd) if (shindex == SHN_LORESERVE - 1) shindex += SHN_HIRESERVE + 1 - SHN_LORESERVE; } + + /* Set up group pointers. */ + if (! _bfd_elf_setup_group_pointers (abfd)) + goto got_wrong_format_error; } /* Let the backend double check the format and override global @@ -856,15 +784,12 @@ elf_object_p (abfd) /* Write out the relocs. */ void -elf_write_relocs (abfd, sec, data) - bfd *abfd; - asection *sec; - PTR data; +elf_write_relocs (bfd *abfd, asection *sec, void *data) { - boolean *failedp = (boolean *) data; + bfd_boolean *failedp = data; Elf_Internal_Shdr *rela_hdr; bfd_vma addr_offset; - void (*swap_out) PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *)); + void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); size_t extsize; bfd_byte *dst_rela; unsigned int idx; @@ -888,10 +813,10 @@ elf_write_relocs (abfd, sec, data) rela_hdr = &elf_section_data (sec)->rel_hdr; rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count; - rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size); + rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size); if (rela_hdr->contents == NULL) { - *failedp = true; + *failedp = TRUE; return; } @@ -942,7 +867,7 @@ elf_write_relocs (abfd, sec, data) n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); if (n < 0) { - *failedp = true; + *failedp = TRUE; return; } last_sym_idx = n; @@ -952,7 +877,7 @@ elf_write_relocs (abfd, sec, data) && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec && ! _bfd_elf_validate_reloc (abfd, ptr)) { - *failedp = true; + *failedp = TRUE; return; } @@ -966,17 +891,16 @@ elf_write_relocs (abfd, sec, data) /* Write out the program headers. */ int -elf_write_out_phdrs (abfd, phdr, count) - bfd *abfd; - const Elf_Internal_Phdr *phdr; - unsigned int count; +elf_write_out_phdrs (bfd *abfd, + const Elf_Internal_Phdr *phdr, + unsigned int count) { while (count--) { Elf_External_Phdr extphdr; elf_swap_phdr_out (abfd, phdr, &extphdr); - if (bfd_bwrite (&extphdr, (bfd_size_type) sizeof (Elf_External_Phdr), - abfd) != sizeof (Elf_External_Phdr)) + if (bfd_bwrite (&extphdr, sizeof (Elf_External_Phdr), abfd) + != sizeof (Elf_External_Phdr)) return -1; phdr++; } @@ -985,9 +909,8 @@ elf_write_out_phdrs (abfd, phdr, count) /* Write out the section headers and the ELF file header. */ -boolean -elf_write_shdrs_and_ehdr (abfd) - bfd *abfd; +bfd_boolean +elf_write_shdrs_and_ehdr (bfd *abfd) { Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ @@ -1007,8 +930,8 @@ elf_write_shdrs_and_ehdr (abfd) elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr); amt = sizeof (x_ehdr); if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_bwrite ((PTR) & x_ehdr, amt, abfd) != amt) - return false; + || bfd_bwrite (&x_ehdr, amt, abfd) != amt) + return FALSE; /* Some fields in the first section header handle overflow of ehdr fields. */ @@ -1020,9 +943,9 @@ elf_write_shdrs_and_ehdr (abfd) /* at this point we've concocted all the ELF sections... */ amt = i_ehdrp->e_shnum; amt *= sizeof (*x_shdrp); - x_shdrp = (Elf_External_Shdr *) bfd_alloc (abfd, amt); + x_shdrp = bfd_alloc (abfd, amt); if (!x_shdrp) - return false; + return FALSE; for (count = 0; count < i_ehdrp->e_shnum; i_shdrp++, count++) { @@ -1030,24 +953,21 @@ elf_write_shdrs_and_ehdr (abfd) elf_debug_section (count, *i_shdrp); #endif elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count); - + if (count == SHN_LORESERVE - 1) i_shdrp += SHN_HIRESERVE + 1 - SHN_LORESERVE; } if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0 - || bfd_bwrite ((PTR) x_shdrp, amt, abfd) != amt) - return false; + || bfd_bwrite (x_shdrp, amt, abfd) != amt) + return FALSE; /* need to dump the string table too... */ - return true; + return TRUE; } long -elf_slurp_symbol_table (abfd, symptrs, dynamic) - bfd *abfd; - asymbol **symptrs; /* Buffer for generated bfd symbols */ - boolean dynamic; +elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic) { Elf_Internal_Shdr *hdr; Elf_Internal_Shdr *verhdr; @@ -1059,7 +979,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) Elf_Internal_Sym *isymbuf = NULL; Elf_External_Versym *xver; Elf_External_Versym *xverbuf = NULL; - struct elf_backend_data *ebd; + const struct elf_backend_data *ebd; bfd_size_type amt; /* Read each raw ELF symbol, converting from external ELF form to @@ -1089,7 +1009,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) || (elf_tdata (abfd)->dynverref_section != 0 && elf_tdata (abfd)->verref == NULL)) { - if (! _bfd_elf_slurp_version_tables (abfd)) + if (!_bfd_elf_slurp_version_tables (abfd, FALSE)) return -1; } } @@ -1107,7 +1027,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) amt = symcount; amt *= sizeof (elf_symbol_type); - symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt); + symbase = bfd_zalloc (abfd, amt); if (symbase == (elf_symbol_type *) NULL) goto error_return; @@ -1131,12 +1051,11 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0) goto error_return; - xverbuf = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size); + xverbuf = bfd_malloc (verhdr->sh_size); if (xverbuf == NULL && verhdr->sh_size != 0) goto error_return; - if (bfd_bread ((PTR) xverbuf, verhdr->sh_size, abfd) - != verhdr->sh_size) + if (bfd_bread (xverbuf, verhdr->sh_size, abfd) != verhdr->sh_size) goto error_return; } @@ -1150,9 +1069,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym)); sym->symbol.the_bfd = abfd; - sym->symbol.name = bfd_elf_string_from_elf_section (abfd, - hdr->sh_link, - isym->st_name); + sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym); sym->symbol.value = isym->st_value; @@ -1163,8 +1080,8 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) else if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) { - sym->symbol.section = section_from_elf_index (abfd, - isym->st_shndx); + sym->symbol.section = bfd_section_from_elf_index (abfd, + isym->st_shndx); if (sym->symbol.section == NULL) { /* This symbol is in a section for which we did not @@ -1189,7 +1106,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) else sym->symbol.section = bfd_abs_section_ptr; - /* If this is a relocateable file, then the symbol value is + /* If this is a relocatable file, then the symbol value is already section relative. */ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) sym->symbol.value -= sym->symbol.section->vma; @@ -1222,6 +1139,9 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) case STT_OBJECT: sym->symbol.flags |= BSF_OBJECT; break; + case STT_TLS: + sym->symbol.flags |= BSF_THREAD_LOCAL; + break; } if (dynamic) @@ -1278,29 +1198,27 @@ error_return: return -1; } -/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of +/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of them. */ -static boolean -elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count, - relents, symbols, dynamic) - bfd *abfd; - asection *asect; - Elf_Internal_Shdr *rel_hdr; - bfd_size_type reloc_count; - arelent *relents; - asymbol **symbols; - boolean dynamic; +static bfd_boolean +elf_slurp_reloc_table_from_section (bfd *abfd, + asection *asect, + Elf_Internal_Shdr *rel_hdr, + bfd_size_type reloc_count, + arelent *relents, + asymbol **symbols, + bfd_boolean dynamic) { - struct elf_backend_data * const ebd = get_elf_backend_data (abfd); - PTR allocated = NULL; + const struct elf_backend_data * const ebd = get_elf_backend_data (abfd); + void *allocated = NULL; bfd_byte *native_relocs; arelent *relent; unsigned int i; int entsize; unsigned int symcount; - allocated = (PTR) bfd_malloc (rel_hdr->sh_size); + allocated = bfd_malloc (rel_hdr->sh_size); if (allocated == NULL) goto error_return; @@ -1309,7 +1227,7 @@ elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count, != rel_hdr->sh_size)) goto error_return; - native_relocs = (bfd_byte *) allocated; + native_relocs = allocated; entsize = rel_hdr->sh_entsize; BFD_ASSERT (entsize == sizeof (Elf_External_Rel) @@ -1356,16 +1274,14 @@ elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count, ps = symbols + ELF_R_SYM (rela.r_info) - 1; s = *ps; - /* Canonicalize ELF section symbols. FIXME: Why? */ - if ((s->flags & BSF_SECTION_SYM) == 0) - relent->sym_ptr_ptr = ps; - else - relent->sym_ptr_ptr = s->section->symbol_ptr_ptr; + relent->sym_ptr_ptr = ps; } relent->addend = rela.r_addend; - if (entsize == sizeof (Elf_External_Rela)) + if ((entsize == sizeof (Elf_External_Rela) + && ebd->elf_info_to_howto != NULL) + || ebd->elf_info_to_howto_rel == NULL) (*ebd->elf_info_to_howto) (abfd, relent, &rela); else (*ebd->elf_info_to_howto_rel) (abfd, relent, &rela); @@ -1374,22 +1290,21 @@ elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count, if (allocated != NULL) free (allocated); - return true; + return TRUE; error_return: if (allocated != NULL) free (allocated); - return false; + return FALSE; } /* Read in and swap the external relocs. */ -boolean -elf_slurp_reloc_table (abfd, asect, symbols, dynamic) - bfd *abfd; - asection *asect; - asymbol **symbols; - boolean dynamic; +bfd_boolean +elf_slurp_reloc_table (bfd *abfd, + asection *asect, + asymbol **symbols, + bfd_boolean dynamic) { struct bfd_elf_section_data * const d = elf_section_data (asect); Elf_Internal_Shdr *rel_hdr; @@ -1400,13 +1315,13 @@ elf_slurp_reloc_table (abfd, asect, symbols, dynamic) bfd_size_type amt; if (asect->relocation != NULL) - return true; + return TRUE; if (! dynamic) { if ((asect->flags & SEC_RELOC) == 0 || asect->reloc_count == 0) - return true; + return TRUE; rel_hdr = &d->rel_hdr; reloc_count = NUM_SHDR_ENTRIES (rel_hdr); @@ -1424,8 +1339,8 @@ elf_slurp_reloc_table (abfd, asect, symbols, dynamic) case because relocations against this section may use the dynamic symbol table, and in that case bfd_section_from_shdr in elf.c does not update the RELOC_COUNT. */ - if (asect->_raw_size == 0) - return true; + if (asect->size == 0) + return TRUE; rel_hdr = &d->this_hdr; reloc_count = NUM_SHDR_ENTRIES (rel_hdr); @@ -1434,32 +1349,30 @@ elf_slurp_reloc_table (abfd, asect, symbols, dynamic) } amt = (reloc_count + reloc_count2) * sizeof (arelent); - relents = (arelent *) bfd_alloc (abfd, amt); + relents = bfd_alloc (abfd, amt); if (relents == NULL) - return false; + return FALSE; if (!elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count, relents, symbols, dynamic)) - return false; + return FALSE; if (rel_hdr2 && !elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr2, reloc_count2, relents + reloc_count, symbols, dynamic)) - return false; + return FALSE; asect->relocation = relents; - return true; + return TRUE; } #ifdef DEBUG static void -elf_debug_section (num, hdr) - int num; - Elf_Internal_Shdr *hdr; +elf_debug_section (int num, Elf_Internal_Shdr *hdr) { fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num, hdr->bfd_section != NULL ? hdr->bfd_section->name : "", @@ -1485,8 +1398,7 @@ elf_debug_section (num, hdr) } static void -elf_debug_file (ehdrp) - Elf_Internal_Ehdr *ehdrp; +elf_debug_file (Elf_Internal_Ehdr *ehdrp) { fprintf (stderr, "e_entry = 0x%.8lx\n", (long) ehdrp->e_entry); fprintf (stderr, "e_phoff = %ld\n", (long) ehdrp->e_phoff); @@ -1498,8 +1410,7 @@ elf_debug_file (ehdrp) } static char * -elf_symbol_flags (flags) - flagword flags; +elf_symbol_flags (flagword flags) { static char buffer[1024]; @@ -1570,8 +1481,230 @@ elf_symbol_flags (flags) } #endif +/* Create a new BFD as if by bfd_openr. Rather than opening a file, + reconstruct an ELF file by reading the segments out of remote memory + based on the ELF file header at EHDR_VMA and the ELF program headers it + points to. If not null, *LOADBASEP is filled in with the difference + between the VMAs from which the segments were read, and the VMAs the + file headers (and hence BFD's idea of each section's VMA) put them at. + + The function TARGET_READ_MEMORY is called to copy LEN bytes from the + remote memory at target address VMA into the local buffer at MYADDR; it + should return zero on success or an `errno' code on failure. TEMPL must + be a BFD for a target with the word size and byte order found in the + remote memory. */ + +bfd * +NAME(_bfd_elf,bfd_from_remote_memory) + (bfd *templ, + bfd_vma ehdr_vma, + bfd_vma *loadbasep, + int (*target_read_memory) (bfd_vma, bfd_byte *, int)) +{ + Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ + Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ + Elf_External_Phdr *x_phdrs; + Elf_Internal_Phdr *i_phdrs, *last_phdr; + bfd *nbfd; + struct bfd_in_memory *bim; + int contents_size; + bfd_byte *contents; + int err; + unsigned int i; + bfd_vma loadbase; + + /* Read in the ELF header in external format. */ + err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr); + if (err) + { + bfd_set_error (bfd_error_system_call); + errno = err; + return NULL; + } + + /* Now check to see if we have a valid ELF file, and one that BFD can + make use of. The magic number must match, the address size ('class') + and byte-swapping must match our XVEC entry. */ + + if (! elf_file_p (&x_ehdr) + || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT + || x_ehdr.e_ident[EI_CLASS] != ELFCLASS) + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + /* Check that file's byte order matches xvec's */ + switch (x_ehdr.e_ident[EI_DATA]) + { + case ELFDATA2MSB: /* Big-endian */ + if (! bfd_header_big_endian (templ)) + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + break; + case ELFDATA2LSB: /* Little-endian */ + if (! bfd_header_little_endian (templ)) + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + break; + case ELFDATANONE: /* No data encoding specified */ + default: /* Unknown data encoding specified */ + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + elf_swap_ehdr_in (templ, &x_ehdr, &i_ehdr); + + /* The file header tells where to find the program headers. + These are what we use to actually choose what to read. */ + + if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0) + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + x_phdrs = bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs)); + if (x_phdrs == NULL) + { + bfd_set_error (bfd_error_no_memory); + return NULL; + } + err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs, + i_ehdr.e_phnum * sizeof x_phdrs[0]); + if (err) + { + free (x_phdrs); + bfd_set_error (bfd_error_system_call); + errno = err; + return NULL; + } + i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum]; + + contents_size = 0; + last_phdr = NULL; + loadbase = ehdr_vma; + for (i = 0; i < i_ehdr.e_phnum; ++i) + { + elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]); + if (i_phdrs[i].p_type == PT_LOAD) + { + bfd_vma segment_end; + segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz + + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; + if (segment_end > (bfd_vma) contents_size) + contents_size = segment_end; + + if ((i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0) + loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align); + + last_phdr = &i_phdrs[i]; + } + } + if (last_phdr == NULL) + { + /* There were no PT_LOAD segments, so we don't have anything to read. */ + free (x_phdrs); + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + /* Trim the last segment so we don't bother with zeros in the last page + that are off the end of the file. However, if the extra bit in that + page includes the section headers, keep them. */ + if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz + && (bfd_vma) contents_size >= (i_ehdr.e_shoff + + i_ehdr.e_shnum * i_ehdr.e_shentsize)) + { + contents_size = last_phdr->p_offset + last_phdr->p_filesz; + if ((bfd_vma) contents_size < (i_ehdr.e_shoff + + i_ehdr.e_shnum * i_ehdr.e_shentsize)) + contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; + } + else + contents_size = last_phdr->p_offset + last_phdr->p_filesz; + + /* Now we know the size of the whole image we want read in. */ + contents = bfd_zmalloc (contents_size); + if (contents == NULL) + { + free (x_phdrs); + bfd_set_error (bfd_error_no_memory); + return NULL; + } + + for (i = 0; i < i_ehdr.e_phnum; ++i) + if (i_phdrs[i].p_type == PT_LOAD) + { + bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align; + bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz + + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; + if (end > (bfd_vma) contents_size) + end = contents_size; + err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr) + & -i_phdrs[i].p_align, + contents + start, end - start); + if (err) + { + free (x_phdrs); + free (contents); + bfd_set_error (bfd_error_system_call); + errno = err; + return NULL; + } + } + free (x_phdrs); + + /* If the segments visible in memory didn't include the section headers, + then clear them from the file header. */ + if ((bfd_vma) contents_size < (i_ehdr.e_shoff + + i_ehdr.e_shnum * i_ehdr.e_shentsize)) + { + memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff); + memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum); + memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx); + } + + /* This will normally have been in the first PT_LOAD segment. But it + conceivably could be missing, and we might have just changed it. */ + memcpy (contents, &x_ehdr, sizeof x_ehdr); + + /* Now we have a memory image of the ELF file contents. Make a BFD. */ + bim = bfd_malloc (sizeof (struct bfd_in_memory)); + if (bim == NULL) + { + free (contents); + bfd_set_error (bfd_error_no_memory); + return NULL; + } + nbfd = _bfd_new_bfd (); + if (nbfd == NULL) + { + free (bim); + free (contents); + bfd_set_error (bfd_error_no_memory); + return NULL; + } + nbfd->filename = ""; + nbfd->xvec = templ->xvec; + bim->size = contents_size; + bim->buffer = contents; + nbfd->iostream = bim; + nbfd->flags = BFD_IN_MEMORY; + nbfd->direction = read_direction; + nbfd->mtime = time (NULL); + nbfd->mtime_set = TRUE; + + if (loadbasep) + *loadbasep = loadbase; + return nbfd; +} + #include "elfcore.h" -#include "elflink.h" /* Size-dependent data and functions. */ const struct elf_size_info NAME(_bfd_elf,size_info) = { @@ -1585,7 +1718,7 @@ const struct elf_size_info NAME(_bfd_elf,size_info) = { sizeof (Elf_External_Note), 4, 1, - ARCH_SIZE, FILE_ALIGN, + ARCH_SIZE, LOG_FILE_ALIGN, ELFCLASS, EV_CURRENT, elf_write_out_phdrs, elf_write_shdrs_and_ehdr,