diff options
-rw-r--r-- | contrib/binutils/bfd/elf.c | 2476 |
1 files changed, 1325 insertions, 1151 deletions
diff --git a/contrib/binutils/bfd/elf.c b/contrib/binutils/bfd/elf.c index 66278ba..2b16f86 100644 --- a/contrib/binutils/bfd/elf.c +++ b/contrib/binutils/bfd/elf.c @@ -1,22 +1,23 @@ /* ELF executable support for BFD. - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. -This file is part of BFD, the Binary File Descriptor library. + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004 Free Software Foundation, Inc. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of BFD, the Binary File Descriptor library. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* $FreeBSD$ */ @@ -44,40 +45,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "elf-bfd.h" #include "libiberty.h" -static INLINE struct elf_segment_map *make_mapping - PARAMS ((bfd *, asection **, unsigned int, unsigned int, boolean)); -static boolean map_sections_to_segments PARAMS ((bfd *)); -static int elf_sort_sections PARAMS ((const PTR, const PTR)); -static boolean assign_file_positions_for_segments PARAMS ((bfd *)); -static boolean assign_file_positions_except_relocs PARAMS ((bfd *)); -static boolean prep_headers PARAMS ((bfd *)); -static boolean swap_out_syms PARAMS ((bfd *, struct bfd_strtab_hash **, int)); -static boolean copy_private_bfd_data PARAMS ((bfd *, bfd *)); -static char *elf_read PARAMS ((bfd *, file_ptr, bfd_size_type)); -static const char *group_signature PARAMS ((bfd *, Elf_Internal_Shdr *)); -static boolean setup_group PARAMS ((bfd *, Elf_Internal_Shdr *, asection *)); -static void merge_sections_remove_hook PARAMS ((bfd *, asection *)); -static void elf_fake_sections PARAMS ((bfd *, asection *, PTR)); -static boolean assign_section_numbers PARAMS ((bfd *)); -static INLINE int sym_is_global PARAMS ((bfd *, asymbol *)); -static boolean elf_map_symbols PARAMS ((bfd *)); -static bfd_size_type get_program_header_size PARAMS ((bfd *)); -static boolean elfcore_read_notes PARAMS ((bfd *, file_ptr, bfd_size_type)); -static boolean elf_find_function PARAMS ((bfd *, asection *, asymbol **, - bfd_vma, const char **, - const char **)); -static int elfcore_make_pid PARAMS ((bfd *)); -static boolean elfcore_maybe_make_sect PARAMS ((bfd *, char *, asection *)); -static boolean elfcore_make_note_pseudosection PARAMS ((bfd *, char *, - Elf_Internal_Note *)); -static boolean elfcore_grok_prfpreg PARAMS ((bfd *, Elf_Internal_Note *)); -static boolean elfcore_grok_prxfpreg PARAMS ((bfd *, Elf_Internal_Note *)); -static boolean elfcore_grok_note PARAMS ((bfd *, Elf_Internal_Note *)); - -static boolean elfcore_netbsd_get_lwpid PARAMS ((Elf_Internal_Note *, int *)); -static boolean elfcore_grok_netbsd_procinfo PARAMS ((bfd *, - Elf_Internal_Note *)); -static boolean elfcore_grok_netbsd_note PARAMS ((bfd *, Elf_Internal_Note *)); +static int elf_sort_sections (const void *, const void *); +static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *); +static bfd_boolean prep_headers (bfd *); +static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ; +static bfd_boolean elfcore_read_notes (bfd *, file_ptr, bfd_size_type) ; /* Swap version information in and out. The version information is currently size independent. If that ever changes, this code will @@ -86,10 +58,9 @@ static boolean elfcore_grok_netbsd_note PARAMS ((bfd *, Elf_Internal_Note *)); /* Swap in a Verdef structure. */ void -_bfd_elf_swap_verdef_in (abfd, src, dst) - bfd *abfd; - const Elf_External_Verdef *src; - Elf_Internal_Verdef *dst; +_bfd_elf_swap_verdef_in (bfd *abfd, + const Elf_External_Verdef *src, + Elf_Internal_Verdef *dst) { dst->vd_version = H_GET_16 (abfd, src->vd_version); dst->vd_flags = H_GET_16 (abfd, src->vd_flags); @@ -103,10 +74,9 @@ _bfd_elf_swap_verdef_in (abfd, src, dst) /* Swap out a Verdef structure. */ void -_bfd_elf_swap_verdef_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Verdef *src; - Elf_External_Verdef *dst; +_bfd_elf_swap_verdef_out (bfd *abfd, + const Elf_Internal_Verdef *src, + Elf_External_Verdef *dst) { H_PUT_16 (abfd, src->vd_version, dst->vd_version); H_PUT_16 (abfd, src->vd_flags, dst->vd_flags); @@ -120,10 +90,9 @@ _bfd_elf_swap_verdef_out (abfd, src, dst) /* Swap in a Verdaux structure. */ void -_bfd_elf_swap_verdaux_in (abfd, src, dst) - bfd *abfd; - const Elf_External_Verdaux *src; - Elf_Internal_Verdaux *dst; +_bfd_elf_swap_verdaux_in (bfd *abfd, + const Elf_External_Verdaux *src, + Elf_Internal_Verdaux *dst) { dst->vda_name = H_GET_32 (abfd, src->vda_name); dst->vda_next = H_GET_32 (abfd, src->vda_next); @@ -132,10 +101,9 @@ _bfd_elf_swap_verdaux_in (abfd, src, dst) /* Swap out a Verdaux structure. */ void -_bfd_elf_swap_verdaux_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Verdaux *src; - Elf_External_Verdaux *dst; +_bfd_elf_swap_verdaux_out (bfd *abfd, + const Elf_Internal_Verdaux *src, + Elf_External_Verdaux *dst) { H_PUT_32 (abfd, src->vda_name, dst->vda_name); H_PUT_32 (abfd, src->vda_next, dst->vda_next); @@ -144,10 +112,9 @@ _bfd_elf_swap_verdaux_out (abfd, src, dst) /* Swap in a Verneed structure. */ void -_bfd_elf_swap_verneed_in (abfd, src, dst) - bfd *abfd; - const Elf_External_Verneed *src; - Elf_Internal_Verneed *dst; +_bfd_elf_swap_verneed_in (bfd *abfd, + const Elf_External_Verneed *src, + Elf_Internal_Verneed *dst) { dst->vn_version = H_GET_16 (abfd, src->vn_version); dst->vn_cnt = H_GET_16 (abfd, src->vn_cnt); @@ -159,10 +126,9 @@ _bfd_elf_swap_verneed_in (abfd, src, dst) /* Swap out a Verneed structure. */ void -_bfd_elf_swap_verneed_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Verneed *src; - Elf_External_Verneed *dst; +_bfd_elf_swap_verneed_out (bfd *abfd, + const Elf_Internal_Verneed *src, + Elf_External_Verneed *dst) { H_PUT_16 (abfd, src->vn_version, dst->vn_version); H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt); @@ -174,10 +140,9 @@ _bfd_elf_swap_verneed_out (abfd, src, dst) /* Swap in a Vernaux structure. */ void -_bfd_elf_swap_vernaux_in (abfd, src, dst) - bfd *abfd; - const Elf_External_Vernaux *src; - Elf_Internal_Vernaux *dst; +_bfd_elf_swap_vernaux_in (bfd *abfd, + const Elf_External_Vernaux *src, + Elf_Internal_Vernaux *dst) { dst->vna_hash = H_GET_32 (abfd, src->vna_hash); dst->vna_flags = H_GET_16 (abfd, src->vna_flags); @@ -189,10 +154,9 @@ _bfd_elf_swap_vernaux_in (abfd, src, dst) /* Swap out a Vernaux structure. */ void -_bfd_elf_swap_vernaux_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Vernaux *src; - Elf_External_Vernaux *dst; +_bfd_elf_swap_vernaux_out (bfd *abfd, + const Elf_Internal_Vernaux *src, + Elf_External_Vernaux *dst) { H_PUT_32 (abfd, src->vna_hash, dst->vna_hash); H_PUT_16 (abfd, src->vna_flags, dst->vna_flags); @@ -204,10 +168,9 @@ _bfd_elf_swap_vernaux_out (abfd, src, dst) /* Swap in a Versym structure. */ void -_bfd_elf_swap_versym_in (abfd, src, dst) - bfd *abfd; - const Elf_External_Versym *src; - Elf_Internal_Versym *dst; +_bfd_elf_swap_versym_in (bfd *abfd, + const Elf_External_Versym *src, + Elf_Internal_Versym *dst) { dst->vs_vers = H_GET_16 (abfd, src->vs_vers); } @@ -215,10 +178,9 @@ _bfd_elf_swap_versym_in (abfd, src, dst) /* Swap out a Versym structure. */ void -_bfd_elf_swap_versym_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Versym *src; - Elf_External_Versym *dst; +_bfd_elf_swap_versym_out (bfd *abfd, + const Elf_Internal_Versym *src, + Elf_External_Versym *dst) { H_PUT_16 (abfd, src->vs_vers, dst->vs_vers); } @@ -227,8 +189,7 @@ _bfd_elf_swap_versym_out (abfd, src, dst) cause invalid hash tables to be generated. */ unsigned long -bfd_elf_hash (namearg) - const char *namearg; +bfd_elf_hash (const char *namearg) { const unsigned char *name = (const unsigned char *) namearg; unsigned long h = 0; @@ -246,7 +207,7 @@ bfd_elf_hash (namearg) h ^= g; } } - return h; + return h & 0xffffffff; } /* Read a specified number of bytes at a specified offset in an ELF @@ -254,10 +215,7 @@ bfd_elf_hash (namearg) buffer. */ static char * -elf_read (abfd, offset, size) - bfd *abfd; - file_ptr offset; - bfd_size_type size; +elf_read (bfd *abfd, file_ptr offset, bfd_size_type size) { char *buf; @@ -265,7 +223,7 @@ elf_read (abfd, offset, size) return NULL; if (bfd_seek (abfd, offset, SEEK_SET) != 0) return NULL; - if (bfd_bread ((PTR) buf, size, abfd) != size) + if (bfd_bread (buf, size, abfd) != size) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_file_truncated); @@ -274,34 +232,29 @@ elf_read (abfd, offset, size) return buf; } -boolean -bfd_elf_mkobject (abfd) - bfd *abfd; +bfd_boolean +bfd_elf_mkobject (bfd *abfd) { /* This just does initialization. */ /* coff_mkobject zalloc's space for tdata.coff_obj_data ... */ - bfd_size_type amt = sizeof (struct elf_obj_tdata); - elf_tdata (abfd) = (struct elf_obj_tdata *) bfd_zalloc (abfd, amt); + elf_tdata (abfd) = bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); if (elf_tdata (abfd) == 0) - return false; + return FALSE; /* Since everything is done at close time, do we need any initialization? */ - return true; + return TRUE; } -boolean -bfd_elf_mkcorefile (abfd) - bfd *abfd; +bfd_boolean +bfd_elf_mkcorefile (bfd *abfd) { /* I think this can be done just like an object file. */ return bfd_elf_mkobject (abfd); } char * -bfd_elf_get_str_section (abfd, shindex) - bfd *abfd; - unsigned int shindex; +bfd_elf_get_str_section (bfd *abfd, unsigned int shindex) { Elf_Internal_Shdr **i_shdrp; char *shstrtab = NULL; @@ -319,16 +272,15 @@ bfd_elf_get_str_section (abfd, shindex) offset = i_shdrp[shindex]->sh_offset; shstrtabsize = i_shdrp[shindex]->sh_size; shstrtab = elf_read (abfd, offset, shstrtabsize); - i_shdrp[shindex]->contents = (PTR) shstrtab; + i_shdrp[shindex]->contents = shstrtab; } return shstrtab; } char * -bfd_elf_string_from_elf_section (abfd, shindex, strindex) - bfd *abfd; - unsigned int shindex; - unsigned int strindex; +bfd_elf_string_from_elf_section (bfd *abfd, + unsigned int shindex, + unsigned int strindex) { Elf_Internal_Shdr *hdr; @@ -363,24 +315,22 @@ bfd_elf_string_from_elf_section (abfd, shindex, strindex) symbols, and symbol section index extensions, respectively. */ Elf_Internal_Sym * -bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, symoffset, - intsym_buf, extsym_buf, extshndx_buf) - bfd *ibfd; - Elf_Internal_Shdr *symtab_hdr; - size_t symcount; - size_t symoffset; - Elf_Internal_Sym *intsym_buf; - PTR extsym_buf; - Elf_External_Sym_Shndx *extshndx_buf; +bfd_elf_get_elf_syms (bfd *ibfd, + Elf_Internal_Shdr *symtab_hdr, + size_t symcount, + size_t symoffset, + Elf_Internal_Sym *intsym_buf, + void *extsym_buf, + Elf_External_Sym_Shndx *extshndx_buf) { Elf_Internal_Shdr *shndx_hdr; - PTR alloc_ext; + void *alloc_ext; const bfd_byte *esym; Elf_External_Sym_Shndx *alloc_extshndx; Elf_External_Sym_Shndx *shndx; Elf_Internal_Sym *isym; Elf_Internal_Sym *isymend; - struct elf_backend_data *bed; + const struct elf_backend_data *bed; size_t extsym_size; bfd_size_type amt; file_ptr pos; @@ -421,7 +371,7 @@ bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, symoffset, pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx); if (extshndx_buf == NULL) { - alloc_extshndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt); + alloc_extshndx = bfd_malloc (amt); extshndx_buf = alloc_extshndx; } if (extshndx_buf == NULL @@ -436,7 +386,7 @@ bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, symoffset, if (intsym_buf == NULL) { bfd_size_type amt = symcount * sizeof (Elf_Internal_Sym); - intsym_buf = (Elf_Internal_Sym *) bfd_malloc (amt); + intsym_buf = bfd_malloc (amt); if (intsym_buf == NULL) goto out; } @@ -446,7 +396,7 @@ bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, symoffset, for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf; isym < isymend; esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL) - (*bed->s->swap_symbol_in) (ibfd, esym, (const PTR) shndx, isym); + (*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym); out: if (alloc_ext != NULL) @@ -457,6 +407,21 @@ bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, symoffset, return intsym_buf; } +/* Look up a symbol name. */ +const char * +bfd_elf_local_sym_name (bfd *abfd, Elf_Internal_Sym *isym) +{ + unsigned int iname = isym->st_name; + unsigned int shindex = elf_tdata (abfd)->symtab_hdr.sh_link; + if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION) + { + iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name; + shindex = elf_elfheader (abfd)->e_shstrndx; + } + + return bfd_elf_string_from_elf_section (abfd, shindex, iname); +} + /* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP sections. The first element is the flags, the rest are section pointers. */ @@ -470,16 +435,12 @@ typedef union elf_internal_group { signature just a string? */ static const char * -group_signature (abfd, ghdr) - bfd *abfd; - Elf_Internal_Shdr *ghdr; +group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr) { Elf_Internal_Shdr *hdr; unsigned char esym[sizeof (Elf64_External_Sym)]; Elf_External_Sym_Shndx eshndx; Elf_Internal_Sym isym; - unsigned int iname; - unsigned int shindex; /* First we need to ensure the symbol table is available. */ if (! bfd_section_from_shdr (abfd, ghdr->sh_link)) @@ -491,25 +452,13 @@ group_signature (abfd, ghdr) &isym, esym, &eshndx) == NULL) return NULL; - /* Look up the symbol name. */ - iname = isym.st_name; - shindex = hdr->sh_link; - if (iname == 0 && ELF_ST_TYPE (isym.st_info) == STT_SECTION) - { - iname = elf_elfsections (abfd)[isym.st_shndx]->sh_name; - shindex = elf_elfheader (abfd)->e_shstrndx; - } - - return bfd_elf_string_from_elf_section (abfd, shindex, iname); + return bfd_elf_local_sym_name (abfd, &isym); } /* Set next_in_group list pointer, and group name for NEWSECT. */ -static boolean -setup_group (abfd, hdr, newsect) - bfd *abfd; - Elf_Internal_Shdr *hdr; - asection *newsect; +static bfd_boolean +setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) { unsigned int num_group = elf_tdata (abfd)->num_group; @@ -541,7 +490,7 @@ setup_group (abfd, hdr, newsect) bfd_size_type amt = num_group * sizeof (Elf_Internal_Shdr *); elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, amt); if (elf_tdata (abfd)->group_sect_ptr == NULL) - return false; + return FALSE; num_group = 0; for (i = 0; i < shnum; i++) @@ -564,7 +513,7 @@ setup_group (abfd, hdr, newsect) || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0 || (bfd_bread (shdr->contents, shdr->sh_size, abfd) != shdr->sh_size)) - return false; + return FALSE; /* Translate raw contents, a flag word followed by an array of elf section indices all in target byte order, @@ -641,7 +590,7 @@ setup_group (abfd, hdr, newsect) gname = group_signature (abfd, shdr); if (gname == NULL) - return false; + return FALSE; elf_group_name (newsect) = gname; /* Start a circular list with one element. */ @@ -664,13 +613,11 @@ setup_group (abfd, hdr, newsect) (*_bfd_error_handler) (_("%s: no group info for section %s"), bfd_archive_filename (abfd), newsect->name); } - return true; + return TRUE; } -boolean -bfd_elf_discard_group (abfd, group) - bfd *abfd ATTRIBUTE_UNUSED; - asection *group; +bfd_boolean +bfd_elf_discard_group (bfd *abfd ATTRIBUTE_UNUSED, asection *group) { asection *first = elf_next_in_group (group); asection *s = first; @@ -683,32 +630,35 @@ bfd_elf_discard_group (abfd, group) if (s == first) break; } - return true; + return TRUE; } /* Make a BFD section from an ELF section. We store a pointer to the BFD section in the bfd_section field of the header. */ -boolean -_bfd_elf_make_section_from_shdr (abfd, hdr, name) - bfd *abfd; - Elf_Internal_Shdr *hdr; - const char *name; +bfd_boolean +_bfd_elf_make_section_from_shdr (bfd *abfd, + Elf_Internal_Shdr *hdr, + const char *name) { asection *newsect; flagword flags; - struct elf_backend_data *bed; + const struct elf_backend_data *bed; if (hdr->bfd_section != NULL) { BFD_ASSERT (strcmp (name, bfd_get_section_name (abfd, hdr->bfd_section)) == 0); - return true; + return TRUE; } newsect = bfd_make_section_anyway (abfd, name); if (newsect == NULL) - return false; + return FALSE; + + /* Always use the real type/flags. */ + elf_section_type (newsect) = hdr->sh_type; + elf_section_flags (newsect) = hdr->sh_flags; newsect->filepos = hdr->sh_offset; @@ -716,7 +666,7 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name) || ! bfd_set_section_size (abfd, newsect, hdr->sh_size) || ! bfd_set_section_alignment (abfd, newsect, bfd_log2 ((bfd_vma) hdr->sh_addralign))) - return false; + return FALSE; flags = SEC_NO_FLAGS; if (hdr->sh_type != SHT_NOBITS) @@ -744,7 +694,7 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name) } if (hdr->sh_flags & SHF_GROUP) if (!setup_group (abfd, hdr, newsect)) - return false; + return FALSE; if ((hdr->sh_flags & SHF_TLS) != 0) flags |= SEC_THREAD_LOCAL; @@ -781,10 +731,10 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name) bed = get_elf_backend_data (abfd); if (bed->elf_backend_section_flags) if (! bed->elf_backend_section_flags (&flags, hdr)) - return false; + return FALSE; if (! bfd_set_section_flags (abfd, newsect, flags)) - return false; + return FALSE; if ((flags & SEC_ALLOC) != 0) { @@ -855,7 +805,7 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name) hdr->bfd_section = newsect; elf_section_data (newsect)->this_hdr = *hdr; - return true; + return TRUE; } /* @@ -874,9 +824,7 @@ DESCRIPTION */ struct elf_internal_shdr * -bfd_elf_find_section (abfd, name) - bfd *abfd; - char *name; +bfd_elf_find_section (bfd *abfd, char *name) { Elf_Internal_Shdr **i_shdrp; char *shstrtab; @@ -905,7 +853,7 @@ const char *const bfd_elf_section_type_names[] = { "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM", }; -/* ELF relocs are against symbols. If we are producing relocateable +/* ELF relocs are against symbols. If we are producing relocatable output, and the reloc is against an external symbol, and nothing has given us any additional addend, the resulting reloc will also be against the same symbol. In such a case, we don't want to @@ -913,25 +861,18 @@ const char *const bfd_elf_section_type_names[] = { all be done at final link time. Rather than put special case code into bfd_perform_relocation, all the reloc types use this howto function. It just short circuits the reloc if producing - relocateable output against an external symbol. */ + relocatable output against an external symbol. */ bfd_reloc_status_type -bfd_elf_generic_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data ATTRIBUTE_UNUSED; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - if (output_bfd != (bfd *) NULL +bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol, + void *data ATTRIBUTE_UNUSED, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 && (! reloc_entry->howto->partial_inplace || reloc_entry->addend == 0)) @@ -946,56 +887,46 @@ bfd_elf_generic_reloc (abfd, /* Make sure sec_info_type is cleared if sec_info is cleared too. */ static void -merge_sections_remove_hook (abfd, sec) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; +merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec) { - struct bfd_elf_section_data *sec_data; - - sec_data = elf_section_data (sec); - BFD_ASSERT (sec_data->sec_info_type == ELF_INFO_TYPE_MERGE); - sec_data->sec_info_type = ELF_INFO_TYPE_NONE; + BFD_ASSERT (sec->sec_info_type == ELF_INFO_TYPE_MERGE); + sec->sec_info_type = ELF_INFO_TYPE_NONE; } /* Finish SHF_MERGE section merging. */ -boolean -_bfd_elf_merge_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +bfd_boolean +_bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info) { - if (!is_elf_hash_table (info)) - return false; + if (!is_elf_hash_table (info->hash)) + return FALSE; if (elf_hash_table (info)->merge_info) _bfd_merge_sections (abfd, elf_hash_table (info)->merge_info, merge_sections_remove_hook); - return true; + return TRUE; } void -_bfd_elf_link_just_syms (sec, info) - asection *sec; - struct bfd_link_info *info; +_bfd_elf_link_just_syms (asection *sec, struct bfd_link_info *info) { sec->output_section = bfd_abs_section_ptr; sec->output_offset = sec->vma; - if (!is_elf_hash_table (info)) + if (!is_elf_hash_table (info->hash)) return; - elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_JUST_SYMS; + sec->sec_info_type = ELF_INFO_TYPE_JUST_SYMS; } /* Copy the program header and other data from one object module to another. */ -boolean -_bfd_elf_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; +bfd_boolean +_bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) { if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; + return TRUE; BFD_ASSERT (!elf_flags_init (obfd) || (elf_elfheader (obfd)->e_flags @@ -1003,18 +934,16 @@ _bfd_elf_copy_private_bfd_data (ibfd, obfd) elf_gp (obfd) = elf_gp (ibfd); elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - elf_flags_init (obfd) = true; - return true; + elf_flags_init (obfd) = TRUE; + return TRUE; } /* Print out the program headers. */ -boolean -_bfd_elf_print_private_bfd_data (abfd, farg) - bfd *abfd; - PTR farg; +bfd_boolean +_bfd_elf_print_private_bfd_data (bfd *abfd, void *farg) { - FILE *f = (FILE *) farg; + FILE *f = farg; Elf_Internal_Phdr *p; asection *s; bfd_byte *dynbuf = NULL; @@ -1042,6 +971,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg) case PT_PHDR: pt = "PHDR"; break; case PT_TLS: pt = "TLS"; break; case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break; + case PT_GNU_STACK: pt = "STACK"; break; default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break; } fprintf (f, "%8s off 0x", pt); @@ -1072,15 +1002,14 @@ _bfd_elf_print_private_bfd_data (abfd, farg) unsigned long shlink; bfd_byte *extdyn, *extdynend; size_t extdynsize; - void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); + void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); fprintf (f, _("\nDynamic Section:\n")); - dynbuf = (bfd_byte *) bfd_malloc (s->_raw_size); + dynbuf = bfd_malloc (s->_raw_size); if (dynbuf == NULL) goto error_return; - if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, (file_ptr) 0, - s->_raw_size)) + if (! bfd_get_section_contents (abfd, s, dynbuf, 0, s->_raw_size)) goto error_return; elfsec = _bfd_elf_section_from_bfd_section (abfd, s); @@ -1098,14 +1027,14 @@ _bfd_elf_print_private_bfd_data (abfd, farg) Elf_Internal_Dyn dyn; const char *name; char ab[20]; - boolean stringp; + bfd_boolean stringp; - (*swap_dyn_in) (abfd, (PTR) extdyn, &dyn); + (*swap_dyn_in) (abfd, extdyn, &dyn); if (dyn.d_tag == DT_NULL) break; - stringp = false; + stringp = FALSE; switch (dyn.d_tag) { default: @@ -1113,7 +1042,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg) name = ab; break; - case DT_NEEDED: name = "NEEDED"; stringp = true; break; + case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break; case DT_PLTRELSZ: name = "PLTRELSZ"; break; case DT_PLTGOT: name = "PLTGOT"; break; case DT_HASH: name = "HASH"; break; @@ -1126,8 +1055,8 @@ _bfd_elf_print_private_bfd_data (abfd, farg) case DT_SYMENT: name = "SYMENT"; break; case DT_INIT: name = "INIT"; break; case DT_FINI: name = "FINI"; break; - case DT_SONAME: name = "SONAME"; stringp = true; break; - case DT_RPATH: name = "RPATH"; stringp = true; break; + case DT_SONAME: name = "SONAME"; stringp = TRUE; break; + case DT_RPATH: name = "RPATH"; stringp = TRUE; break; case DT_SYMBOLIC: name = "SYMBOLIC"; break; case DT_REL: name = "REL"; break; case DT_RELSZ: name = "RELSZ"; break; @@ -1141,7 +1070,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg) case DT_FINI_ARRAY: name = "FINI_ARRAY"; break; case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break; case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break; - case DT_RUNPATH: name = "RUNPATH"; stringp = true; break; + case DT_RUNPATH: name = "RUNPATH"; stringp = TRUE; break; case DT_FLAGS: name = "FLAGS"; break; case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break; case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break; @@ -1153,9 +1082,9 @@ _bfd_elf_print_private_bfd_data (abfd, farg) case DT_POSFLAG_1: name = "POSFLAG_1"; break; case DT_SYMINSZ: name = "SYMINSZ"; break; case DT_SYMINENT: name = "SYMINENT"; break; - case DT_CONFIG: name = "CONFIG"; stringp = true; break; - case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = true; break; - case DT_AUDIT: name = "AUDIT"; stringp = true; break; + case DT_CONFIG: name = "CONFIG"; stringp = TRUE; break; + case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = TRUE; break; + case DT_AUDIT: name = "AUDIT"; stringp = TRUE; break; case DT_PLTPAD: name = "PLTPAD"; break; case DT_MOVETAB: name = "MOVETAB"; break; case DT_SYMINFO: name = "SYMINFO"; break; @@ -1167,9 +1096,9 @@ _bfd_elf_print_private_bfd_data (abfd, farg) case DT_VERDEFNUM: name = "VERDEFNUM"; break; case DT_VERNEED: name = "VERNEED"; break; case DT_VERNEEDNUM: name = "VERNEEDNUM"; break; - case DT_AUXILIARY: name = "AUXILIARY"; stringp = true; break; + case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break; case DT_USED: name = "USED"; break; - case DT_FILTER: name = "FILTER"; stringp = true; break; + case DT_FILTER: name = "FILTER"; stringp = TRUE; break; } fprintf (f, " %-11s ", name); @@ -1196,7 +1125,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg) || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL)) { if (! _bfd_elf_slurp_version_tables (abfd)) - return false; + return FALSE; } if (elf_dynverdef (abfd) != 0) @@ -1238,24 +1167,23 @@ _bfd_elf_print_private_bfd_data (abfd, farg) } } - return true; + return TRUE; error_return: if (dynbuf != NULL) free (dynbuf); - return false; + return FALSE; } /* Display ELF-specific fields of a symbol. */ void -bfd_elf_print_symbol (abfd, filep, symbol, how) - bfd *abfd; - PTR filep; - asymbol *symbol; - bfd_print_symbol_type how; +bfd_elf_print_symbol (bfd *abfd, + void *filep, + asymbol *symbol, + bfd_print_symbol_type how) { - FILE *file = (FILE *) filep; + FILE *file = filep; switch (how) { case bfd_print_symbol_name: @@ -1270,7 +1198,7 @@ bfd_elf_print_symbol (abfd, filep, symbol, how) { const char *section_name; const char *name = NULL; - struct elf_backend_data *bed; + const struct elf_backend_data *bed; unsigned char st_other; bfd_vma val; @@ -1283,7 +1211,7 @@ bfd_elf_print_symbol (abfd, filep, symbol, how) if (name == NULL) { name = symbol->name; - bfd_print_symbol_vandf (abfd, (PTR) file, symbol); + bfd_print_symbol_vandf (abfd, file, symbol); } fprintf (file, " %s\t", section_name); @@ -1372,10 +1300,9 @@ bfd_elf_print_symbol (abfd, filep, symbol, how) /* Create an entry in an ELF linker hash table. */ struct bfd_hash_entry * -_bfd_elf_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; +_bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, + const char *string) { /* Allocate the structure if it has not already been allocated by a subclass. */ @@ -1395,17 +1322,17 @@ _bfd_elf_link_hash_newfunc (entry, table, string) /* Set local fields. */ ret->indx = -1; - ret->size = 0; ret->dynindx = -1; ret->dynstr_index = 0; + ret->elf_hash_value = 0; ret->weakdef = NULL; - ret->got.refcount = htab->init_refcount; - ret->plt.refcount = htab->init_refcount; - ret->linker_section_pointer = NULL; ret->verinfo.verdef = NULL; - ret->vtable_entries_used = NULL; ret->vtable_entries_size = 0; + ret->vtable_entries_used = NULL; ret->vtable_parent = NULL; + ret->got = htab->init_refcount; + ret->plt = htab->init_refcount; + ret->size = 0; ret->type = STT_NOTYPE; ret->other = 0; /* Assume that we have been called by a non-ELF symbol reader. @@ -1422,9 +1349,9 @@ _bfd_elf_link_hash_newfunc (entry, table, string) old indirect symbol. Also used for copying flags to a weakdef. */ void -_bfd_elf_link_hash_copy_indirect (bed, dir, ind) - struct elf_backend_data *bed; - struct elf_link_hash_entry *dir, *ind; +_bfd_elf_link_hash_copy_indirect (const struct elf_backend_data *bed, + struct elf_link_hash_entry *dir, + struct elf_link_hash_entry *ind) { bfd_signed_vma tmp; bfd_signed_vma lowest_valid = bed->can_refcount; @@ -1432,12 +1359,13 @@ _bfd_elf_link_hash_copy_indirect (bed, dir, ind) /* Copy down any references that we may have already seen to the symbol which just became indirect. */ - dir->elf_link_hash_flags |= - (ind->elf_link_hash_flags - & (ELF_LINK_HASH_REF_DYNAMIC - | ELF_LINK_HASH_REF_REGULAR - | ELF_LINK_HASH_REF_REGULAR_NONWEAK - | ELF_LINK_NON_GOT_REF)); + dir->elf_link_hash_flags + |= ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC + | ELF_LINK_HASH_REF_REGULAR + | ELF_LINK_HASH_REF_REGULAR_NONWEAK + | ELF_LINK_NON_GOT_REF + | ELF_LINK_HASH_NEEDS_PLT + | ELF_LINK_POINTER_EQUALITY_NEEDED); if (ind->root.type != bfd_link_hash_indirect) return; @@ -1474,12 +1402,11 @@ _bfd_elf_link_hash_copy_indirect (bed, dir, ind) } void -_bfd_elf_link_hash_hide_symbol (info, h, force_local) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - boolean force_local; +_bfd_elf_link_hash_hide_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h, + bfd_boolean force_local) { - h->plt.offset = (bfd_vma) -1; + h->plt = elf_hash_table (info)->init_offset; h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; if (force_local) { @@ -1495,31 +1422,39 @@ _bfd_elf_link_hash_hide_symbol (info, h, force_local) /* Initialize an ELF linker hash table. */ -boolean -_bfd_elf_link_hash_table_init (table, abfd, newfunc) - struct elf_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); +bfd_boolean +_bfd_elf_link_hash_table_init + (struct elf_link_hash_table *table, + bfd *abfd, + struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, + struct bfd_hash_table *, + const char *)) { - boolean ret; + bfd_boolean ret; - table->dynamic_sections_created = false; + table->dynamic_sections_created = FALSE; table->dynobj = NULL; - table->init_refcount = get_elf_backend_data (abfd)->can_refcount - 1; + /* Make sure can_refcount is extended to the width and signedness of + init_refcount before we subtract one from it. */ + table->init_refcount.refcount = get_elf_backend_data (abfd)->can_refcount; + table->init_refcount.refcount -= 1; + table->init_offset.offset = -(bfd_vma) 1; /* The first dynamic symbol is a dummy. */ table->dynsymcount = 1; table->dynstr = NULL; table->bucketcount = 0; table->needed = NULL; - table->runpath = NULL; - table->loaded = NULL; table->hgot = NULL; table->stab_info = NULL; table->merge_info = NULL; + memset (&table->eh_info, 0, sizeof (table->eh_info)); table->dynlocal = NULL; - ret = _bfd_link_hash_table_init (& table->root, abfd, newfunc); + table->runpath = NULL; + table->tls_sec = NULL; + table->tls_size = 0; + table->loaded = NULL; + + ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc); table->root.type = bfd_link_elf_hash_table; return ret; @@ -1528,14 +1463,13 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc) /* Create an ELF linker hash table. */ struct bfd_link_hash_table * -_bfd_elf_link_hash_table_create (abfd) - bfd *abfd; +_bfd_elf_link_hash_table_create (bfd *abfd) { struct elf_link_hash_table *ret; bfd_size_type amt = sizeof (struct elf_link_hash_table); - ret = (struct elf_link_hash_table *) bfd_malloc (amt); - if (ret == (struct elf_link_hash_table *) NULL) + ret = bfd_malloc (amt); + if (ret == NULL) return NULL; if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc)) @@ -1549,13 +1483,10 @@ _bfd_elf_link_hash_table_create (abfd) /* This is a hook for the ELF emulation code in the generic linker to tell the backend linker what file name to use for the DT_NEEDED - entry for a dynamic object. The generic linker passes name as an - empty string to indicate that no DT_NEEDED entry should be made. */ + entry for a dynamic object. */ void -bfd_elf_set_dt_needed_name (abfd, name) - bfd *abfd; - const char *name; +bfd_elf_set_dt_needed_name (bfd *abfd, const char *name) { if (bfd_get_flavour (abfd) == bfd_target_elf_flavour && bfd_get_format (abfd) == bfd_object) @@ -1563,24 +1494,21 @@ bfd_elf_set_dt_needed_name (abfd, name) } void -bfd_elf_set_dt_needed_soname (abfd, name) - bfd *abfd; - const char *name; +bfd_elf_set_dyn_lib_class (bfd *abfd, int lib_class) { if (bfd_get_flavour (abfd) == bfd_target_elf_flavour && bfd_get_format (abfd) == bfd_object) - elf_dt_soname (abfd) = name; + elf_dyn_lib_class (abfd) = lib_class; } /* Get the list of DT_NEEDED entries for a link. This is a hook for the linker ELF emulation code. */ struct bfd_link_needed_list * -bfd_elf_get_needed_list (abfd, info) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; +bfd_elf_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info) { - if (info->hash->creator->flavour != bfd_target_elf_flavour) + if (! is_elf_hash_table (info->hash)) return NULL; return elf_hash_table (info)->needed; } @@ -1589,11 +1517,10 @@ bfd_elf_get_needed_list (abfd, info) hook for the linker ELF emulation code. */ struct bfd_link_needed_list * -bfd_elf_get_runpath_list (abfd, info) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; +bfd_elf_get_runpath_list (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info) { - if (info->hash->creator->flavour != bfd_target_elf_flavour) + if (! is_elf_hash_table (info->hash)) return NULL; return elf_hash_table (info)->runpath; } @@ -1603,8 +1530,7 @@ bfd_elf_get_runpath_list (abfd, info) passed to bfd_elf_set_dt_needed_name, or it is the filename. */ const char * -bfd_elf_get_dt_soname (abfd) - bfd *abfd; +bfd_elf_get_dt_soname (bfd *abfd) { if (bfd_get_flavour (abfd) == bfd_target_elf_flavour && bfd_get_format (abfd) == bfd_object) @@ -1615,10 +1541,9 @@ bfd_elf_get_dt_soname (abfd) /* Get the list of DT_NEEDED entries from a BFD. This is a hook for the ELF linker emulation code. */ -boolean -bfd_elf_get_bfd_needed_list (abfd, pneeded) - bfd *abfd; - struct bfd_link_needed_list **pneeded; +bfd_boolean +bfd_elf_get_bfd_needed_list (bfd *abfd, + struct bfd_link_needed_list **pneeded) { asection *s; bfd_byte *dynbuf = NULL; @@ -1626,24 +1551,23 @@ bfd_elf_get_bfd_needed_list (abfd, pneeded) unsigned long shlink; bfd_byte *extdyn, *extdynend; size_t extdynsize; - void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *)); + void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); *pneeded = NULL; if (bfd_get_flavour (abfd) != bfd_target_elf_flavour || bfd_get_format (abfd) != bfd_object) - return true; + return TRUE; s = bfd_get_section_by_name (abfd, ".dynamic"); if (s == NULL || s->_raw_size == 0) - return true; + return TRUE; - dynbuf = (bfd_byte *) bfd_malloc (s->_raw_size); + dynbuf = bfd_malloc (s->_raw_size); if (dynbuf == NULL) goto error_return; - if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, (file_ptr) 0, - s->_raw_size)) + if (! bfd_get_section_contents (abfd, s, dynbuf, 0, s->_raw_size)) goto error_return; elfsec = _bfd_elf_section_from_bfd_section (abfd, s); @@ -1661,7 +1585,7 @@ bfd_elf_get_bfd_needed_list (abfd, pneeded) { Elf_Internal_Dyn dyn; - (*swap_dyn_in) (abfd, (PTR) extdyn, &dyn); + (*swap_dyn_in) (abfd, extdyn, &dyn); if (dyn.d_tag == DT_NULL) break; @@ -1678,7 +1602,7 @@ bfd_elf_get_bfd_needed_list (abfd, pneeded) goto error_return; amt = sizeof *l; - l = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); + l = bfd_alloc (abfd, amt); if (l == NULL) goto error_return; @@ -1691,18 +1615,18 @@ bfd_elf_get_bfd_needed_list (abfd, pneeded) free (dynbuf); - return true; + return TRUE; error_return: if (dynbuf != NULL) free (dynbuf); - return false; + return FALSE; } /* Allocate an ELF string table--force the first byte to be zero. */ struct bfd_strtab_hash * -_bfd_elf_stringtab_init () +_bfd_elf_stringtab_init (void) { struct bfd_strtab_hash *ret; @@ -1711,7 +1635,7 @@ _bfd_elf_stringtab_init () { bfd_size_type loc; - loc = _bfd_stringtab_add (ret, "", true, false); + loc = _bfd_stringtab_add (ret, "", TRUE, FALSE); BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1); if (loc == (bfd_size_type) -1) { @@ -1726,14 +1650,12 @@ _bfd_elf_stringtab_init () /* Create a new bfd section from an ELF section header. */ -boolean -bfd_section_from_shdr (abfd, shindex) - bfd *abfd; - unsigned int shindex; +bfd_boolean +bfd_section_from_shdr (bfd *abfd, unsigned int shindex) { Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex]; Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd); - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); const char *name; name = elf_string_from_elf_strtab (abfd, hdr->sh_name); @@ -1742,7 +1664,7 @@ bfd_section_from_shdr (abfd, shindex) { case SHT_NULL: /* Inactive section. Throw it away. */ - return true; + return TRUE; case SHT_PROGBITS: /* Normal section with contents. */ case SHT_NOBITS: /* .bss section. */ @@ -1755,7 +1677,7 @@ bfd_section_from_shdr (abfd, shindex) case SHT_DYNAMIC: /* Dynamic linking information. */ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) - return false; + return FALSE; if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB) { Elf_Internal_Shdr *dynsymhdr; @@ -1788,7 +1710,7 @@ bfd_section_from_shdr (abfd, shindex) case SHT_SYMTAB: /* A symbol table */ if (elf_onesymtab (abfd) == shindex) - return true; + return TRUE; BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym); BFD_ASSERT (elf_onesymtab (abfd) == 0); @@ -1801,18 +1723,18 @@ bfd_section_from_shdr (abfd, shindex) SHF_ALLOC is set, and this is a shared object, then we also treat this section as a BFD section. We can not base the decision purely on SHF_ALLOC, because that flag is sometimes - set in a relocateable object file, which would confuse the + set in a relocatable object file, which would confuse the linker. */ if ((hdr->sh_flags & SHF_ALLOC) != 0 && (abfd->flags & DYNAMIC) != 0 && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) - return false; + return FALSE; - return true; + return TRUE; case SHT_DYNSYM: /* A dynamic symbol table */ if (elf_dynsymtab (abfd) == shindex) - return true; + return TRUE; BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym); BFD_ASSERT (elf_dynsymtab (abfd) == 0); @@ -1827,26 +1749,26 @@ bfd_section_from_shdr (abfd, shindex) case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections */ if (elf_symtab_shndx (abfd) == shindex) - return true; + return TRUE; /* Get the associated symbol table. */ if (! bfd_section_from_shdr (abfd, hdr->sh_link) || hdr->sh_link != elf_onesymtab (abfd)) - return false; + return FALSE; elf_symtab_shndx (abfd) = shindex; elf_tdata (abfd)->symtab_shndx_hdr = *hdr; elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr; - return true; + return TRUE; case SHT_STRTAB: /* A string table */ if (hdr->bfd_section != NULL) - return true; + return TRUE; if (ehdr->e_shstrndx == shindex) { elf_tdata (abfd)->shstrtab_hdr = *hdr; elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr; - return true; + return TRUE; } { unsigned int i, num_sec; @@ -1858,13 +1780,13 @@ bfd_section_from_shdr (abfd, shindex) if (hdr2->sh_link == shindex) { if (! bfd_section_from_shdr (abfd, i)) - return false; + return FALSE; if (elf_onesymtab (abfd) == i) { elf_tdata (abfd)->strtab_hdr = *hdr; elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr; - return true; + return TRUE; } if (elf_dynsymtab (abfd) == i) { @@ -1944,7 +1866,7 @@ bfd_section_from_shdr (abfd, shindex) /* Get the symbol table. */ if (elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB && ! bfd_section_from_shdr (abfd, hdr->sh_link)) - return false; + return FALSE; /* If this reloc section does not use the main symbol table we don't treat it as a reloc section. BFD can't adequately @@ -1956,10 +1878,10 @@ bfd_section_from_shdr (abfd, shindex) return _bfd_elf_make_section_from_shdr (abfd, hdr, name); if (! bfd_section_from_shdr (abfd, hdr->sh_info)) - return false; + return FALSE; target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info); if (target_sect == NULL) - return false; + return FALSE; if ((target_sect->flags & SEC_RELOC) == 0 || target_sect->reloc_count == 0) @@ -1969,7 +1891,7 @@ bfd_section_from_shdr (abfd, shindex) bfd_size_type amt; BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL); amt = sizeof (*hdr2); - hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt); + hdr2 = bfd_alloc (abfd, amt); elf_section_data (target_sect)->rel_hdr2 = hdr2; } *hdr2 = *hdr; @@ -1981,10 +1903,9 @@ bfd_section_from_shdr (abfd, shindex) /* In the section to which the relocations apply, mark whether its relocations are of the REL or RELA variety. */ if (hdr->sh_size != 0) - elf_section_data (target_sect)->use_rela_p - = (hdr->sh_type == SHT_RELA); + target_sect->use_rela_p = hdr->sh_type == SHT_RELA; abfd->flags |= HAS_RELOC; - return true; + return TRUE; } break; @@ -2007,7 +1928,7 @@ bfd_section_from_shdr (abfd, shindex) break; case SHT_SHLIB: - return true; + return TRUE; case SHT_GROUP: /* We need a BFD section for objcopy and relocatable linking, @@ -2015,9 +1936,9 @@ bfd_section_from_shdr (abfd, shindex) name. */ name = group_signature (abfd, hdr); if (name == NULL) - return false; + return FALSE; if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name)) - return false; + return FALSE; if (hdr->contents != NULL) { Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents; @@ -2047,18 +1968,17 @@ bfd_section_from_shdr (abfd, shindex) break; } - return true; + return TRUE; } /* Return the section for the local symbol specified by ABFD, R_SYMNDX. Return SEC for sections that have no elf section, and NULL on error. */ asection * -bfd_section_from_r_symndx (abfd, cache, sec, r_symndx) - bfd *abfd; - struct sym_sec_cache *cache; - asection *sec; - unsigned long r_symndx; +bfd_section_from_r_symndx (bfd *abfd, + struct sym_sec_cache *cache, + asection *sec, + unsigned long r_symndx) { Elf_Internal_Shdr *symtab_hdr; unsigned char esym[sizeof (Elf64_External_Sym)]; @@ -2081,7 +2001,8 @@ bfd_section_from_r_symndx (abfd, cache, sec, r_symndx) } cache->indx[ent] = r_symndx; cache->sec[ent] = sec; - if (isym.st_shndx < SHN_LORESERVE || isym.st_shndx > SHN_HIRESERVE) + if ((isym.st_shndx != SHN_UNDEF && isym.st_shndx < SHN_LORESERVE) + || isym.st_shndx > SHN_HIRESERVE) { asection *s; s = bfd_section_from_elf_index (abfd, isym.st_shndx); @@ -2095,33 +2016,149 @@ bfd_section_from_r_symndx (abfd, cache, sec, r_symndx) section. */ asection * -bfd_section_from_elf_index (abfd, index) - bfd *abfd; - unsigned int index; +bfd_section_from_elf_index (bfd *abfd, unsigned int index) { if (index >= elf_numsections (abfd)) return NULL; return elf_elfsections (abfd)[index]->bfd_section; } -boolean -_bfd_elf_new_section_hook (abfd, sec) - bfd *abfd; - asection *sec; +static struct bfd_elf_special_section const special_sections[] = +{ + { ".bss", 4, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, + { ".comment", 8, 0, SHT_PROGBITS, 0 }, + { ".data", 5, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".data1", 6, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".debug", 6, 0, SHT_PROGBITS, 0 }, + { ".fini", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { ".init", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { ".line", 5, 0, SHT_PROGBITS, 0 }, + { ".rodata", 7, -2, SHT_PROGBITS, SHF_ALLOC }, + { ".rodata1", 8, 0, SHT_PROGBITS, SHF_ALLOC }, + { ".tbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, + { ".tdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, + { ".text", 5, -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { ".init_array", 11, 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE }, + { ".fini_array", 11, 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE }, + { ".preinit_array", 14, 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE }, + { ".debug_line", 11, 0, SHT_PROGBITS, 0 }, + { ".debug_info", 11, 0, SHT_PROGBITS, 0 }, + { ".debug_abbrev", 13, 0, SHT_PROGBITS, 0 }, + { ".debug_aranges", 14, 0, SHT_PROGBITS, 0 }, + { ".dynamic", 8, 0, SHT_DYNAMIC, SHF_ALLOC }, + { ".dynstr", 7, 0, SHT_STRTAB, SHF_ALLOC }, + { ".dynsym", 7, 0, SHT_DYNSYM, SHF_ALLOC }, + { ".got", 4, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".hash", 5, 0, SHT_HASH, SHF_ALLOC }, + { ".interp", 7, 0, SHT_PROGBITS, 0 }, + { ".plt", 4, 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { ".shstrtab", 9, 0, SHT_STRTAB, 0 }, + { ".strtab", 7, 0, SHT_STRTAB, 0 }, + { ".symtab", 7, 0, SHT_SYMTAB, 0 }, + { ".gnu.version", 12, 0, SHT_GNU_versym, 0 }, + { ".gnu.version_d", 14, 0, SHT_GNU_verdef, 0 }, + { ".gnu.version_r", 14, 0, SHT_GNU_verneed, 0 }, + { ".note", 5, -1, SHT_NOTE, 0 }, + { ".rela", 5, -1, SHT_RELA, 0 }, + { ".rel", 4, -1, SHT_REL, 0 }, + { ".stabstr", 5, 3, SHT_STRTAB, 0 }, + { NULL, 0, 0, 0, 0 } +}; + +static const struct bfd_elf_special_section * +get_special_section (const char *name, + const struct bfd_elf_special_section *special_sections, + unsigned int rela) +{ + int i; + int len = strlen (name); + + for (i = 0; special_sections[i].prefix != NULL; i++) + { + int suffix_len; + int prefix_len = special_sections[i].prefix_length; + + if (len < prefix_len) + continue; + if (memcmp (name, special_sections[i].prefix, prefix_len) != 0) + continue; + + suffix_len = special_sections[i].suffix_length; + if (suffix_len <= 0) + { + if (name[prefix_len] != 0) + { + if (suffix_len == 0) + continue; + if (name[prefix_len] != '.' + && (suffix_len == -2 + || (rela && special_sections[i].type == SHT_REL))) + continue; + } + } + else + { + if (len < prefix_len + suffix_len) + continue; + if (memcmp (name + len - suffix_len, + special_sections[i].prefix + prefix_len, + suffix_len) != 0) + continue; + } + return &special_sections[i]; + } + + return NULL; +} + +const struct bfd_elf_special_section * +_bfd_elf_get_sec_type_attr (bfd *abfd, const char *name) +{ + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct bfd_elf_special_section *ssect = NULL; + + /* See if this is one of the special sections. */ + if (name) + { + unsigned int rela = bed->default_use_rela_p; + + if (bed->special_sections) + ssect = get_special_section (name, bed->special_sections, rela); + + if (! ssect) + ssect = get_special_section (name, special_sections, rela); + } + + return ssect; +} + +bfd_boolean +_bfd_elf_new_section_hook (bfd *abfd, asection *sec) { struct bfd_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + const struct bfd_elf_special_section *ssect; - sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, amt); - if (!sdata) - return false; - sec->used_by_bfd = (PTR) sdata; + sdata = (struct bfd_elf_section_data *) sec->used_by_bfd; + if (sdata == NULL) + { + sdata = bfd_zalloc (abfd, sizeof (*sdata)); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + } + + elf_section_type (sec) = SHT_NULL; + ssect = _bfd_elf_get_sec_type_attr (abfd, sec->name); + if (ssect != NULL) + { + elf_section_type (sec) = ssect->type; + elf_section_flags (sec) = ssect->attr; + } /* Indicate whether or not this section should use RELA relocations. */ - sdata->use_rela_p - = get_elf_backend_data (abfd)->default_use_rela_p; + sec->use_rela_p = get_elf_backend_data (abfd)->default_use_rela_p; - return true; + return TRUE; } /* Create a new bfd section from an ELF program header. @@ -2146,12 +2183,11 @@ _bfd_elf_new_section_hook (abfd, sec) */ -boolean -_bfd_elf_make_section_from_phdr (abfd, hdr, index, typename) - bfd *abfd; - Elf_Internal_Phdr *hdr; - int index; - const char *typename; +bfd_boolean +_bfd_elf_make_section_from_phdr (bfd *abfd, + Elf_Internal_Phdr *hdr, + int index, + const char *typename) { asection *newsect; char *name; @@ -2164,18 +2200,19 @@ _bfd_elf_make_section_from_phdr (abfd, hdr, index, typename) && (hdr->p_memsz > hdr->p_filesz)); sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : ""); len = strlen (namebuf) + 1; - name = bfd_alloc (abfd, (bfd_size_type) len); + name = bfd_alloc (abfd, len); if (!name) - return false; + return FALSE; memcpy (name, namebuf, len); newsect = bfd_make_section (abfd, name); if (newsect == NULL) - return false; + return FALSE; newsect->vma = hdr->p_vaddr; newsect->lma = hdr->p_paddr; newsect->_raw_size = hdr->p_filesz; newsect->filepos = hdr->p_offset; newsect->flags |= SEC_HAS_CONTENTS; + newsect->alignment_power = bfd_log2 (hdr->p_align); if (hdr->p_type == PT_LOAD) { newsect->flags |= SEC_ALLOC; @@ -2196,13 +2233,13 @@ _bfd_elf_make_section_from_phdr (abfd, hdr, index, typename) { sprintf (namebuf, "%s%db", typename, index); len = strlen (namebuf) + 1; - name = bfd_alloc (abfd, (bfd_size_type) len); + name = bfd_alloc (abfd, len); if (!name) - return false; + return FALSE; memcpy (name, namebuf, len); newsect = bfd_make_section (abfd, name); if (newsect == NULL) - return false; + return FALSE; newsect->vma = hdr->p_vaddr + hdr->p_filesz; newsect->lma = hdr->p_paddr + hdr->p_filesz; newsect->_raw_size = hdr->p_memsz - hdr->p_filesz; @@ -2216,16 +2253,13 @@ _bfd_elf_make_section_from_phdr (abfd, hdr, index, typename) newsect->flags |= SEC_READONLY; } - return true; + return TRUE; } -boolean -bfd_section_from_phdr (abfd, hdr, index) - bfd *abfd; - Elf_Internal_Phdr *hdr; - int index; +bfd_boolean +bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index) { - struct elf_backend_data *bed; + const struct elf_backend_data *bed; switch (hdr->p_type) { @@ -2243,10 +2277,10 @@ bfd_section_from_phdr (abfd, hdr, index) case PT_NOTE: if (! _bfd_elf_make_section_from_phdr (abfd, hdr, index, "note")) - return false; - if (! elfcore_read_notes (abfd, (file_ptr) hdr->p_offset, hdr->p_filesz)) - return false; - return true; + return FALSE; + if (! elfcore_read_notes (abfd, hdr->p_offset, hdr->p_filesz)) + return FALSE; + return TRUE; case PT_SHLIB: return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "shlib"); @@ -2254,6 +2288,13 @@ bfd_section_from_phdr (abfd, hdr, index) case PT_PHDR: return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "phdr"); + case PT_GNU_EH_FRAME: + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, + "eh_frame_hdr"); + + case PT_GNU_STACK: + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "stack"); + default: /* Check for any processor-specific program segment types. If no handler for them, default to making "segment" sections. */ @@ -2266,52 +2307,48 @@ bfd_section_from_phdr (abfd, hdr, index) } /* Initialize REL_HDR, the section-header for new section, containing - relocations against ASECT. If USE_RELA_P is true, we use RELA + relocations against ASECT. If USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL relocations. */ -boolean -_bfd_elf_init_reloc_shdr (abfd, rel_hdr, asect, use_rela_p) - bfd *abfd; - Elf_Internal_Shdr *rel_hdr; - asection *asect; - boolean use_rela_p; +bfd_boolean +_bfd_elf_init_reloc_shdr (bfd *abfd, + Elf_Internal_Shdr *rel_hdr, + asection *asect, + bfd_boolean use_rela_p) { char *name; - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); bfd_size_type amt = sizeof ".rela" + strlen (asect->name); name = bfd_alloc (abfd, amt); if (name == NULL) - return false; + return FALSE; sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name); rel_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name, - false); + FALSE); if (rel_hdr->sh_name == (unsigned int) -1) - return false; + return FALSE; rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL; rel_hdr->sh_entsize = (use_rela_p ? bed->s->sizeof_rela : bed->s->sizeof_rel); - rel_hdr->sh_addralign = bed->s->file_align; + rel_hdr->sh_addralign = 1 << bed->s->log_file_align; rel_hdr->sh_flags = 0; rel_hdr->sh_addr = 0; rel_hdr->sh_size = 0; rel_hdr->sh_offset = 0; - return true; + return TRUE; } /* Set up an ELF internal section header for a section. */ static void -elf_fake_sections (abfd, asect, failedptrarg) - bfd *abfd; - asection *asect; - PTR failedptrarg; +elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg) { - struct elf_backend_data *bed = get_elf_backend_data (abfd); - boolean *failedptr = (boolean *) failedptrarg; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + bfd_boolean *failedptr = failedptrarg; Elf_Internal_Shdr *this_hdr; if (*failedptr) @@ -2323,11 +2360,11 @@ elf_fake_sections (abfd, asect, failedptrarg) this_hdr = &elf_section_data (asect)->this_hdr; - this_hdr->sh_name = (unsigned long) _bfd_elf_strtab_add (elf_shstrtab (abfd), - asect->name, false); - if (this_hdr->sh_name == (unsigned long) -1) + this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), + asect->name, FALSE); + if (this_hdr->sh_name == (unsigned int) -1) { - *failedptr = true; + *failedptr = TRUE; return; } @@ -2349,55 +2386,59 @@ elf_fake_sections (abfd, asect, failedptrarg) this_hdr->bfd_section = asect; this_hdr->contents = NULL; - /* FIXME: This should not be based on section names. */ - if (strcmp (asect->name, ".dynstr") == 0) - this_hdr->sh_type = SHT_STRTAB; - else if (strcmp (asect->name, ".hash") == 0) + /* If the section type is unspecified, we set it based on + asect->flags. */ + if (this_hdr->sh_type == SHT_NULL) { - this_hdr->sh_type = SHT_HASH; - this_hdr->sh_entsize = bed->s->sizeof_hash_entry; + if ((asect->flags & SEC_ALLOC) != 0 + && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) + || (asect->flags & SEC_NEVER_LOAD) != 0)) + this_hdr->sh_type = SHT_NOBITS; + else + this_hdr->sh_type = SHT_PROGBITS; } - else if (strcmp (asect->name, ".dynsym") == 0) + + switch (this_hdr->sh_type) { - this_hdr->sh_type = SHT_DYNSYM; + default: + break; + + case SHT_STRTAB: + case SHT_INIT_ARRAY: + case SHT_FINI_ARRAY: + case SHT_PREINIT_ARRAY: + case SHT_NOTE: + case SHT_NOBITS: + case SHT_PROGBITS: + break; + + case SHT_HASH: + this_hdr->sh_entsize = bed->s->sizeof_hash_entry; + break; + + case SHT_DYNSYM: this_hdr->sh_entsize = bed->s->sizeof_sym; - } - else if (strcmp (asect->name, ".dynamic") == 0) - { - this_hdr->sh_type = SHT_DYNAMIC; + break; + + case SHT_DYNAMIC: this_hdr->sh_entsize = bed->s->sizeof_dyn; - } - else if (strncmp (asect->name, ".rela", 5) == 0 - && get_elf_backend_data (abfd)->may_use_rela_p) - { - this_hdr->sh_type = SHT_RELA; - this_hdr->sh_entsize = bed->s->sizeof_rela; - } - else if (strncmp (asect->name, ".rel", 4) == 0 - && get_elf_backend_data (abfd)->may_use_rel_p) - { - this_hdr->sh_type = SHT_REL; - this_hdr->sh_entsize = bed->s->sizeof_rel; - } - else if (strcmp (asect->name, ".init_array") == 0) - this_hdr->sh_type = SHT_INIT_ARRAY; - else if (strcmp (asect->name, ".fini_array") == 0) - this_hdr->sh_type = SHT_FINI_ARRAY; - else if (strcmp (asect->name, ".preinit_array") == 0) - this_hdr->sh_type = SHT_PREINIT_ARRAY; - else if (strncmp (asect->name, ".note", 5) == 0) - this_hdr->sh_type = SHT_NOTE; - else if (strncmp (asect->name, ".stab", 5) == 0 - && strcmp (asect->name + strlen (asect->name) - 3, "str") == 0) - this_hdr->sh_type = SHT_STRTAB; - else if (strcmp (asect->name, ".gnu.version") == 0) - { - this_hdr->sh_type = SHT_GNU_versym; + break; + + case SHT_RELA: + if (get_elf_backend_data (abfd)->may_use_rela_p) + this_hdr->sh_entsize = bed->s->sizeof_rela; + break; + + case SHT_REL: + if (get_elf_backend_data (abfd)->may_use_rel_p) + this_hdr->sh_entsize = bed->s->sizeof_rel; + break; + + case SHT_GNU_versym: this_hdr->sh_entsize = sizeof (Elf_External_Versym); - } - else if (strcmp (asect->name, ".gnu.version_d") == 0) - { - this_hdr->sh_type = SHT_GNU_verdef; + break; + + case SHT_GNU_verdef: this_hdr->sh_entsize = 0; /* objcopy or strip will copy over sh_info, but may not set cverdefs. The linker will set cverdefs, but sh_info will be @@ -2407,10 +2448,9 @@ elf_fake_sections (abfd, asect, failedptrarg) else BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0 || this_hdr->sh_info == elf_tdata (abfd)->cverdefs); - } - else if (strcmp (asect->name, ".gnu.version_r") == 0) - { - this_hdr->sh_type = SHT_GNU_verneed; + break; + + case SHT_GNU_verneed: this_hdr->sh_entsize = 0; /* objcopy or strip will copy over sh_info, but may not set cverrefs. The linker will set cverrefs, but sh_info will be @@ -2420,18 +2460,12 @@ elf_fake_sections (abfd, asect, failedptrarg) else BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0 || this_hdr->sh_info == elf_tdata (abfd)->cverrefs); - } - else if ((asect->flags & SEC_GROUP) != 0) - { - this_hdr->sh_type = SHT_GROUP; + break; + + case SHT_GROUP: this_hdr->sh_entsize = 4; + break; } - else if ((asect->flags & SEC_ALLOC) != 0 - && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - || (asect->flags & SEC_NEVER_LOAD) != 0)) - this_hdr->sh_type = SHT_NOBITS; - else - this_hdr->sh_type = SHT_PROGBITS; if ((asect->flags & SEC_ALLOC) != 0) this_hdr->sh_flags |= SHF_ALLOC; @@ -2454,7 +2488,7 @@ elf_fake_sections (abfd, asect, failedptrarg) if (asect->_raw_size == 0 && (asect->flags & SEC_HAS_CONTENTS) == 0) { struct bfd_link_order *o; - + this_hdr->sh_size = 0; for (o = asect->link_order_head; o != NULL; o = o->next) if (this_hdr->sh_size < o->offset + o->size) @@ -2467,7 +2501,7 @@ elf_fake_sections (abfd, asect, failedptrarg) /* Check for processor-specific section types. */ if (bed->elf_backend_fake_sections && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect)) - *failedptr = true; + *failedptr = TRUE; /* If the section has relocs, set up a section header for the SHT_REL[A] section. If two relocation sections are required for @@ -2477,24 +2511,21 @@ elf_fake_sections (abfd, asect, failedptrarg) && !_bfd_elf_init_reloc_shdr (abfd, &elf_section_data (asect)->rel_hdr, asect, - elf_section_data (asect)->use_rela_p)) - *failedptr = true; + asect->use_rela_p)) + *failedptr = TRUE; } /* Fill in the contents of a SHT_GROUP section. */ void -bfd_elf_set_group_contents (abfd, sec, failedptrarg) - bfd *abfd; - asection *sec; - PTR failedptrarg; +bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) { - boolean *failedptr = (boolean *) failedptrarg; + bfd_boolean *failedptr = failedptrarg; unsigned long symindx; asection *elt, *first; unsigned char *loc; struct bfd_link_order *l; - boolean gas; + bfd_boolean gas; if (elf_section_data (sec)->this_hdr.sh_type != SHT_GROUP || *failedptr) @@ -2516,17 +2547,17 @@ bfd_elf_set_group_contents (abfd, sec, failedptrarg) elf_section_data (sec)->this_hdr.sh_info = symindx; /* The contents won't be allocated for "ld -r" or objcopy. */ - gas = true; + gas = TRUE; if (sec->contents == NULL) { - gas = false; + gas = FALSE; sec->contents = bfd_alloc (abfd, sec->_raw_size); /* Arrange for the section to be written out. */ elf_section_data (sec)->this_hdr.contents = sec->contents; if (sec->contents == NULL) { - *failedptr = true; + *failedptr = TRUE; return; } } @@ -2592,9 +2623,8 @@ bfd_elf_set_group_contents (abfd, sec, failedptrarg) too. The link/info pointers for the standard section types are filled in here too, while we're at it. */ -static boolean -assign_section_numbers (abfd) - bfd *abfd; +static bfd_boolean +assign_section_numbers (bfd *abfd) { struct elf_obj_tdata *t = elf_tdata (abfd); asection *sec; @@ -2654,9 +2684,9 @@ assign_section_numbers (abfd) t->symtab_shndx_section = section_number++; t->symtab_shndx_hdr.sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), - ".symtab_shndx", false); + ".symtab_shndx", FALSE); if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1) - return false; + return FALSE; } if (section_number == SHN_LORESERVE) section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; @@ -2675,18 +2705,17 @@ assign_section_numbers (abfd) /* Set up the list of section header pointers, in agreement with the indices. */ amt = section_number * sizeof (Elf_Internal_Shdr *); - i_shdrp = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt); + i_shdrp = bfd_zalloc (abfd, amt); if (i_shdrp == NULL) - return false; + return FALSE; amt = sizeof (Elf_Internal_Shdr); - i_shdrp[0] = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt); + i_shdrp[0] = bfd_zalloc (abfd, amt); if (i_shdrp[0] == NULL) { bfd_release (abfd, i_shdrp); - return false; + return FALSE; } - memset (i_shdrp[0], 0, sizeof (Elf_Internal_Shdr)); elf_elfsections (abfd) = i_shdrp; @@ -2767,9 +2796,9 @@ assign_section_numbers (abfd) char *alc; len = strlen (sec->name); - alc = (char *) bfd_malloc ((bfd_size_type) (len - 2)); + alc = bfd_malloc (len - 2); if (alc == NULL) - return false; + return FALSE; memcpy (alc, sec->name, len - 3); alc[len - 3] = '\0'; s = bfd_get_section_by_name (abfd, alc); @@ -2818,30 +2847,27 @@ assign_section_numbers (abfd) else i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd), i_shdrp[secn]->sh_name); - return true; + return TRUE; } /* Map symbol from it's internal number to the external number, moving all local symbols to be at the head of the list. */ -static INLINE int -sym_is_global (abfd, sym) - bfd *abfd; - asymbol *sym; +static int +sym_is_global (bfd *abfd, asymbol *sym) { /* If the backend has a special mapping, use it. */ - if (get_elf_backend_data (abfd)->elf_backend_sym_is_global) - return ((*get_elf_backend_data (abfd)->elf_backend_sym_is_global) - (abfd, sym)); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + if (bed->elf_backend_sym_is_global) + return (*bed->elf_backend_sym_is_global) (abfd, sym); return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0 || bfd_is_und_section (bfd_get_section (sym)) || bfd_is_com_section (bfd_get_section (sym))); } -static boolean -elf_map_symbols (abfd) - bfd *abfd; +static bfd_boolean +elf_map_symbols (bfd *abfd) { unsigned int symcount = bfd_get_symcount (abfd); asymbol **syms = bfd_get_outsymbols (abfd); @@ -2869,9 +2895,9 @@ elf_map_symbols (abfd) max_index++; amt = max_index * sizeof (asymbol *); - sect_syms = (asymbol **) bfd_zalloc (abfd, amt); + sect_syms = bfd_zalloc (abfd, amt); if (sect_syms == NULL) - return false; + return FALSE; elf_section_syms (abfd) = sect_syms; elf_num_section_syms (abfd) = max_index; @@ -2943,10 +2969,10 @@ elf_map_symbols (abfd) /* Now sort the symbols so the local symbols are first. */ amt = (num_locals + num_globals) * sizeof (asymbol *); - new_syms = (asymbol **) bfd_alloc (abfd, amt); + new_syms = bfd_alloc (abfd, amt); if (new_syms == NULL) - return false; + return FALSE; for (idx = 0; idx < symcount; idx++) { @@ -2981,17 +3007,14 @@ elf_map_symbols (abfd) elf_num_locals (abfd) = num_locals; elf_num_globals (abfd) = num_globals; - return true; + return TRUE; } /* Align to the maximum file alignment that could be required for any ELF data structure. */ -static INLINE file_ptr align_file_position PARAMS ((file_ptr, int)); -static INLINE file_ptr -align_file_position (off, align) - file_ptr off; - int align; +static inline file_ptr +align_file_position (file_ptr off, int align) { return (off + align - 1) & ~(align - 1); } @@ -2999,11 +3022,10 @@ align_file_position (off, align) /* Assign a file position to a section, optionally aligning to the required section alignment. */ -INLINE file_ptr -_bfd_elf_assign_file_position_for_section (i_shdrp, offset, align) - Elf_Internal_Shdr *i_shdrp; - file_ptr offset; - boolean align; +file_ptr +_bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp, + file_ptr offset, + bfd_boolean align) { if (align) { @@ -3025,37 +3047,36 @@ _bfd_elf_assign_file_position_for_section (i_shdrp, offset, align) otherwise prepare to begin writing out the ELF file. If LINK_INFO is not NULL, this is being called by the ELF backend linker. */ -boolean -_bfd_elf_compute_section_file_positions (abfd, link_info) - bfd *abfd; - struct bfd_link_info *link_info; +bfd_boolean +_bfd_elf_compute_section_file_positions (bfd *abfd, + struct bfd_link_info *link_info) { - struct elf_backend_data *bed = get_elf_backend_data (abfd); - boolean failed; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + bfd_boolean failed; struct bfd_strtab_hash *strtab; Elf_Internal_Shdr *shstrtab_hdr; if (abfd->output_has_begun) - return true; + return TRUE; /* Do any elf backend specific processing first. */ if (bed->elf_backend_begin_write_processing) (*bed->elf_backend_begin_write_processing) (abfd, link_info); if (! prep_headers (abfd)) - return false; + return FALSE; /* Post process the headers if necessary. */ if (bed->elf_backend_post_process_headers) (*bed->elf_backend_post_process_headers) (abfd, link_info); - failed = false; + failed = FALSE; bfd_map_over_sections (abfd, elf_fake_sections, &failed); if (failed) - return false; + return FALSE; if (!assign_section_numbers (abfd)) - return false; + return FALSE; /* The backend linker builds symbol table information itself. */ if (link_info == NULL && bfd_get_symcount (abfd) > 0) @@ -3064,14 +3085,14 @@ _bfd_elf_compute_section_file_positions (abfd, link_info) int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC)); if (! swap_out_syms (abfd, &strtab, relocatable_p)) - return false; + return FALSE; } if (link_info == NULL) { bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); if (failed) - return false; + return FALSE; } shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr; @@ -3086,8 +3107,8 @@ _bfd_elf_compute_section_file_positions (abfd, link_info) /* sh_offset is set in assign_file_positions_except_relocs. */ shstrtab_hdr->sh_addralign = 1; - if (!assign_file_positions_except_relocs (abfd)) - return false; + if (!assign_file_positions_except_relocs (abfd, link_info)) + return FALSE; if (link_info == NULL && bfd_get_symcount (abfd) > 0) { @@ -3097,14 +3118,14 @@ _bfd_elf_compute_section_file_positions (abfd, link_info) off = elf_tdata (abfd)->next_file_pos; hdr = &elf_tdata (abfd)->symtab_hdr; - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); hdr = &elf_tdata (abfd)->symtab_shndx_hdr; if (hdr->sh_size != 0) - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); hdr = &elf_tdata (abfd)->strtab_hdr; - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); elf_tdata (abfd)->next_file_pos = off; @@ -3112,24 +3133,23 @@ _bfd_elf_compute_section_file_positions (abfd, link_info) out. */ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 || ! _bfd_stringtab_emit (abfd, strtab)) - return false; + return FALSE; _bfd_stringtab_free (strtab); } - abfd->output_has_begun = true; + abfd->output_has_begun = TRUE; - return true; + return TRUE; } /* Create a mapping from a set of sections to a program segment. */ -static INLINE struct elf_segment_map * -make_mapping (abfd, sections, from, to, phdr) - bfd *abfd; - asection **sections; - unsigned int from; - unsigned int to; - boolean phdr; +static struct elf_segment_map * +make_mapping (bfd *abfd, + asection **sections, + unsigned int from, + unsigned int to, + bfd_boolean phdr) { struct elf_segment_map *m; unsigned int i; @@ -3138,7 +3158,7 @@ make_mapping (abfd, sections, from, to, phdr) amt = sizeof (struct elf_segment_map); amt += (to - from - 1) * sizeof (asection *); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); + m = bfd_zalloc (abfd, amt); if (m == NULL) return NULL; m->next = NULL; @@ -3159,9 +3179,8 @@ make_mapping (abfd, sections, from, to, phdr) /* Set up a mapping from BFD sections to program segments. */ -static boolean -map_sections_to_segments (abfd) - bfd *abfd; +static bfd_boolean +map_sections_to_segments (bfd *abfd) { asection **sections = NULL; asection *s; @@ -3171,26 +3190,27 @@ map_sections_to_segments (abfd) struct elf_segment_map **pm; struct elf_segment_map *m; asection *last_hdr; + bfd_vma last_size; unsigned int phdr_index; bfd_vma maxpagesize; asection **hdrpp; - boolean phdr_in_segment = true; - boolean writable; + bfd_boolean phdr_in_segment = TRUE; + bfd_boolean writable; int tls_count = 0; asection *first_tls = NULL; asection *dynsec, *eh_frame_hdr; bfd_size_type amt; if (elf_tdata (abfd)->segment_map != NULL) - return true; + return TRUE; if (bfd_count_sections (abfd) == 0) - return true; + return TRUE; /* Select the allocated sections, and sort them. */ amt = bfd_count_sections (abfd) * sizeof (asection *); - sections = (asection **) bfd_malloc (amt); + sections = bfd_malloc (amt); if (sections == NULL) goto error_return; @@ -3220,7 +3240,7 @@ map_sections_to_segments (abfd) if (s != NULL && (s->flags & SEC_LOAD) != 0) { amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); + m = bfd_zalloc (abfd, amt); if (m == NULL) goto error_return; m->next = NULL; @@ -3234,7 +3254,7 @@ map_sections_to_segments (abfd) pm = &m->next; amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); + m = bfd_zalloc (abfd, amt); if (m == NULL) goto error_return; m->next = NULL; @@ -3250,9 +3270,10 @@ map_sections_to_segments (abfd) segment when the start of the second section can be placed within a few bytes of the end of the first section. */ last_hdr = NULL; + last_size = 0; phdr_index = 0; maxpagesize = get_elf_backend_data (abfd)->maxpagesize; - writable = false; + writable = FALSE; dynsec = bfd_get_section_by_name (abfd, ".dynamic"); if (dynsec != NULL && (dynsec->flags & SEC_LOAD) == 0) @@ -3272,13 +3293,13 @@ map_sections_to_segments (abfd) if ((abfd->flags & D_PAGED) == 0 || sections[0]->lma < phdr_size || sections[0]->lma % maxpagesize < phdr_size % maxpagesize) - phdr_in_segment = false; + phdr_in_segment = FALSE; } for (i = 0, hdrpp = sections; i < count; i++, hdrpp++) { asection *hdr; - boolean new_segment; + bfd_boolean new_segment; hdr = *hdrpp; @@ -3289,39 +3310,40 @@ map_sections_to_segments (abfd) { /* If we don't have a segment yet, then we don't need a new one (we build the last one after this loop). */ - new_segment = false; + new_segment = FALSE; } else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma) { /* If this section has a different relation between the virtual address and the load address, then we need a new segment. */ - new_segment = true; + new_segment = TRUE; } - else if (BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize) + else if (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) < BFD_ALIGN (hdr->lma, maxpagesize)) { /* If putting this section in this segment would force us to skip a page in the segment, then we need a new segment. */ - new_segment = true; + new_segment = TRUE; } - else if ((last_hdr->flags & SEC_LOAD) == 0 - && (hdr->flags & SEC_LOAD) != 0) + else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0 + && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0) { /* We don't want to put a loadable section after a - nonloadable section in the same segment. */ - new_segment = true; + nonloadable section in the same segment. + Consider .tbss sections as loadable for this purpose. */ + new_segment = TRUE; } else if ((abfd->flags & D_PAGED) == 0) { /* If the file is not demand paged, which means that we don't require the sections to be correctly aligned in the file, then there is no other reason for a new segment. */ - new_segment = false; + new_segment = FALSE; } else if (! writable && (hdr->flags & SEC_READONLY) == 0 - && (((last_hdr->lma + last_hdr->_raw_size - 1) + && (((last_hdr->lma + last_size - 1) & ~(maxpagesize - 1)) != (hdr->lma & ~(maxpagesize - 1)))) { @@ -3332,19 +3354,24 @@ map_sections_to_segments (abfd) only case in which the new section is not on the same page as the previous section is when the previous section ends precisely on a page boundary. */ - new_segment = true; + new_segment = TRUE; } else { /* Otherwise, we can use the same segment. */ - new_segment = false; + new_segment = FALSE; } if (! new_segment) { if ((hdr->flags & SEC_READONLY) == 0) - writable = true; + writable = TRUE; last_hdr = hdr; + /* .tbss sections effectively have zero size. */ + if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL) + last_size = hdr->_raw_size; + else + last_size = 0; continue; } @@ -3359,13 +3386,18 @@ map_sections_to_segments (abfd) pm = &m->next; if ((hdr->flags & SEC_READONLY) == 0) - writable = true; + writable = TRUE; else - writable = false; + writable = FALSE; last_hdr = hdr; + /* .tbss sections effectively have zero size. */ + if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL) + last_size = hdr->_raw_size; + else + last_size = 0; phdr_index = i; - phdr_in_segment = false; + phdr_in_segment = FALSE; } /* Create a final PT_LOAD program segment. */ @@ -3383,7 +3415,7 @@ map_sections_to_segments (abfd) if (dynsec != NULL) { amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); + m = bfd_zalloc (abfd, amt); if (m == NULL) goto error_return; m->next = NULL; @@ -3406,7 +3438,7 @@ map_sections_to_segments (abfd) && strncmp (s->name, ".note", 5) == 0) { amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); + m = bfd_zalloc (abfd, amt); if (m == NULL) goto error_return; m->next = NULL; @@ -3432,7 +3464,7 @@ map_sections_to_segments (abfd) amt = sizeof (struct elf_segment_map); amt += (tls_count - 1) * sizeof (asection *); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); + m = bfd_zalloc (abfd, amt); if (m == NULL) goto error_return; m->next = NULL; @@ -3454,19 +3486,33 @@ map_sections_to_segments (abfd) /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME segment. */ - eh_frame_hdr = NULL; - if (elf_tdata (abfd)->eh_frame_hdr) - eh_frame_hdr = bfd_get_section_by_name (abfd, ".eh_frame_hdr"); - if (eh_frame_hdr != NULL && (eh_frame_hdr->flags & SEC_LOAD)) + eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr; + if (eh_frame_hdr != NULL + && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0) { amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); + m = bfd_zalloc (abfd, amt); if (m == NULL) goto error_return; m->next = NULL; m->p_type = PT_GNU_EH_FRAME; m->count = 1; - m->sections[0] = eh_frame_hdr; + m->sections[0] = eh_frame_hdr->output_section; + + *pm = m; + pm = &m->next; + } + + if (elf_tdata (abfd)->stack_flags) + { + amt = sizeof (struct elf_segment_map); + m = bfd_zalloc (abfd, amt); + if (m == NULL) + goto error_return; + m->next = NULL; + m->p_type = PT_GNU_STACK; + m->p_flags = elf_tdata (abfd)->stack_flags; + m->p_flags_valid = 1; *pm = m; pm = &m->next; @@ -3476,23 +3522,22 @@ map_sections_to_segments (abfd) sections = NULL; elf_tdata (abfd)->segment_map = mfirst; - return true; + return TRUE; error_return: if (sections != NULL) free (sections); - return false; + return FALSE; } /* Sort sections by address. */ static int -elf_sort_sections (arg1, arg2) - const PTR arg1; - const PTR arg2; +elf_sort_sections (const void *arg1, const void *arg2) { const asection *sec1 = *(const asection **) arg1; const asection *sec2 = *(const asection **) arg2; + bfd_size_type size1, size2; /* Sort by LMA first, since this is the address used to place the section into a segment. */ @@ -3510,7 +3555,7 @@ elf_sort_sections (arg1, arg2) /* Put !SEC_LOAD sections after SEC_LOAD ones. */ -#define TOEND(x) (((x)->flags & SEC_LOAD) == 0) +#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0) if (TOEND (sec1)) { @@ -3532,21 +3577,52 @@ elf_sort_sections (arg1, arg2) /* Sort by size, to put zero sized sections before others at the same address. */ - if (sec1->_raw_size < sec2->_raw_size) + size1 = (sec1->flags & SEC_LOAD) ? sec1->_raw_size : 0; + size2 = (sec2->flags & SEC_LOAD) ? sec2->_raw_size : 0; + + if (size1 < size2) return -1; - if (sec1->_raw_size > sec2->_raw_size) + if (size1 > size2) return 1; return sec1->target_index - sec2->target_index; } +/* Ian Lance Taylor writes: + + We shouldn't be using % with a negative signed number. That's just + not good. We have to make sure either that the number is not + negative, or that the number has an unsigned type. When the types + are all the same size they wind up as unsigned. When file_ptr is a + larger signed type, the arithmetic winds up as signed long long, + which is wrong. + + What we're trying to say here is something like ``increase OFF by + the least amount that will cause it to be equal to the VMA modulo + the page size.'' */ +/* In other words, something like: + + vma_offset = m->sections[0]->vma % bed->maxpagesize; + off_offset = off % bed->maxpagesize; + if (vma_offset < off_offset) + adjustment = vma_offset + bed->maxpagesize - off_offset; + else + adjustment = vma_offset - off_offset; + + which can can be collapsed into the expression below. */ + +static file_ptr +vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize) +{ + return ((vma - off) % maxpagesize); +} + /* Assign file positions to the sections based on the mapping from sections to segments. This function also sets up some fields in the file header, and writes out the program headers. */ -static boolean -assign_file_positions_for_segments (abfd) - bfd *abfd; +static bfd_boolean +assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info) { const struct elf_backend_data *bed = get_elf_backend_data (abfd); unsigned int count; @@ -3562,7 +3638,7 @@ assign_file_positions_for_segments (abfd) if (elf_tdata (abfd)->segment_map == NULL) { if (! map_sections_to_segments (abfd)) - return false; + return FALSE; } else { @@ -3598,8 +3674,8 @@ assign_file_positions_for_segments (abfd) if (bed->elf_backend_modify_segment_map) { - if (! (*bed->elf_backend_modify_segment_map) (abfd)) - return false; + if (! (*bed->elf_backend_modify_segment_map) (abfd, link_info)) + return FALSE; } count = 0; @@ -3611,7 +3687,7 @@ assign_file_positions_for_segments (abfd) elf_elfheader (abfd)->e_phnum = count; if (count == 0) - return true; + return TRUE; /* If we already counted the number of program segments, make sure that we allocated enough space. This happens when SIZEOF_HEADERS @@ -3623,16 +3699,16 @@ assign_file_positions_for_segments (abfd) (_("%s: Not enough room for program headers (allocated %u, need %u)"), bfd_get_filename (abfd), alloc, count)); bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } if (alloc == 0) alloc = count; amt = alloc * sizeof (Elf_Internal_Phdr); - phdrs = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt); + phdrs = bfd_alloc (abfd, amt); if (phdrs == NULL) - return false; + return FALSE; off = bed->s->sizeof_ehdr; off += alloc * bed->s->sizeof_phdr; @@ -3668,7 +3744,8 @@ assign_file_positions_for_segments (abfd) && (m->sections[0]->flags & SEC_ALLOC) != 0) { if ((abfd->flags & D_PAGED) != 0) - off += (m->sections[0]->vma - off) % bed->maxpagesize; + off += vma_page_aligned_bias (m->sections[0]->vma, off, + bed->maxpagesize); else { bfd_size_type align; @@ -3683,7 +3760,8 @@ assign_file_positions_for_segments (abfd) align = secalign; } - off += (m->sections[0]->vma - off) % (1 << align); + off += vma_page_aligned_bias (m->sections[0]->vma, off, + 1 << align); } } @@ -3703,7 +3781,7 @@ assign_file_positions_for_segments (abfd) && (abfd->flags & D_PAGED) != 0) p->p_align = bed->maxpagesize; else if (m->count == 0) - p->p_align = bed->s->file_align; + p->p_align = 1 << bed->s->log_file_align; else p->p_align = 0; @@ -3728,7 +3806,7 @@ assign_file_positions_for_segments (abfd) (_("%s: Not enough room for program headers, try linking with -N"), bfd_get_filename (abfd)); bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } p->p_vaddr -= off; @@ -3815,9 +3893,15 @@ assign_file_positions_for_segments (abfd) bfd_vma adjust = sec->lma - (p->p_paddr + p->p_memsz); p->p_memsz += adjust; - off += adjust; - voff += adjust; - if ((flags & SEC_LOAD) != 0) + if (p->p_type == PT_LOAD + || (p->p_type == PT_NOTE + && bfd_get_format (abfd) == bfd_core)) + { + off += adjust; + voff += adjust; + } + if ((flags & SEC_LOAD) != 0 + || (flags & SEC_THREAD_LOCAL) != 0) p->p_filesz += adjust; } @@ -3839,9 +3923,11 @@ assign_file_positions_for_segments (abfd) not have the SEC_LOAD case just above, and then this was necessary, but now I'm not sure. */ if ((abfd->flags & D_PAGED) != 0) - adjust = (sec->vma - voff) % bed->maxpagesize; + adjust = vma_page_aligned_bias (sec->vma, voff, + bed->maxpagesize); else - adjust = (sec->vma - voff) % align; + adjust = vma_page_aligned_bias (sec->vma, voff, + align); } else adjust = 0; @@ -3855,7 +3941,7 @@ Error: First section in segment (%s) starts at 0x%x whereas the segment starts a bfd_section_name (abfd, sec), sec->lma, p->p_paddr); - return false; + return FALSE; } p->p_memsz += adjust; off += adjust; @@ -3874,7 +3960,9 @@ Error: First section in segment (%s) starts at 0x%x whereas the segment starts a || (flags & SEC_HAS_CONTENTS) != 0) off += sec->_raw_size; - if ((flags & SEC_ALLOC) != 0) + if ((flags & SEC_ALLOC) != 0 + && ((flags & SEC_LOAD) != 0 + || (flags & SEC_THREAD_LOCAL) == 0)) voff += sec->_raw_size; } @@ -3901,6 +3989,9 @@ Error: First section in segment (%s) starts at 0x%x whereas the segment starts a } else { + if ((sec->flags & SEC_LOAD) != 0 + || (sec->flags & SEC_THREAD_LOCAL) == 0 + || p->p_type == PT_TLS) p->p_memsz += sec->_raw_size; if ((flags & SEC_LOAD) != 0) @@ -3978,9 +4069,9 @@ Error: First section in segment (%s) starts at 0x%x whereas the segment starts a /* Write out the program headers. */ if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0 || bed->s->write_out_phdrs (abfd, phdrs, alloc) != 0) - return false; + return FALSE; - return true; + return TRUE; } /* Get the size of the program header. @@ -3995,12 +4086,11 @@ Error: First section in segment (%s) starts at 0x%x whereas the segment starts a will be two segments. */ static bfd_size_type -get_program_header_size (abfd) - bfd *abfd; +get_program_header_size (bfd *abfd) { size_t segs; asection *s; - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); /* We can't return a different result each time we're called. */ if (elf_tdata (abfd)->program_header_size != 0) @@ -4037,13 +4127,18 @@ get_program_header_size (abfd) ++segs; } - if (elf_tdata (abfd)->eh_frame_hdr - && bfd_get_section_by_name (abfd, ".eh_frame_hdr") != NULL) + if (elf_tdata (abfd)->eh_frame_hdr) { /* We need a PT_GNU_EH_FRAME segment. */ ++segs; } + if (elf_tdata (abfd)->stack_flags) + { + /* We need a PT_GNU_STACK segment. */ + ++segs; + } + for (s = abfd->sections; s != NULL; s = s->next) { if ((s->flags & SEC_LOAD) != 0 @@ -4090,16 +4185,16 @@ get_program_header_size (abfd) We also don't set the positions of the .symtab and .strtab here. */ -static boolean -assign_file_positions_except_relocs (abfd) - bfd *abfd; +static bfd_boolean +assign_file_positions_except_relocs (bfd *abfd, + struct bfd_link_info *link_info) { struct elf_obj_tdata * const tdata = elf_tdata (abfd); Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd); Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); unsigned int num_sec = elf_numsections (abfd); file_ptr off; - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 && bfd_get_format (abfd) != bfd_core) @@ -4127,7 +4222,7 @@ assign_file_positions_except_relocs (abfd) hdr->sh_offset = -1; } else - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); if (i == SHN_LORESERVE - 1) { @@ -4143,8 +4238,8 @@ assign_file_positions_except_relocs (abfd) /* Assign file positions for the loaded sections based on the assignment of sections to segments. */ - if (! assign_file_positions_for_segments (abfd)) - return false; + if (! assign_file_positions_for_segments (abfd, link_info)) + return FALSE; /* Assign file positions for the other sections. */ @@ -4166,20 +4261,20 @@ assign_file_positions_except_relocs (abfd) ? "*unknown*" : hdr->bfd_section->name))); if ((abfd->flags & D_PAGED) != 0) - off += (hdr->sh_addr - off) % bed->maxpagesize; + off += vma_page_aligned_bias (hdr->sh_addr, off, + bed->maxpagesize); else - off += (hdr->sh_addr - off) % hdr->sh_addralign; + off += vma_page_aligned_bias (hdr->sh_addr, off, + hdr->sh_addralign); off = _bfd_elf_assign_file_position_for_section (hdr, off, - false); + FALSE); } - else if (hdr->sh_type == SHT_REL - || hdr->sh_type == SHT_RELA - || hdr == i_shdrpp[tdata->symtab_section] + else if (hdr == i_shdrpp[tdata->symtab_section] || hdr == i_shdrpp[tdata->symtab_shndx_section] || hdr == i_shdrpp[tdata->strtab_section]) hdr->sh_offset = -1; else - off = _bfd_elf_assign_file_position_for_section (hdr, off, true); + off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); if (i == SHN_LORESERVE - 1) { @@ -4190,31 +4285,30 @@ assign_file_positions_except_relocs (abfd) } /* Place the section headers. */ - off = align_file_position (off, bed->s->file_align); + off = align_file_position (off, 1 << bed->s->log_file_align); i_ehdrp->e_shoff = off; off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize; elf_tdata (abfd)->next_file_pos = off; - return true; + return TRUE; } -static boolean -prep_headers (abfd) - bfd *abfd; +static bfd_boolean +prep_headers (bfd *abfd) { Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */ Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ struct elf_strtab_hash *shstrtab; - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); i_ehdrp = elf_elfheader (abfd); i_shdrp = elf_elfsections (abfd); shstrtab = _bfd_elf_strtab_init (); if (shstrtab == NULL) - return false; + return FALSE; elf_shstrtab (abfd) = shstrtab; @@ -4254,11 +4348,8 @@ prep_headers (abfd) Such need can generally be supplied by replacing the tests for e_machine with the conditions used to determine it. */ default: - if (get_elf_backend_data (abfd) != NULL) - i_ehdrp->e_machine = get_elf_backend_data (abfd)->elf_machine_code; - else - i_ehdrp->e_machine = EM_NONE; - } + i_ehdrp->e_machine = bed->elf_machine_code; + } i_ehdrp->e_version = bed->s->ev_current; i_ehdrp->e_ehsize = bed->s->sizeof_ehdr; @@ -4294,25 +4385,24 @@ prep_headers (abfd) } elf_tdata (abfd)->symtab_hdr.sh_name = - (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", false); + (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", FALSE); elf_tdata (abfd)->strtab_hdr.sh_name = - (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", false); + (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", FALSE); elf_tdata (abfd)->shstrtab_hdr.sh_name = - (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", false); + (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE); if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1) - return false; + return FALSE; - return true; + return TRUE; } /* Assign file positions for all the reloc sections which are not part of the loadable file image. */ void -_bfd_elf_assign_file_positions_for_relocs (abfd) - bfd *abfd; +_bfd_elf_assign_file_positions_for_relocs (bfd *abfd) { file_ptr off; unsigned int i, num_sec; @@ -4328,34 +4418,32 @@ _bfd_elf_assign_file_positions_for_relocs (abfd) shdrp = *shdrpp; if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA) && shdrp->sh_offset == -1) - off = _bfd_elf_assign_file_position_for_section (shdrp, off, true); + off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE); } elf_tdata (abfd)->next_file_pos = off; } -boolean -_bfd_elf_write_object_contents (abfd) - bfd *abfd; +bfd_boolean +_bfd_elf_write_object_contents (bfd *abfd) { - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); Elf_Internal_Ehdr *i_ehdrp; Elf_Internal_Shdr **i_shdrp; - boolean failed; + bfd_boolean failed; unsigned int count, num_sec; if (! abfd->output_has_begun - && ! _bfd_elf_compute_section_file_positions - (abfd, (struct bfd_link_info *) NULL)) - return false; + && ! _bfd_elf_compute_section_file_positions (abfd, NULL)) + return FALSE; i_shdrp = elf_elfsections (abfd); i_ehdrp = elf_elfheader (abfd); - failed = false; + failed = FALSE; bfd_map_over_sections (abfd, bed->s->write_relocs, &failed); if (failed) - return false; + return FALSE; _bfd_elf_assign_file_positions_for_relocs (abfd); @@ -4371,7 +4459,7 @@ _bfd_elf_write_object_contents (abfd) if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0 || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt) - return false; + return FALSE; } if (count == SHN_LORESERVE - 1) count += SHN_HIRESERVE + 1 - SHN_LORESERVE; @@ -4380,7 +4468,7 @@ _bfd_elf_write_object_contents (abfd) /* Write out the section header names. */ if (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0 || ! _bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd))) - return false; + return FALSE; if (bed->elf_backend_final_write_processing) (*bed->elf_backend_final_write_processing) (abfd, @@ -4389,9 +4477,8 @@ _bfd_elf_write_object_contents (abfd) return bed->s->write_shdrs_and_ehdr (abfd); } -boolean -_bfd_elf_write_corefile_contents (abfd) - bfd *abfd; +bfd_boolean +_bfd_elf_write_corefile_contents (bfd *abfd) { /* Hopefully this can be done just like an object file. */ return _bfd_elf_write_object_contents (abfd); @@ -4400,11 +4487,9 @@ _bfd_elf_write_corefile_contents (abfd) /* Given a section, search the header to find them. */ int -_bfd_elf_section_from_bfd_section (abfd, asect) - bfd *abfd; - struct sec *asect; +_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect) { - struct elf_backend_data *bed; + const struct elf_backend_data *bed; int index; if (elf_section_data (asect) != NULL @@ -4451,9 +4536,7 @@ _bfd_elf_section_from_bfd_section (abfd, asect) on error. */ int -_bfd_elf_symbol_from_bfd_symbol (abfd, asym_ptr_ptr) - bfd *abfd; - asymbol **asym_ptr_ptr; +_bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr) { asymbol *asym_ptr = *asym_ptr_ptr; int idx; @@ -4507,31 +4590,29 @@ _bfd_elf_symbol_from_bfd_symbol (abfd, asym_ptr_ptr) /* Copy private BFD data. This copies any program header information. */ -static boolean -copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - Elf_Internal_Ehdr * iehdr; - struct elf_segment_map * map; - struct elf_segment_map * map_first; - struct elf_segment_map ** pointer_to_map; - Elf_Internal_Phdr * segment; - asection * section; - unsigned int i; - unsigned int num_segments; - boolean phdr_included = false; - bfd_vma maxpagesize; - struct elf_segment_map * phdr_adjust_seg = NULL; - unsigned int phdr_adjust_num = 0; - struct elf_backend_data * bed; +static bfd_boolean +copy_private_bfd_data (bfd *ibfd, bfd *obfd) +{ + Elf_Internal_Ehdr *iehdr; + struct elf_segment_map *map; + struct elf_segment_map *map_first; + struct elf_segment_map **pointer_to_map; + Elf_Internal_Phdr *segment; + asection *section; + unsigned int i; + unsigned int num_segments; + bfd_boolean phdr_included = FALSE; + bfd_vma maxpagesize; + struct elf_segment_map *phdr_adjust_seg = NULL; + unsigned int phdr_adjust_num = 0; + const struct elf_backend_data *bed; if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; + return TRUE; if (elf_tdata (ibfd)->phdr == NULL) - return true; + return TRUE; bed = get_elf_backend_data (ibfd); iehdr = elf_elfheader (ibfd); @@ -4547,18 +4628,23 @@ copy_private_bfd_data (ibfd, obfd) (start + (segment->p_memsz > segment->p_filesz \ ? segment->p_memsz : segment->p_filesz)) - /* Returns true if the given section is contained within +#define SECTION_SIZE(section, segment) \ + (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) \ + != SEC_THREAD_LOCAL || segment->p_type == PT_TLS) \ + ? section->_raw_size : 0) + + /* Returns TRUE if the given section is contained within the given segment. VMA addresses are compared. */ #define IS_CONTAINED_BY_VMA(section, segment) \ (section->vma >= segment->p_vaddr \ - && (section->vma + section->_raw_size \ + && (section->vma + SECTION_SIZE (section, segment) \ <= (SEGMENT_END (segment, segment->p_vaddr)))) - /* Returns true if the given section is contained within + /* Returns TRUE if the given section is contained within the given segment. LMA addresses are compared. */ #define IS_CONTAINED_BY_LMA(section, segment, base) \ (section->lma >= base \ - && (section->lma + section->_raw_size \ + && (section->lma + SECTION_SIZE (section, segment) \ <= SEGMENT_END (segment, base))) /* Special case: corefile "NOTE" section containing regs, prpsinfo etc. */ @@ -4590,7 +4676,10 @@ copy_private_bfd_data (ibfd, obfd) if that is set for the segment and the VMA otherwise, 2. It is an allocated segment, 3. There is an output section associated with it, - 4. The section has not already been allocated to a previous segment. */ + 4. The section has not already been allocated to a previous segment. + 5. PT_GNU_STACK segments do not include any sections. + 6. PT_TLS segment includes only SHF_TLS sections. + 7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments. */ #define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \ ((((segment->p_paddr \ ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \ @@ -4598,20 +4687,33 @@ copy_private_bfd_data (ibfd, obfd) && (section->flags & SEC_ALLOC) != 0) \ || IS_COREFILE_NOTE (segment, section)) \ && section->output_section != NULL \ + && segment->p_type != PT_GNU_STACK \ + && (segment->p_type != PT_TLS \ + || (section->flags & SEC_THREAD_LOCAL)) \ + && (segment->p_type == PT_LOAD \ + || segment->p_type == PT_TLS \ + || (section->flags & SEC_THREAD_LOCAL) == 0) \ && ! section->segment_mark) - /* Returns true iff seg1 starts after the end of seg2. */ -#define SEGMENT_AFTER_SEGMENT(seg1, seg2) \ - (seg1->p_vaddr >= SEGMENT_END (seg2, seg2->p_vaddr)) + /* Returns TRUE iff seg1 starts after the end of seg2. */ +#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field) \ + (seg1->field >= SEGMENT_END (seg2, seg2->field)) - /* Returns true iff seg1 and seg2 overlap. */ + /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both + their VMA address ranges and their LMA address ranges overlap. + It is possible to have overlapping VMA ranges without overlapping LMA + ranges. RedBoot images for example can have both .data and .bss mapped + to the same VMA range, but with the .data section mapped to a different + LMA. */ #define SEGMENT_OVERLAPS(seg1, seg2) \ - (!(SEGMENT_AFTER_SEGMENT (seg1, seg2) \ - || SEGMENT_AFTER_SEGMENT (seg2, seg1))) + ( !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr) \ + || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr)) \ + && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr) \ + || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr))) /* Initialise the segment mark field. */ for (section = ibfd->sections; section != NULL; section = section->next) - section->segment_mark = false; + section->segment_mark = FALSE; /* Scan through the segments specified in the program header of the input BFD. For this first scan we look for overlaps @@ -4629,7 +4731,7 @@ copy_private_bfd_data (ibfd, obfd) if (IS_SOLARIS_PT_INTERP (segment, section)) { /* Mininal change so that the normal section to segment - assigment code will work. */ + assignment code will work. */ segment->p_vaddr = section->vma; break; } @@ -4705,18 +4807,19 @@ copy_private_bfd_data (ibfd, obfd) continue; /* Compute how many sections might be placed into this segment. */ - section_count = 0; - for (section = ibfd->sections; section != NULL; section = section->next) + for (section = ibfd->sections, section_count = 0; + section != NULL; + section = section->next) if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed)) ++section_count; - /* Allocate a segment map big enough to contain all of the - sections we have selected. */ + /* Allocate a segment map big enough to contain + all of the sections we have selected. */ amt = sizeof (struct elf_segment_map); amt += ((bfd_size_type) section_count - 1) * sizeof (asection *); - map = (struct elf_segment_map *) bfd_alloc (obfd, amt); + map = bfd_alloc (obfd, amt); if (map == NULL) - return false; + return FALSE; /* Initialise the fields of the segment map. Default to using the physical address of the segment in the input BFD. */ @@ -4743,7 +4846,7 @@ copy_private_bfd_data (ibfd, obfd) + iehdr->e_phnum * iehdr->e_phentsize))); if (segment->p_type == PT_LOAD && map->includes_phdrs) - phdr_included = true; + phdr_included = TRUE; } if (section_count == 0) @@ -4783,7 +4886,7 @@ copy_private_bfd_data (ibfd, obfd) and possibly its LMA changed, and a new segment or segments will have to be created to contain the other sections. - 4. The sections have been moved, but not be the same amount. + 4. The sections have been moved, but not by the same amount. In this case we can change the segment's LMA to match the LMA of the first section and we will have to create a new segment or segments to contain the other sections. @@ -4795,9 +4898,9 @@ copy_private_bfd_data (ibfd, obfd) /* Gcc 2.96 miscompiles this code on mips. Don't do casting here to work around this long long bug. */ amt = section_count * sizeof (asection *); - sections = (asection **) bfd_malloc (amt); + sections = bfd_malloc (amt); if (sections == NULL) - return false; + return FALSE; /* Step One: Scan for segment vs section LMA conflicts. Also add the sections to the section array allocated above. @@ -4978,7 +5081,7 @@ copy_private_bfd_data (ibfd, obfd) map->sections[map->count++] = output_section; ++isec; sections[j] = NULL; - section->segment_mark = true; + section->segment_mark = TRUE; } else if (suggested_lma == 0) suggested_lma = output_section->lma; @@ -4997,9 +5100,12 @@ copy_private_bfd_data (ibfd, obfd) and carry on looping. */ amt = sizeof (struct elf_segment_map); amt += ((bfd_size_type) section_count - 1) * sizeof (asection *); - map = (struct elf_segment_map *) bfd_alloc (obfd, amt); + map = bfd_alloc (obfd, amt); if (map == NULL) - return false; + { + free (sections); + return FALSE; + } /* Initialise the fields of the segment map. Set the physical physical address to the LMA of the first section that has @@ -5027,10 +5133,8 @@ copy_private_bfd_data (ibfd, obfd) if (map->p_paddr != 0) break; if (map == NULL) - { - for (map = map_first; map != NULL; map = map->next) - map->p_paddr_valid = 0; - } + for (map = map_first; map != NULL; map = map->next) + map->p_paddr_valid = 0; elf_tdata (obfd)->segment_map = map_first; @@ -5075,6 +5179,7 @@ copy_private_bfd_data (ibfd, obfd) #endif #undef SEGMENT_END +#undef SECTION_SIZE #undef IS_CONTAINED_BY_VMA #undef IS_CONTAINED_BY_LMA #undef IS_COREFILE_NOTE @@ -5082,24 +5187,23 @@ copy_private_bfd_data (ibfd, obfd) #undef INCLUDE_SECTION_IN_SEGMENT #undef SEGMENT_AFTER_SEGMENT #undef SEGMENT_OVERLAPS - return true; + return TRUE; } /* Copy private section information. This copies over the entsize field, and sometimes the info field. */ -boolean -_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec) - bfd *ibfd; - asection *isec; - bfd *obfd; - asection *osec; +bfd_boolean +_bfd_elf_copy_private_section_data (bfd *ibfd, + asection *isec, + bfd *obfd, + asection *osec) { Elf_Internal_Shdr *ihdr, *ohdr; if (ibfd->xvec->flavour != bfd_target_elf_flavour || obfd->xvec->flavour != bfd_target_elf_flavour) - return true; + return TRUE; if (elf_tdata (obfd)->segment_map == NULL && elf_tdata (ibfd)->phdr != NULL) { @@ -5115,7 +5219,7 @@ _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec) if (s == NULL) { if (! copy_private_bfd_data (ibfd, obfd)) - return false; + return FALSE; } } @@ -5136,10 +5240,9 @@ _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec) elf_next_in_group (osec) = elf_next_in_group (isec); elf_group_name (osec) = elf_group_name (isec); - elf_section_data (osec)->use_rela_p - = elf_section_data (isec)->use_rela_p; + osec->use_rela_p = isec->use_rela_p; - return true; + return TRUE; } /* Copy private symbol information. If this symbol is in a section @@ -5154,18 +5257,17 @@ _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec) #define MAP_SHSTRTAB (SHN_HIOS + 4) #define MAP_SYM_SHNDX (SHN_HIOS + 5) -boolean -_bfd_elf_copy_private_symbol_data (ibfd, isymarg, obfd, osymarg) - bfd *ibfd; - asymbol *isymarg; - bfd *obfd; - asymbol *osymarg; +bfd_boolean +_bfd_elf_copy_private_symbol_data (bfd *ibfd, + asymbol *isymarg, + bfd *obfd, + asymbol *osymarg) { elf_symbol_type *isym, *osym; if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; + return TRUE; isym = elf_symbol_from (ibfd, isymarg); osym = elf_symbol_from (obfd, osymarg); @@ -5190,18 +5292,17 @@ _bfd_elf_copy_private_symbol_data (ibfd, isymarg, obfd, osymarg) osym->internal_elf_sym.st_shndx = shndx; } - return true; + return TRUE; } /* Swap out the symbols. */ -static boolean -swap_out_syms (abfd, sttp, relocatable_p) - bfd *abfd; - struct bfd_strtab_hash **sttp; - int relocatable_p; +static bfd_boolean +swap_out_syms (bfd *abfd, + struct bfd_strtab_hash **sttp, + int relocatable_p) { - struct elf_backend_data *bed; + const struct elf_backend_data *bed; int symcount; asymbol **syms; struct bfd_strtab_hash *stt; @@ -5212,14 +5313,15 @@ swap_out_syms (abfd, sttp, relocatable_p) char *outbound_shndx; int idx; bfd_size_type amt; + bfd_boolean name_local_sections; if (!elf_map_symbols (abfd)) - return false; + return FALSE; /* Dump out the symtabs. */ stt = _bfd_elf_stringtab_init (); if (stt == NULL) - return false; + return FALSE; bed = get_elf_backend_data (abfd); symcount = bfd_get_symcount (abfd); @@ -5228,7 +5330,7 @@ swap_out_syms (abfd, sttp, relocatable_p) symtab_hdr->sh_entsize = bed->s->sizeof_sym; symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1); symtab_hdr->sh_info = elf_num_locals (abfd) + 1; - symtab_hdr->sh_addralign = bed->s->file_align; + symtab_hdr->sh_addralign = 1 << bed->s->log_file_align; symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; symstrtab_hdr->sh_type = SHT_STRTAB; @@ -5236,8 +5338,11 @@ swap_out_syms (abfd, sttp, relocatable_p) amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym; outbound_syms = bfd_alloc (abfd, amt); if (outbound_syms == NULL) - return false; - symtab_hdr->contents = (PTR) outbound_syms; + { + _bfd_stringtab_free (stt); + return FALSE; + } + symtab_hdr->contents = outbound_syms; outbound_shndx = NULL; symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; @@ -5246,7 +5351,11 @@ swap_out_syms (abfd, sttp, relocatable_p) amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx); outbound_shndx = bfd_zalloc (abfd, amt); if (outbound_shndx == NULL) - return false; + { + _bfd_stringtab_free (stt); + return FALSE; + } + symtab_shndx_hdr->contents = outbound_shndx; symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; symtab_shndx_hdr->sh_size = amt; @@ -5254,7 +5363,7 @@ swap_out_syms (abfd, sttp, relocatable_p) symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); } - /* now generate the data (for "contents") */ + /* Now generate the data (for "contents"). */ { /* Fill in zeroth symbol and swap it out. */ Elf_Internal_Sym sym; @@ -5270,6 +5379,10 @@ swap_out_syms (abfd, sttp, relocatable_p) outbound_shndx += sizeof (Elf_External_Sym_Shndx); } + name_local_sections + = (bed->elf_backend_name_local_section_symbols + && bed->elf_backend_name_local_section_symbols (abfd)); + syms = bfd_get_outsymbols (abfd); for (idx = 0; idx < symcount; idx++) { @@ -5279,7 +5392,8 @@ swap_out_syms (abfd, sttp, relocatable_p) flagword flags = syms[idx]->flags; int type; - if ((flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM) + if (!name_local_sections + && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM) { /* Local section symbols have no name. */ sym.st_name = 0; @@ -5288,9 +5402,12 @@ swap_out_syms (abfd, sttp, relocatable_p) { sym.st_name = (unsigned long) _bfd_stringtab_add (stt, syms[idx]->name, - true, false); + TRUE, FALSE); if (sym.st_name == (unsigned long) -1) - return false; + { + _bfd_stringtab_free (stt); + return FALSE; + } } type_ptr = elf_symbol_from (abfd, syms[idx]); @@ -5320,6 +5437,7 @@ swap_out_syms (abfd, sttp, relocatable_p) value += sec->output_offset; sec = sec->output_section; } + /* Don't add in the section vma for relocatable output. */ if (! relocatable_p) value += sec->vma; @@ -5371,7 +5489,17 @@ swap_out_syms (abfd, sttp, relocatable_p) section of a symbol to be a section that is actually in the output file. */ sec2 = bfd_get_section_by_name (abfd, sec->name); - BFD_ASSERT (sec2 != 0); + if (sec2 == NULL) + { + _bfd_error_handler (_("\ +Unable to find equivalent output section for symbol '%s' from section '%s'"), + syms[idx]->name ? syms[idx]->name : "<Local sym>", + sec->name); + bfd_set_error (bfd_error_invalid_operation); + _bfd_stringtab_free (stt); + return FALSE; + } + shndx = _bfd_elf_section_from_bfd_section (abfd, sec2); BFD_ASSERT (shndx != -1); } @@ -5392,7 +5520,7 @@ swap_out_syms (abfd, sttp, relocatable_p) if (syms[idx]->section->flags & SEC_THREAD_LOCAL) type = STT_TLS; - /* Processor-specific types */ + /* Processor-specific types. */ if (type_ptr != NULL && bed->elf_backend_get_symbol_type) type = ((*bed->elf_backend_get_symbol_type) @@ -5450,7 +5578,7 @@ swap_out_syms (abfd, sttp, relocatable_p) symstrtab_hdr->sh_info = 0; symstrtab_hdr->sh_addralign = 1; - return true; + return TRUE; } /* Return the number of bytes required to hold the symtab vector. @@ -5460,8 +5588,7 @@ swap_out_syms (abfd, sttp, relocatable_p) always has a dummy entry as symbol #0, so it ends up even. */ long -_bfd_elf_get_symtab_upper_bound (abfd) - bfd *abfd; +_bfd_elf_get_symtab_upper_bound (bfd *abfd) { long symcount; long symtab_size; @@ -5476,8 +5603,7 @@ _bfd_elf_get_symtab_upper_bound (abfd) } long -_bfd_elf_get_dynamic_symtab_upper_bound (abfd) - bfd *abfd; +_bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) { long symcount; long symtab_size; @@ -5498,9 +5624,8 @@ _bfd_elf_get_dynamic_symtab_upper_bound (abfd) } long -_bfd_elf_get_reloc_upper_bound (abfd, asect) - bfd *abfd ATTRIBUTE_UNUSED; - sec_ptr asect; +_bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, + sec_ptr asect) { return (asect->reloc_count + 1) * sizeof (arelent *); } @@ -5508,17 +5633,16 @@ _bfd_elf_get_reloc_upper_bound (abfd, asect) /* Canonicalize the relocs. */ long -_bfd_elf_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; +_bfd_elf_canonicalize_reloc (bfd *abfd, + sec_ptr section, + arelent **relptr, + asymbol **symbols) { arelent *tblptr; unsigned int i; - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); - if (! bed->s->slurp_reloc_table (abfd, section, symbols, false)) + if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE)) return -1; tblptr = section->relocation; @@ -5531,12 +5655,10 @@ _bfd_elf_canonicalize_reloc (abfd, section, relptr, symbols) } long -_bfd_elf_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; +_bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation) { - struct elf_backend_data *bed = get_elf_backend_data (abfd); - long symcount = bed->s->slurp_symbol_table (abfd, alocation, false); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE); if (symcount >= 0) bfd_get_symcount (abfd) = symcount; @@ -5544,12 +5666,11 @@ _bfd_elf_get_symtab (abfd, alocation) } long -_bfd_elf_canonicalize_dynamic_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; +_bfd_elf_canonicalize_dynamic_symtab (bfd *abfd, + asymbol **allocation) { - struct elf_backend_data *bed = get_elf_backend_data (abfd); - long symcount = bed->s->slurp_symbol_table (abfd, alocation, true); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE); if (symcount >= 0) bfd_get_dynamic_symcount (abfd) = symcount; @@ -5562,8 +5683,7 @@ _bfd_elf_canonicalize_dynamic_symtab (abfd, alocation) considered to be a dynamic reloc section. */ long -_bfd_elf_get_dynamic_reloc_upper_bound (abfd) - bfd *abfd; +_bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) { long ret; asection *s; @@ -5595,12 +5715,11 @@ _bfd_elf_get_dynamic_reloc_upper_bound (abfd) section. */ long -_bfd_elf_canonicalize_dynamic_reloc (abfd, storage, syms) - bfd *abfd; - arelent **storage; - asymbol **syms; +_bfd_elf_canonicalize_dynamic_reloc (bfd *abfd, + arelent **storage, + asymbol **syms) { - boolean (*slurp_relocs) PARAMS ((bfd *, asection *, asymbol **, boolean)); + bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean); asection *s; long ret; @@ -5621,7 +5740,7 @@ _bfd_elf_canonicalize_dynamic_reloc (abfd, storage, syms) arelent *p; long count, i; - if (! (*slurp_relocs) (abfd, s, syms, true)) + if (! (*slurp_relocs) (abfd, s, syms, TRUE)) return -1; count = s->_raw_size / elf_section_data (s)->this_hdr.sh_entsize; p = s->relocation; @@ -5638,9 +5757,8 @@ _bfd_elf_canonicalize_dynamic_reloc (abfd, storage, syms) /* Read in the version information. */ -boolean -_bfd_elf_slurp_version_tables (abfd) - bfd *abfd; +bfd_boolean +_bfd_elf_slurp_version_tables (bfd *abfd) { bfd_byte *contents = NULL; bfd_size_type amt; @@ -5657,11 +5775,11 @@ _bfd_elf_slurp_version_tables (abfd) hdr = &elf_tdata (abfd)->dynverdef_hdr; - contents = (bfd_byte *) bfd_malloc (hdr->sh_size); + contents = bfd_malloc (hdr->sh_size); if (contents == NULL) goto error_return; if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread ((PTR) contents, hdr->sh_size, abfd) != hdr->sh_size) + || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) goto error_return; /* We know the number of entries in the section but not the maximum @@ -5681,7 +5799,7 @@ _bfd_elf_slurp_version_tables (abfd) } amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef); - elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt); + elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt); if (elf_tdata (abfd)->verdef == NULL) goto error_return; @@ -5703,7 +5821,7 @@ _bfd_elf_slurp_version_tables (abfd) iverdef->vd_bfd = abfd; amt = (bfd_size_type) iverdef->vd_cnt * sizeof (Elf_Internal_Verdaux); - iverdef->vd_auxptr = (Elf_Internal_Verdaux *) bfd_alloc (abfd, amt); + iverdef->vd_auxptr = bfd_alloc (abfd, amt); if (iverdef->vd_auxptr == NULL) goto error_return; @@ -5754,18 +5872,17 @@ _bfd_elf_slurp_version_tables (abfd) hdr = &elf_tdata (abfd)->dynverref_hdr; amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed); - elf_tdata (abfd)->verref = - (Elf_Internal_Verneed *) bfd_zalloc (abfd, amt); + elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt); if (elf_tdata (abfd)->verref == NULL) goto error_return; elf_tdata (abfd)->cverrefs = hdr->sh_info; - contents = (bfd_byte *) bfd_malloc (hdr->sh_size); + contents = bfd_malloc (hdr->sh_size); if (contents == NULL) goto error_return; if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread ((PTR) contents, hdr->sh_size, abfd) != hdr->sh_size) + || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) goto error_return; everneed = (Elf_External_Verneed *) contents; @@ -5788,7 +5905,7 @@ _bfd_elf_slurp_version_tables (abfd) amt = iverneed->vn_cnt; amt *= sizeof (Elf_Internal_Vernaux); - iverneed->vn_auxptr = (Elf_Internal_Vernaux *) bfd_alloc (abfd, amt); + iverneed->vn_auxptr = bfd_alloc (abfd, amt); evernaux = ((Elf_External_Vernaux *) ((bfd_byte *) everneed + iverneed->vn_aux)); @@ -5825,22 +5942,21 @@ _bfd_elf_slurp_version_tables (abfd) contents = NULL; } - return true; + return TRUE; error_return: - if (contents == NULL) + if (contents != NULL) free (contents); - return false; + return FALSE; } asymbol * -_bfd_elf_make_empty_symbol (abfd) - bfd *abfd; +_bfd_elf_make_empty_symbol (bfd *abfd) { elf_symbol_type *newsym; bfd_size_type amt = sizeof (elf_symbol_type); - newsym = (elf_symbol_type *) bfd_zalloc (abfd, amt); + newsym = bfd_zalloc (abfd, amt); if (!newsym) return NULL; else @@ -5851,10 +5967,9 @@ _bfd_elf_make_empty_symbol (abfd) } void -_bfd_elf_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd ATTRIBUTE_UNUSED; - asymbol *symbol; - symbol_info *ret; +_bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, + asymbol *symbol, + symbol_info *ret) { bfd_symbol_info (symbol, ret); } @@ -5863,19 +5978,18 @@ _bfd_elf_get_symbol_info (ignore_abfd, symbol, ret) use this function for the is_local_label_name entry point, but some override it. */ -boolean -_bfd_elf_is_local_label_name (abfd, name) - bfd *abfd ATTRIBUTE_UNUSED; - const char *name; +bfd_boolean +_bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, + const char *name) { /* Normal local symbols start with ``.L''. */ if (name[0] == '.' && name[1] == 'L') - return true; + return TRUE; /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate DWARF debugging symbols starting with ``..''. */ if (name[0] == '.' && name[1] == '.') - return true; + return TRUE; /* gcc will sometimes generate symbols beginning with ``_.L_'' when emitting DWARF debugging output. I suspect this is actually a @@ -5884,32 +5998,30 @@ _bfd_elf_is_local_label_name (abfd, name) underscore to be emitted on some ELF targets). For ease of use, we treat such symbols as local. */ if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_') - return true; + return TRUE; - return false; + return FALSE; } alent * -_bfd_elf_get_lineno (ignore_abfd, symbol) - bfd *ignore_abfd ATTRIBUTE_UNUSED; - asymbol *symbol ATTRIBUTE_UNUSED; +_bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED, + asymbol *symbol ATTRIBUTE_UNUSED) { abort (); return NULL; } -boolean -_bfd_elf_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; +bfd_boolean +_bfd_elf_set_arch_mach (bfd *abfd, + enum bfd_architecture arch, + unsigned long machine) { /* If this isn't the right architecture for this backend, and this isn't the generic backend, fail. */ if (arch != get_elf_backend_data (abfd)->arch && arch != bfd_arch_unknown && get_elf_backend_data (abfd)->arch != bfd_arch_unknown) - return false; + return FALSE; return bfd_default_set_arch_mach (abfd, arch, machine); } @@ -5917,15 +6029,13 @@ _bfd_elf_set_arch_mach (abfd, arch, machine) /* Find the function to a particular section and offset, for error reporting. */ -static boolean -elf_find_function (abfd, section, symbols, offset, - filename_ptr, functionname_ptr) - bfd *abfd ATTRIBUTE_UNUSED; - asection *section; - asymbol **symbols; - bfd_vma offset; - const char **filename_ptr; - const char **functionname_ptr; +static bfd_boolean +elf_find_function (bfd *abfd ATTRIBUTE_UNUSED, + asection *section, + asymbol **symbols, + bfd_vma offset, + const char **filename_ptr, + const char **functionname_ptr) { const char *filename; asymbol *func; @@ -5966,31 +6076,29 @@ elf_find_function (abfd, section, symbols, offset, } if (func == NULL) - return false; + return FALSE; if (filename_ptr) *filename_ptr = filename; if (functionname_ptr) *functionname_ptr = bfd_asymbol_name (func); - return true; + return TRUE; } /* Find the nearest line to a particular section and offset, for error reporting. */ -boolean -_bfd_elf_find_nearest_line (abfd, section, symbols, offset, - filename_ptr, functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - const char **filename_ptr; - const char **functionname_ptr; - unsigned int *line_ptr; +bfd_boolean +_bfd_elf_find_nearest_line (bfd *abfd, + asection *section, + asymbol **symbols, + bfd_vma offset, + const char **filename_ptr, + const char **functionname_ptr, + unsigned int *line_ptr) { - boolean found; + bfd_boolean found; if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, filename_ptr, functionname_ptr, @@ -6001,7 +6109,7 @@ _bfd_elf_find_nearest_line (abfd, section, symbols, offset, *filename_ptr ? NULL : filename_ptr, functionname_ptr); - return true; + return TRUE; } if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, @@ -6014,32 +6122,30 @@ _bfd_elf_find_nearest_line (abfd, section, symbols, offset, *filename_ptr ? NULL : filename_ptr, functionname_ptr); - return true; + return TRUE; } if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, &found, filename_ptr, functionname_ptr, line_ptr, &elf_tdata (abfd)->line_info)) - return false; + return FALSE; if (found && (*functionname_ptr || *line_ptr)) - return true; + return TRUE; if (symbols == NULL) - return false; + return FALSE; if (! elf_find_function (abfd, section, symbols, offset, filename_ptr, functionname_ptr)) - return false; + return FALSE; *line_ptr = 0; - return true; + return TRUE; } int -_bfd_elf_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; +_bfd_elf_sizeof_headers (bfd *abfd, bfd_boolean reloc) { int ret; @@ -6049,57 +6155,41 @@ _bfd_elf_sizeof_headers (abfd, reloc) return ret; } -boolean -_bfd_elf_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; +bfd_boolean +_bfd_elf_set_section_contents (bfd *abfd, + sec_ptr section, + const void *location, + file_ptr offset, + bfd_size_type count) { Elf_Internal_Shdr *hdr; bfd_signed_vma pos; if (! abfd->output_has_begun - && ! (_bfd_elf_compute_section_file_positions - (abfd, (struct bfd_link_info *) NULL))) - return false; + && ! _bfd_elf_compute_section_file_positions (abfd, NULL)) + return FALSE; hdr = &elf_section_data (section)->this_hdr; pos = hdr->sh_offset + offset; if (bfd_seek (abfd, pos, SEEK_SET) != 0 || bfd_bwrite (location, count, abfd) != count) - return false; + return FALSE; - return true; -} - -void -_bfd_elf_no_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr ATTRIBUTE_UNUSED; - Elf_Internal_Rela *dst ATTRIBUTE_UNUSED; -{ - abort (); + return TRUE; } -#if 0 void -_bfd_elf_no_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rel *dst; +_bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr ATTRIBUTE_UNUSED, + Elf_Internal_Rela *dst ATTRIBUTE_UNUSED) { abort (); } -#endif /* Try to convert a non-ELF reloc into an ELF one. */ -boolean -_bfd_elf_validate_reloc (abfd, areloc) - bfd *abfd; - arelent *areloc; +bfd_boolean +_bfd_elf_validate_reloc (bfd *abfd, arelent *areloc) { /* Check whether we really have an ELF howto. */ @@ -6182,19 +6272,18 @@ _bfd_elf_validate_reloc (abfd, areloc) goto fail; } - return true; + return TRUE; fail: (*_bfd_error_handler) (_("%s: unsupported relocation type %s"), bfd_archive_filename (abfd), areloc->howto->name); bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } -boolean -_bfd_elf_close_and_cleanup (abfd) - bfd *abfd; +bfd_boolean +_bfd_elf_close_and_cleanup (bfd *abfd) { if (bfd_get_format (abfd) == bfd_object) { @@ -6211,14 +6300,11 @@ _bfd_elf_close_and_cleanup (abfd) this reloc. */ bfd_reloc_status_type -_bfd_elf_rel_vtable_reloc_fn (abfd, re, symbol, data, is, obfd, errmsg) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *re ATTRIBUTE_UNUSED; - struct symbol_cache_entry *symbol ATTRIBUTE_UNUSED; - PTR data ATTRIBUTE_UNUSED; - asection *is ATTRIBUTE_UNUSED; - bfd *obfd ATTRIBUTE_UNUSED; - char **errmsg ATTRIBUTE_UNUSED; +_bfd_elf_rel_vtable_reloc_fn + (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED, + struct bfd_symbol *symbol ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED, + bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED) { return bfd_reloc_ok; } @@ -6235,8 +6321,7 @@ _bfd_elf_rel_vtable_reloc_fn (abfd, re, symbol, data, is, obfd, errmsg) /* FIXME: this is kinda wrong, but it's what gdb wants. */ static int -elfcore_make_pid (abfd) - bfd *abfd; +elfcore_make_pid (bfd *abfd) { return ((elf_tdata (abfd)->core_lwpid << 16) + (elf_tdata (abfd)->core_pid)); @@ -6247,26 +6332,23 @@ elfcore_make_pid (abfd) reference to NAME, so you shouldn't deallocate or overwrite it. */ -static boolean -elfcore_maybe_make_sect (abfd, name, sect) - bfd *abfd; - char *name; - asection *sect; +static bfd_boolean +elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect) { asection *sect2; if (bfd_get_section_by_name (abfd, name) != NULL) - return true; + return TRUE; sect2 = bfd_make_section (abfd, name); if (sect2 == NULL) - return false; + return FALSE; sect2->_raw_size = sect->_raw_size; sect2->filepos = sect->filepos; sect2->flags = sect->flags; sect2->alignment_power = sect->alignment_power; - return true; + return TRUE; } /* Create a pseudosection containing SIZE bytes at FILEPOS. This @@ -6276,12 +6358,11 @@ elfcore_maybe_make_sect (abfd, name, sect) - For the multi-threaded case, a section named "NAME/PID", where PID is elfcore_make_pid (abfd). Both pseudosections have identical contents. */ -boolean -_bfd_elfcore_make_pseudosection (abfd, name, size, filepos) - bfd *abfd; - char *name; - size_t size; - ufile_ptr filepos; +bfd_boolean +_bfd_elfcore_make_pseudosection (bfd *abfd, + char *name, + size_t size, + ufile_ptr filepos) { char buf[100]; char *threaded_name; @@ -6292,14 +6373,14 @@ _bfd_elfcore_make_pseudosection (abfd, name, size, filepos) sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd)); len = strlen (buf) + 1; - threaded_name = bfd_alloc (abfd, (bfd_size_type) len); + threaded_name = bfd_alloc (abfd, len); if (threaded_name == NULL) - return false; + return FALSE; memcpy (threaded_name, buf, len); - sect = bfd_make_section (abfd, threaded_name); + sect = bfd_make_section_anyway (abfd, threaded_name); if (sect == NULL) - return false; + return FALSE; sect->_raw_size = size; sect->filepos = filepos; sect->flags = SEC_HAS_CONTENTS; @@ -6315,12 +6396,9 @@ _bfd_elfcore_make_pseudosection (abfd, name, size, filepos) */ #if defined (HAVE_PRSTATUS_T) -static boolean elfcore_grok_prstatus PARAMS ((bfd *, Elf_Internal_Note *)); -static boolean -elfcore_grok_prstatus (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) { size_t raw_size; int offset; @@ -6380,7 +6458,7 @@ elfcore_grok_prstatus (abfd, note) { /* Fail - we don't know how to handle any other note size (ie. data object type). */ - return true; + return TRUE; } /* Make a ".reg/999" section and a ".reg" section. */ @@ -6390,11 +6468,10 @@ elfcore_grok_prstatus (abfd, note) #endif /* defined (HAVE_PRSTATUS_T) */ /* Create a pseudosection containing the exact contents of NOTE. */ -static boolean -elfcore_make_note_pseudosection (abfd, name, note) - bfd *abfd; - char *name; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_make_note_pseudosection (bfd *abfd, + char *name, + Elf_Internal_Note *note) { return _bfd_elfcore_make_pseudosection (abfd, name, note->descsz, note->descpos); @@ -6404,10 +6481,8 @@ elfcore_make_note_pseudosection (abfd, name, note) but it doesn't matter, because we don't have to pick this data structure apart. */ -static boolean -elfcore_grok_prfpreg (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note) { return elfcore_make_note_pseudosection (abfd, ".reg2", note); } @@ -6416,10 +6491,8 @@ elfcore_grok_prfpreg (abfd, note) type of 5 (NT_PRXFPREG). Just include the whole note's contents literally. */ -static boolean -elfcore_grok_prxfpreg (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note) { return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note); } @@ -6443,10 +6516,7 @@ typedef psinfo32_t elfcore_psinfo32_t; the copy will always have a terminating '\0'. */ char * -_bfd_elfcore_strndup (abfd, start, max) - bfd *abfd; - char *start; - size_t max; +_bfd_elfcore_strndup (bfd *abfd, char *start, size_t max) { char *dups; char *end = memchr (start, '\0', max); @@ -6457,7 +6527,7 @@ _bfd_elfcore_strndup (abfd, start, max) else len = end - start; - dups = bfd_alloc (abfd, (bfd_size_type) len + 1); + dups = bfd_alloc (abfd, len + 1); if (dups == NULL) return NULL; @@ -6468,12 +6538,8 @@ _bfd_elfcore_strndup (abfd, start, max) } #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) -static boolean elfcore_grok_psinfo PARAMS ((bfd *, Elf_Internal_Note *)); - -static boolean -elfcore_grok_psinfo (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) { if (note->descsz == sizeof (elfcore_psinfo_t)) { @@ -6511,7 +6577,7 @@ elfcore_grok_psinfo (abfd, note) { /* Fail - we don't know how to handle any other note size (ie. data object type). */ - return true; + return TRUE; } /* Note that for some reason, a spurious space is tacked @@ -6526,17 +6592,13 @@ elfcore_grok_psinfo (abfd, note) command[n - 1] = '\0'; } - return true; + return TRUE; } #endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */ #if defined (HAVE_PSTATUS_T) -static boolean elfcore_grok_pstatus PARAMS ((bfd *, Elf_Internal_Note *)); - -static boolean -elfcore_grok_pstatus (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note) { if (note->descsz == sizeof (pstatus_t) #if defined (HAVE_PXSTATUS_T) @@ -6565,17 +6627,13 @@ elfcore_grok_pstatus (abfd, note) lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an NT_LWPSTATUS note, presumably. */ - return true; + return TRUE; } #endif /* defined (HAVE_PSTATUS_T) */ #if defined (HAVE_LWPSTATUS_T) -static boolean elfcore_grok_lwpstatus PARAMS ((bfd *, Elf_Internal_Note *)); - -static boolean -elfcore_grok_lwpstatus (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note) { lwpstatus_t lwpstat; char buf[100]; @@ -6588,7 +6646,7 @@ elfcore_grok_lwpstatus (abfd, note) && note->descsz != sizeof (lwpxstatus_t) #endif ) - return true; + return TRUE; memcpy (&lwpstat, note->descdata, sizeof (lwpstat)); @@ -6599,14 +6657,14 @@ elfcore_grok_lwpstatus (abfd, note) sprintf (buf, ".reg/%d", elfcore_make_pid (abfd)); len = strlen (buf) + 1; - name = bfd_alloc (abfd, (bfd_size_type) len); + name = bfd_alloc (abfd, len); if (name == NULL) - return false; + return FALSE; memcpy (name, buf, len); - sect = bfd_make_section (abfd, name); + sect = bfd_make_section_anyway (abfd, name); if (sect == NULL) - return false; + return FALSE; #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT) sect->_raw_size = sizeof (lwpstat.pr_context.uc_mcontext.gregs); @@ -6623,20 +6681,20 @@ elfcore_grok_lwpstatus (abfd, note) sect->alignment_power = 2; if (!elfcore_maybe_make_sect (abfd, ".reg", sect)) - return false; + return FALSE; /* Make a ".reg2/999" section */ sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd)); len = strlen (buf) + 1; - name = bfd_alloc (abfd, (bfd_size_type) len); + name = bfd_alloc (abfd, len); if (name == NULL) - return false; + return FALSE; memcpy (name, buf, len); - sect = bfd_make_section (abfd, name); + sect = bfd_make_section_anyway (abfd, name); if (sect == NULL) - return false; + return FALSE; #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT) sect->_raw_size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs); @@ -6657,10 +6715,8 @@ elfcore_grok_lwpstatus (abfd, note) #endif /* defined (HAVE_LWPSTATUS_T) */ #if defined (HAVE_WIN32_PSTATUS_T) -static boolean -elfcore_grok_win32pstatus (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note) { char buf[30]; char *name; @@ -6669,7 +6725,7 @@ elfcore_grok_win32pstatus (abfd, note) win32_pstatus_t pstatus; if (note->descsz < sizeof (pstatus)) - return true; + return TRUE; memcpy (&pstatus, note->descdata, sizeof (pstatus)); @@ -6686,15 +6742,15 @@ elfcore_grok_win32pstatus (abfd, note) sprintf (buf, ".reg/%d", pstatus.data.thread_info.tid); len = strlen (buf) + 1; - name = bfd_alloc (abfd, (bfd_size_type) len); + name = bfd_alloc (abfd, len); if (name == NULL) - return false; + return FALSE; memcpy (name, buf, len); - sect = bfd_make_section (abfd, name); + sect = bfd_make_section_anyway (abfd, name); if (sect == NULL) - return false; + return FALSE; sect->_raw_size = sizeof (pstatus.data.thread_info.thread_context); sect->filepos = (note->descpos @@ -6705,7 +6761,7 @@ elfcore_grok_win32pstatus (abfd, note) if (pstatus.data.thread_info.is_active_thread) if (! elfcore_maybe_make_sect (abfd, ".reg", sect)) - return false; + return FALSE; break; case NOTE_INFO_MODULE: @@ -6713,16 +6769,16 @@ elfcore_grok_win32pstatus (abfd, note) sprintf (buf, ".module/%08x", pstatus.data.module_info.base_address); len = strlen (buf) + 1; - name = bfd_alloc (abfd, (bfd_size_type) len); + name = bfd_alloc (abfd, len); if (name == NULL) - return false; + return FALSE; memcpy (name, buf, len); - sect = bfd_make_section (abfd, name); + sect = bfd_make_section_anyway (abfd, name); if (sect == NULL) - return false; + return FALSE; sect->_raw_size = note->descsz; sect->filepos = note->descpos; @@ -6731,33 +6787,31 @@ elfcore_grok_win32pstatus (abfd, note) break; default: - return true; + return TRUE; } - return true; + return TRUE; } #endif /* HAVE_WIN32_PSTATUS_T */ -static boolean -elfcore_grok_note (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) { - struct elf_backend_data *bed = get_elf_backend_data (abfd); + const struct elf_backend_data *bed = get_elf_backend_data (abfd); switch (note->type) { default: - return true; + return TRUE; case NT_PRSTATUS: if (bed->elf_backend_grok_prstatus) if ((*bed->elf_backend_grok_prstatus) (abfd, note)) - return true; + return TRUE; #if defined (HAVE_PRSTATUS_T) return elfcore_grok_prstatus (abfd, note); #else - return true; + return TRUE; #endif #if defined (HAVE_PSTATUS_T) @@ -6779,29 +6833,41 @@ elfcore_grok_note (abfd, note) #endif case NT_PRXFPREG: /* Linux SSE extension */ - if (note->namesz == 5 - && ! strcmp (note->namedata, "LINUX")) + if (note->namesz == 6 + && strcmp (note->namedata, "LINUX") == 0) return elfcore_grok_prxfpreg (abfd, note); else - return true; + return TRUE; case NT_PRPSINFO: case NT_PSINFO: if (bed->elf_backend_grok_psinfo) if ((*bed->elf_backend_grok_psinfo) (abfd, note)) - return true; + return TRUE; #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) return elfcore_grok_psinfo (abfd, note); #else - return true; + return TRUE; #endif + + case NT_AUXV: + { + asection *sect = bfd_make_section_anyway (abfd, ".auxv"); + + if (sect == NULL) + return FALSE; + sect->_raw_size = note->descsz; + sect->filepos = note->descpos; + sect->flags = SEC_HAS_CONTENTS; + sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32; + + return TRUE; + } } } -static boolean -elfcore_netbsd_get_lwpid (note, lwpidp) - Elf_Internal_Note *note; - int *lwpidp; +static bfd_boolean +elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp) { char *cp; @@ -6809,15 +6875,13 @@ elfcore_netbsd_get_lwpid (note, lwpidp) if (cp != NULL) { *lwpidp = atoi(cp + 1); - return true; + return TRUE; } - return false; + return FALSE; } -static boolean -elfcore_grok_netbsd_procinfo (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note) { /* Signal number at offset 0x08. */ @@ -6832,13 +6896,12 @@ elfcore_grok_netbsd_procinfo (abfd, note) elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31); - return true; + return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo", + note); } -static boolean -elfcore_grok_netbsd_note (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +static bfd_boolean +elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note) { int lwp; @@ -6861,7 +6924,7 @@ elfcore_grok_netbsd_note (abfd, note) understand it. */ if (note->type < NT_NETBSDCORE_FIRSTMACH) - return true; + return TRUE; switch (bfd_get_arch (abfd)) @@ -6880,7 +6943,7 @@ elfcore_grok_netbsd_note (abfd, note) return elfcore_make_note_pseudosection (abfd, ".reg2", note); default: - return true; + return TRUE; } /* On all other arch's, PT_GETREGS == mach+1 and @@ -6896,12 +6959,118 @@ elfcore_grok_netbsd_note (abfd, note) return elfcore_make_note_pseudosection (abfd, ".reg2", note); default: - return true; + return TRUE; } } /* NOTREACHED */ } +static bfd_boolean +elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, pid_t *tid) +{ + void *ddata = note->descdata; + char buf[100]; + char *name; + asection *sect; + short sig; + unsigned flags; + + /* nto_procfs_status 'pid' field is at offset 0. */ + elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata); + + /* nto_procfs_status 'tid' field is at offset 4. Pass it back. */ + *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4); + + /* nto_procfs_status 'flags' field is at offset 8. */ + flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8); + + /* nto_procfs_status 'what' field is at offset 14. */ + if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0) + { + elf_tdata (abfd)->core_signal = sig; + elf_tdata (abfd)->core_lwpid = *tid; + } + + /* _DEBUG_FLAG_CURTID (current thread) is 0x80. Some cores + do not come from signals so we make sure we set the current + thread just in case. */ + if (flags & 0x00000080) + elf_tdata (abfd)->core_lwpid = *tid; + + /* Make a ".qnx_core_status/%d" section. */ + sprintf (buf, ".qnx_core_status/%d", *tid); + + name = bfd_alloc (abfd, strlen (buf) + 1); + if (name == NULL) + return FALSE; + strcpy (name, buf); + + sect = bfd_make_section_anyway (abfd, name); + if (sect == NULL) + return FALSE; + + sect->_raw_size = note->descsz; + sect->filepos = note->descpos; + sect->flags = SEC_HAS_CONTENTS; + sect->alignment_power = 2; + + return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect)); +} + +static bfd_boolean +elfcore_grok_nto_gregs (bfd *abfd, Elf_Internal_Note *note, pid_t tid) +{ + char buf[100]; + char *name; + asection *sect; + + /* Make a ".reg/%d" section. */ + sprintf (buf, ".reg/%d", tid); + + name = bfd_alloc (abfd, strlen (buf) + 1); + if (name == NULL) + return FALSE; + strcpy (name, buf); + + sect = bfd_make_section_anyway (abfd, name); + if (sect == NULL) + return FALSE; + + sect->_raw_size = note->descsz; + sect->filepos = note->descpos; + sect->flags = SEC_HAS_CONTENTS; + sect->alignment_power = 2; + + /* This is the current thread. */ + if (elf_tdata (abfd)->core_lwpid == tid) + return elfcore_maybe_make_sect (abfd, ".reg", sect); + + return TRUE; +} + +#define BFD_QNT_CORE_INFO 7 +#define BFD_QNT_CORE_STATUS 8 +#define BFD_QNT_CORE_GREG 9 +#define BFD_QNT_CORE_FPREG 10 + +static bfd_boolean +elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note) +{ + /* Every GREG section has a STATUS section before it. Store the + tid from the previous call to pass down to the next gregs + function. */ + static pid_t tid = 1; + + switch (note->type) + { + case BFD_QNT_CORE_INFO: return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note); + case BFD_QNT_CORE_STATUS: return elfcore_grok_nto_status (abfd, note, &tid); + case BFD_QNT_CORE_GREG: return elfcore_grok_nto_gregs (abfd, note, tid); + case BFD_QNT_CORE_FPREG: return elfcore_grok_prfpreg (abfd, note); + default: return TRUE; + } +} + /* Function: elfcore_write_note Inputs: @@ -6915,14 +7084,13 @@ elfcore_grok_netbsd_note (abfd, note) End of buffer containing note. */ char * -elfcore_write_note (abfd, buf, bufsiz, name, type, input, size) - bfd *abfd; - char *buf; - int *bufsiz; - const char *name; - int type; - const PTR input; - int size; +elfcore_write_note (bfd *abfd, + char *buf, + int *bufsiz, + const char *name, + int type, + const void *input, + int size) { Elf_External_Note *xnp; size_t namesz; @@ -6934,14 +7102,14 @@ elfcore_write_note (abfd, buf, bufsiz, name, type, input, size) pad = 0; if (name != NULL) { - struct elf_backend_data *bed; + const struct elf_backend_data *bed; namesz = strlen (name) + 1; bed = get_elf_backend_data (abfd); - pad = -namesz & (bed->s->file_align - 1); + pad = -namesz & ((1 << bed->s->log_file_align) - 1); } - newspace = sizeof (Elf_External_Note) - 1 + namesz + pad + size; + newspace = 12 + namesz + pad + size; p = realloc (buf, *bufsiz + newspace); dest = p + *bufsiz; @@ -6967,12 +7135,11 @@ elfcore_write_note (abfd, buf, bufsiz, name, type, input, size) #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) char * -elfcore_write_prpsinfo (abfd, buf, bufsiz, fname, psargs) - bfd *abfd; - char *buf; - int *bufsiz; - const char *fname; - const char *psargs; +elfcore_write_prpsinfo (bfd *abfd, + char *buf, + int *bufsiz, + const char *fname, + const char *psargs) { int note_type; char *note_name = "CORE"; @@ -6995,13 +7162,12 @@ elfcore_write_prpsinfo (abfd, buf, bufsiz, fname, psargs) #if defined (HAVE_PRSTATUS_T) char * -elfcore_write_prstatus (abfd, buf, bufsiz, pid, cursig, gregs) - bfd *abfd; - char *buf; - int *bufsiz; - long pid; - int cursig; - const PTR gregs; +elfcore_write_prstatus (bfd *abfd, + char *buf, + int *bufsiz, + long pid, + int cursig, + const void *gregs) { prstatus_t prstat; char *note_name = "CORE"; @@ -7017,13 +7183,12 @@ elfcore_write_prstatus (abfd, buf, bufsiz, pid, cursig, gregs) #if defined (HAVE_LWPSTATUS_T) char * -elfcore_write_lwpstatus (abfd, buf, bufsiz, pid, cursig, gregs) - bfd *abfd; - char *buf; - int *bufsiz; - long pid; - int cursig; - const PTR gregs; +elfcore_write_lwpstatus (bfd *abfd, + char *buf, + int *bufsiz, + long pid, + int cursig, + const void *gregs) { lwpstatus_t lwpstat; char *note_name = "CORE"; @@ -7049,13 +7214,12 @@ elfcore_write_lwpstatus (abfd, buf, bufsiz, pid, cursig, gregs) #if defined (HAVE_PSTATUS_T) char * -elfcore_write_pstatus (abfd, buf, bufsiz, pid, cursig, gregs) - bfd *abfd; - char *buf; - int *bufsiz; - long pid; - int cursig; - const PTR gregs; +elfcore_write_pstatus (bfd *abfd, + char *buf, + int *bufsiz, + long pid, + int cursig, + const void *gregs) { pstatus_t pstat; char *note_name = "CORE"; @@ -7069,12 +7233,11 @@ elfcore_write_pstatus (abfd, buf, bufsiz, pid, cursig, gregs) #endif /* HAVE_PSTATUS_T */ char * -elfcore_write_prfpreg (abfd, buf, bufsiz, fpregs, size) - bfd *abfd; - char *buf; - int *bufsiz; - const PTR fpregs; - int size; +elfcore_write_prfpreg (bfd *abfd, + char *buf, + int *bufsiz, + const void *fpregs, + int size) { char *note_name = "CORE"; return elfcore_write_note (abfd, buf, bufsiz, @@ -7082,42 +7245,38 @@ elfcore_write_prfpreg (abfd, buf, bufsiz, fpregs, size) } char * -elfcore_write_prxfpreg (abfd, buf, bufsiz, xfpregs, size) - bfd *abfd; - char *buf; - int *bufsiz; - const PTR xfpregs; - int size; +elfcore_write_prxfpreg (bfd *abfd, + char *buf, + int *bufsiz, + const void *xfpregs, + int size) { char *note_name = "LINUX"; return elfcore_write_note (abfd, buf, bufsiz, note_name, NT_PRXFPREG, xfpregs, size); } -static boolean -elfcore_read_notes (abfd, offset, size) - bfd *abfd; - file_ptr offset; - bfd_size_type size; +static bfd_boolean +elfcore_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size) { char *buf; char *p; if (size <= 0) - return true; + return TRUE; if (bfd_seek (abfd, offset, SEEK_SET) != 0) - return false; + return FALSE; buf = bfd_malloc (size); if (buf == NULL) - return false; + return FALSE; if (bfd_bread (buf, size, abfd) != size) { error: free (buf); - return false; + return FALSE; } p = buf; @@ -7141,6 +7300,11 @@ elfcore_read_notes (abfd, offset, size) if (! elfcore_grok_netbsd_note (abfd, &in)) goto error; } + else if (strncmp (in.namedata, "QNX", 3) == 0) + { + if (! elfcore_grok_nto_note (abfd, &in)) + goto error; + } else { if (! elfcore_grok_note (abfd, &in)) @@ -7151,7 +7315,7 @@ elfcore_read_notes (abfd, offset, size) } free (buf); - return true; + return TRUE; } /* Providing external access to the ELF program header table. */ @@ -7161,8 +7325,7 @@ elfcore_read_notes (abfd, offset, size) occurs; bfd_get_error will return an appropriate code. */ long -bfd_get_elf_phdr_upper_bound (abfd) - bfd *abfd; +bfd_get_elf_phdr_upper_bound (bfd *abfd) { if (abfd->xvec->flavour != bfd_target_elf_flavour) { @@ -7182,9 +7345,7 @@ bfd_get_elf_phdr_upper_bound (abfd) error occurs; bfd_get_error will return an appropriate code. */ int -bfd_get_elf_phdrs (abfd, phdrs) - bfd *abfd; - void *phdrs; +bfd_get_elf_phdrs (bfd *abfd, void *phdrs) { int num_phdrs; @@ -7202,10 +7363,7 @@ bfd_get_elf_phdrs (abfd, phdrs) } void -_bfd_elf_sprintf_vma (abfd, buf, value) - bfd *abfd ATTRIBUTE_UNUSED; - char *buf; - bfd_vma value; +_bfd_elf_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value) { #ifdef BFD64 Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ @@ -7233,10 +7391,7 @@ _bfd_elf_sprintf_vma (abfd, buf, value) } void -_bfd_elf_fprintf_vma (abfd, stream, value) - bfd *abfd ATTRIBUTE_UNUSED; - PTR stream; - bfd_vma value; +_bfd_elf_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value) { #ifdef BFD64 Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ @@ -7265,8 +7420,7 @@ _bfd_elf_fprintf_vma (abfd, stream, value) } enum elf_reloc_type_class -_bfd_elf_reloc_type_class (rela) - const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED; +_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED) { return reloc_class_normal; } @@ -7275,12 +7429,12 @@ _bfd_elf_reloc_type_class (rela) relocation against a local symbol. */ bfd_vma -_bfd_elf_rela_local_sym (abfd, sym, sec, rel) - bfd *abfd; - Elf_Internal_Sym *sym; - asection *sec; - Elf_Internal_Rela *rel; +_bfd_elf_rela_local_sym (bfd *abfd, + Elf_Internal_Sym *sym, + asection **psec, + Elf_Internal_Rela *rel) { + asection *sec = *psec; bfd_vma relocation; relocation = (sec->output_section->vma @@ -7288,58 +7442,78 @@ _bfd_elf_rela_local_sym (abfd, sym, sec, rel) + sym->st_value); if ((sec->flags & SEC_MERGE) && ELF_ST_TYPE (sym->st_info) == STT_SECTION - && elf_section_data (sec)->sec_info_type == ELF_INFO_TYPE_MERGE) + && sec->sec_info_type == ELF_INFO_TYPE_MERGE) { - asection *msec; - - msec = sec; rel->r_addend = - _bfd_merged_section_offset (abfd, &msec, + _bfd_merged_section_offset (abfd, psec, elf_section_data (sec)->sec_info, sym->st_value + rel->r_addend, - (bfd_vma) 0) - - relocation; - rel->r_addend += msec->output_section->vma + msec->output_offset; + 0); + sec = *psec; + rel->r_addend -= relocation; + rel->r_addend += sec->output_section->vma + sec->output_offset; } return relocation; } bfd_vma -_bfd_elf_rel_local_sym (abfd, sym, psec, addend) - bfd *abfd; - Elf_Internal_Sym *sym; - asection **psec; - bfd_vma addend; +_bfd_elf_rel_local_sym (bfd *abfd, + Elf_Internal_Sym *sym, + asection **psec, + bfd_vma addend) { asection *sec = *psec; - if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_MERGE) + if (sec->sec_info_type != ELF_INFO_TYPE_MERGE) return sym->st_value + addend; return _bfd_merged_section_offset (abfd, psec, elf_section_data (sec)->sec_info, - sym->st_value + addend, (bfd_vma) 0); + sym->st_value + addend, 0); } bfd_vma -_bfd_elf_section_offset (abfd, info, sec, offset) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - bfd_vma offset; +_bfd_elf_section_offset (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + bfd_vma offset) { struct bfd_elf_section_data *sec_data; sec_data = elf_section_data (sec); - switch (sec_data->sec_info_type) + switch (sec->sec_info_type) { case ELF_INFO_TYPE_STABS: - return _bfd_stab_section_offset - (abfd, &elf_hash_table (info)->merge_info, sec, &sec_data->sec_info, - offset); + return _bfd_stab_section_offset (abfd, + &elf_hash_table (info)->merge_info, + sec, &sec_data->sec_info, offset); case ELF_INFO_TYPE_EH_FRAME: return _bfd_elf_eh_frame_section_offset (abfd, sec, offset); default: return offset; } } + +/* 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 an ELF target with the word size and byte order found in + the remote memory. */ + +bfd * +bfd_elf_bfd_from_remote_memory + (bfd *templ, + bfd_vma ehdr_vma, + bfd_vma *loadbasep, + int (*target_read_memory) (bfd_vma, char *, int)) +{ + return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory) + (templ, ehdr_vma, loadbasep, target_read_memory); +} |