133965Sjdp/* ELF executable support for BFD. 233965Sjdp 3130563Sobrien Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 4218822Sdim 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 533965Sjdp 6130563Sobrien This file is part of BFD, the Binary File Descriptor library. 733965Sjdp 8130563Sobrien This program is free software; you can redistribute it and/or modify 9130563Sobrien it under the terms of the GNU General Public License as published by 10130563Sobrien the Free Software Foundation; either version 2 of the License, or 11130563Sobrien (at your option) any later version. 1233965Sjdp 13130563Sobrien This program is distributed in the hope that it will be useful, 14130563Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 15130563Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130563Sobrien GNU General Public License for more details. 1733965Sjdp 18130563Sobrien You should have received a copy of the GNU General Public License 19130563Sobrien along with this program; if not, write to the Free Software 20218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2191047Sobrien 22130563Sobrien 2359160Sobrien/* $FreeBSD$ */ 2459160Sobrien 2533965Sjdp 26218822Sdim/* 27218822SdimSECTION 2833965Sjdp ELF backends 2933965Sjdp 3033965Sjdp BFD support for ELF formats is being worked on. 3133965Sjdp Currently, the best supported back ends are for sparc and i386 3233965Sjdp (running svr4 or Solaris 2). 3333965Sjdp 3433965Sjdp Documentation of the internals of the support code still needs 3533965Sjdp to be written. The code is changing quickly enough that we 3691047Sobrien haven't bothered yet. */ 3733965Sjdp 3877301Sobrien/* For sparc64-cross-sparc32. */ 3977301Sobrien#define _SYSCALL32 40218822Sdim#include "sysdep.h" 4133965Sjdp#include "bfd.h" 4233965Sjdp#include "bfdlink.h" 4333965Sjdp#include "libbfd.h" 4433965Sjdp#define ARCH_SIZE 0 4533965Sjdp#include "elf-bfd.h" 4689860Sobrien#include "libiberty.h" 4733965Sjdp 48130563Sobrienstatic int elf_sort_sections (const void *, const void *); 49130563Sobrienstatic bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *); 50130563Sobrienstatic bfd_boolean prep_headers (bfd *); 51130563Sobrienstatic bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ; 52130563Sobrienstatic bfd_boolean elfcore_read_notes (bfd *, file_ptr, bfd_size_type) ; 5333965Sjdp 5433965Sjdp/* Swap version information in and out. The version information is 5533965Sjdp currently size independent. If that ever changes, this code will 5633965Sjdp need to move into elfcode.h. */ 5733965Sjdp 5833965Sjdp/* Swap in a Verdef structure. */ 5933965Sjdp 6033965Sjdpvoid 61130563Sobrien_bfd_elf_swap_verdef_in (bfd *abfd, 62130563Sobrien const Elf_External_Verdef *src, 63130563Sobrien Elf_Internal_Verdef *dst) 6433965Sjdp{ 6589860Sobrien dst->vd_version = H_GET_16 (abfd, src->vd_version); 6689860Sobrien dst->vd_flags = H_GET_16 (abfd, src->vd_flags); 6789860Sobrien dst->vd_ndx = H_GET_16 (abfd, src->vd_ndx); 6889860Sobrien dst->vd_cnt = H_GET_16 (abfd, src->vd_cnt); 6989860Sobrien dst->vd_hash = H_GET_32 (abfd, src->vd_hash); 7089860Sobrien dst->vd_aux = H_GET_32 (abfd, src->vd_aux); 7189860Sobrien dst->vd_next = H_GET_32 (abfd, src->vd_next); 7233965Sjdp} 7333965Sjdp 7433965Sjdp/* Swap out a Verdef structure. */ 7533965Sjdp 7633965Sjdpvoid 77130563Sobrien_bfd_elf_swap_verdef_out (bfd *abfd, 78130563Sobrien const Elf_Internal_Verdef *src, 79130563Sobrien Elf_External_Verdef *dst) 8033965Sjdp{ 8189860Sobrien H_PUT_16 (abfd, src->vd_version, dst->vd_version); 8289860Sobrien H_PUT_16 (abfd, src->vd_flags, dst->vd_flags); 8389860Sobrien H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx); 8489860Sobrien H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt); 8589860Sobrien H_PUT_32 (abfd, src->vd_hash, dst->vd_hash); 8689860Sobrien H_PUT_32 (abfd, src->vd_aux, dst->vd_aux); 8789860Sobrien H_PUT_32 (abfd, src->vd_next, dst->vd_next); 8833965Sjdp} 8933965Sjdp 9033965Sjdp/* Swap in a Verdaux structure. */ 9133965Sjdp 9233965Sjdpvoid 93130563Sobrien_bfd_elf_swap_verdaux_in (bfd *abfd, 94130563Sobrien const Elf_External_Verdaux *src, 95130563Sobrien Elf_Internal_Verdaux *dst) 9633965Sjdp{ 9789860Sobrien dst->vda_name = H_GET_32 (abfd, src->vda_name); 9889860Sobrien dst->vda_next = H_GET_32 (abfd, src->vda_next); 9933965Sjdp} 10033965Sjdp 10133965Sjdp/* Swap out a Verdaux structure. */ 10233965Sjdp 10333965Sjdpvoid 104130563Sobrien_bfd_elf_swap_verdaux_out (bfd *abfd, 105130563Sobrien const Elf_Internal_Verdaux *src, 106130563Sobrien Elf_External_Verdaux *dst) 10733965Sjdp{ 10889860Sobrien H_PUT_32 (abfd, src->vda_name, dst->vda_name); 10989860Sobrien H_PUT_32 (abfd, src->vda_next, dst->vda_next); 11033965Sjdp} 11133965Sjdp 11233965Sjdp/* Swap in a Verneed structure. */ 11333965Sjdp 11433965Sjdpvoid 115130563Sobrien_bfd_elf_swap_verneed_in (bfd *abfd, 116130563Sobrien const Elf_External_Verneed *src, 117130563Sobrien Elf_Internal_Verneed *dst) 11833965Sjdp{ 11989860Sobrien dst->vn_version = H_GET_16 (abfd, src->vn_version); 12089860Sobrien dst->vn_cnt = H_GET_16 (abfd, src->vn_cnt); 12189860Sobrien dst->vn_file = H_GET_32 (abfd, src->vn_file); 12289860Sobrien dst->vn_aux = H_GET_32 (abfd, src->vn_aux); 12389860Sobrien dst->vn_next = H_GET_32 (abfd, src->vn_next); 12433965Sjdp} 12533965Sjdp 12633965Sjdp/* Swap out a Verneed structure. */ 12733965Sjdp 12833965Sjdpvoid 129130563Sobrien_bfd_elf_swap_verneed_out (bfd *abfd, 130130563Sobrien const Elf_Internal_Verneed *src, 131130563Sobrien Elf_External_Verneed *dst) 13233965Sjdp{ 13389860Sobrien H_PUT_16 (abfd, src->vn_version, dst->vn_version); 13489860Sobrien H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt); 13589860Sobrien H_PUT_32 (abfd, src->vn_file, dst->vn_file); 13689860Sobrien H_PUT_32 (abfd, src->vn_aux, dst->vn_aux); 13789860Sobrien H_PUT_32 (abfd, src->vn_next, dst->vn_next); 13833965Sjdp} 13933965Sjdp 14033965Sjdp/* Swap in a Vernaux structure. */ 14133965Sjdp 14233965Sjdpvoid 143130563Sobrien_bfd_elf_swap_vernaux_in (bfd *abfd, 144130563Sobrien const Elf_External_Vernaux *src, 145130563Sobrien Elf_Internal_Vernaux *dst) 14633965Sjdp{ 14789860Sobrien dst->vna_hash = H_GET_32 (abfd, src->vna_hash); 14889860Sobrien dst->vna_flags = H_GET_16 (abfd, src->vna_flags); 14989860Sobrien dst->vna_other = H_GET_16 (abfd, src->vna_other); 15089860Sobrien dst->vna_name = H_GET_32 (abfd, src->vna_name); 15189860Sobrien dst->vna_next = H_GET_32 (abfd, src->vna_next); 15233965Sjdp} 15333965Sjdp 15433965Sjdp/* Swap out a Vernaux structure. */ 15533965Sjdp 15633965Sjdpvoid 157130563Sobrien_bfd_elf_swap_vernaux_out (bfd *abfd, 158130563Sobrien const Elf_Internal_Vernaux *src, 159130563Sobrien Elf_External_Vernaux *dst) 16033965Sjdp{ 16189860Sobrien H_PUT_32 (abfd, src->vna_hash, dst->vna_hash); 16289860Sobrien H_PUT_16 (abfd, src->vna_flags, dst->vna_flags); 16389860Sobrien H_PUT_16 (abfd, src->vna_other, dst->vna_other); 16489860Sobrien H_PUT_32 (abfd, src->vna_name, dst->vna_name); 16589860Sobrien H_PUT_32 (abfd, src->vna_next, dst->vna_next); 16633965Sjdp} 16733965Sjdp 16833965Sjdp/* Swap in a Versym structure. */ 16933965Sjdp 17033965Sjdpvoid 171130563Sobrien_bfd_elf_swap_versym_in (bfd *abfd, 172130563Sobrien const Elf_External_Versym *src, 173130563Sobrien Elf_Internal_Versym *dst) 17433965Sjdp{ 17589860Sobrien dst->vs_vers = H_GET_16 (abfd, src->vs_vers); 17633965Sjdp} 17733965Sjdp 17833965Sjdp/* Swap out a Versym structure. */ 17933965Sjdp 18033965Sjdpvoid 181130563Sobrien_bfd_elf_swap_versym_out (bfd *abfd, 182130563Sobrien const Elf_Internal_Versym *src, 183130563Sobrien Elf_External_Versym *dst) 18433965Sjdp{ 18589860Sobrien H_PUT_16 (abfd, src->vs_vers, dst->vs_vers); 18633965Sjdp} 18733965Sjdp 18833965Sjdp/* Standard ELF hash function. Do not change this function; you will 18960508Sobrien cause invalid hash tables to be generated. */ 19060508Sobrien 19133965Sjdpunsigned long 192130563Sobrienbfd_elf_hash (const char *namearg) 19333965Sjdp{ 19460508Sobrien const unsigned char *name = (const unsigned char *) namearg; 19533965Sjdp unsigned long h = 0; 19633965Sjdp unsigned long g; 19733965Sjdp int ch; 19833965Sjdp 19933965Sjdp while ((ch = *name++) != '\0') 20033965Sjdp { 20133965Sjdp h = (h << 4) + ch; 20233965Sjdp if ((g = (h & 0xf0000000)) != 0) 20333965Sjdp { 20433965Sjdp h ^= g >> 24; 20560508Sobrien /* The ELF ABI says `h &= ~g', but this is equivalent in 20660508Sobrien this case and on some machines one insn instead of two. */ 20760508Sobrien h ^= g; 20833965Sjdp } 20933965Sjdp } 210130563Sobrien return h & 0xffffffff; 21133965Sjdp} 21233965Sjdp 213218822Sdim/* DT_GNU_HASH hash function. Do not change this function; you will 214218822Sdim cause invalid hash tables to be generated. */ 21533965Sjdp 216218822Sdimunsigned long 217218822Sdimbfd_elf_gnu_hash (const char *namearg) 21833965Sjdp{ 219218822Sdim const unsigned char *name = (const unsigned char *) namearg; 220218822Sdim unsigned long h = 5381; 221218822Sdim unsigned char ch; 22233965Sjdp 223218822Sdim while ((ch = *name++) != '\0') 224218822Sdim h = (h << 5) + h + ch; 225218822Sdim return h & 0xffffffff; 22633965Sjdp} 22733965Sjdp 228130563Sobrienbfd_boolean 229130563Sobrienbfd_elf_mkobject (bfd *abfd) 23033965Sjdp{ 231218822Sdim if (abfd->tdata.any == NULL) 232218822Sdim { 233218822Sdim abfd->tdata.any = bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); 234218822Sdim if (abfd->tdata.any == NULL) 235218822Sdim return FALSE; 236218822Sdim } 23733965Sjdp 238218822Sdim elf_tdata (abfd)->program_header_size = (bfd_size_type) -1; 239218822Sdim 240130563Sobrien return TRUE; 24133965Sjdp} 24233965Sjdp 243130563Sobrienbfd_boolean 244130563Sobrienbfd_elf_mkcorefile (bfd *abfd) 24560508Sobrien{ 24677301Sobrien /* I think this can be done just like an object file. */ 24760508Sobrien return bfd_elf_mkobject (abfd); 24860508Sobrien} 24960508Sobrien 25033965Sjdpchar * 251130563Sobrienbfd_elf_get_str_section (bfd *abfd, unsigned int shindex) 25233965Sjdp{ 25333965Sjdp Elf_Internal_Shdr **i_shdrp; 254218822Sdim bfd_byte *shstrtab = NULL; 25589860Sobrien file_ptr offset; 25689860Sobrien bfd_size_type shstrtabsize; 25733965Sjdp 25833965Sjdp i_shdrp = elf_elfsections (abfd); 259218822Sdim if (i_shdrp == 0 260218822Sdim || shindex >= elf_numsections (abfd) 261218822Sdim || i_shdrp[shindex] == 0) 262218822Sdim return NULL; 26333965Sjdp 264218822Sdim shstrtab = i_shdrp[shindex]->contents; 26533965Sjdp if (shstrtab == NULL) 26633965Sjdp { 26777301Sobrien /* No cached one, attempt to read, and cache what we read. */ 26833965Sjdp offset = i_shdrp[shindex]->sh_offset; 26933965Sjdp shstrtabsize = i_shdrp[shindex]->sh_size; 270218822Sdim 271218822Sdim /* Allocate and clear an extra byte at the end, to prevent crashes 272218822Sdim in case the string table is not terminated. */ 273218822Sdim if (shstrtabsize + 1 == 0 274218822Sdim || (shstrtab = bfd_alloc (abfd, shstrtabsize + 1)) == NULL 275218822Sdim || bfd_seek (abfd, offset, SEEK_SET) != 0) 276218822Sdim shstrtab = NULL; 277218822Sdim else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize) 278218822Sdim { 279218822Sdim if (bfd_get_error () != bfd_error_system_call) 280218822Sdim bfd_set_error (bfd_error_file_truncated); 281218822Sdim shstrtab = NULL; 282218822Sdim } 283218822Sdim else 284218822Sdim shstrtab[shstrtabsize] = '\0'; 285130563Sobrien i_shdrp[shindex]->contents = shstrtab; 28633965Sjdp } 287218822Sdim return (char *) shstrtab; 28833965Sjdp} 28933965Sjdp 29033965Sjdpchar * 291130563Sobrienbfd_elf_string_from_elf_section (bfd *abfd, 292130563Sobrien unsigned int shindex, 293130563Sobrien unsigned int strindex) 29433965Sjdp{ 29533965Sjdp Elf_Internal_Shdr *hdr; 29633965Sjdp 29733965Sjdp if (strindex == 0) 29833965Sjdp return ""; 29933965Sjdp 300218822Sdim if (elf_elfsections (abfd) == NULL || shindex >= elf_numsections (abfd)) 301218822Sdim return NULL; 302218822Sdim 30333965Sjdp hdr = elf_elfsections (abfd)[shindex]; 30433965Sjdp 30533965Sjdp if (hdr->contents == NULL 30633965Sjdp && bfd_elf_get_str_section (abfd, shindex) == NULL) 30733965Sjdp return NULL; 30833965Sjdp 30938891Sjdp if (strindex >= hdr->sh_size) 31038891Sjdp { 311218822Sdim unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx; 31238891Sjdp (*_bfd_error_handler) 313218822Sdim (_("%B: invalid string offset %u >= %lu for section `%s'"), 314218822Sdim abfd, strindex, (unsigned long) hdr->sh_size, 315218822Sdim (shindex == shstrndx && strindex == hdr->sh_name 31638891Sjdp ? ".shstrtab" 317218822Sdim : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name))); 31838891Sjdp return ""; 31938891Sjdp } 32038891Sjdp 32133965Sjdp return ((char *) hdr->contents) + strindex; 32233965Sjdp} 32333965Sjdp 324104838Sobrien/* Read and convert symbols to internal format. 325104838Sobrien SYMCOUNT specifies the number of symbols to read, starting from 326104838Sobrien symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF 327104838Sobrien are non-NULL, they are used to store the internal symbols, external 328104838Sobrien symbols, and symbol section index extensions, respectively. */ 329104838Sobrien 330104838SobrienElf_Internal_Sym * 331130563Sobrienbfd_elf_get_elf_syms (bfd *ibfd, 332130563Sobrien Elf_Internal_Shdr *symtab_hdr, 333130563Sobrien size_t symcount, 334130563Sobrien size_t symoffset, 335130563Sobrien Elf_Internal_Sym *intsym_buf, 336130563Sobrien void *extsym_buf, 337130563Sobrien Elf_External_Sym_Shndx *extshndx_buf) 338104838Sobrien{ 339104838Sobrien Elf_Internal_Shdr *shndx_hdr; 340130563Sobrien void *alloc_ext; 341104838Sobrien const bfd_byte *esym; 342104838Sobrien Elf_External_Sym_Shndx *alloc_extshndx; 343104838Sobrien Elf_External_Sym_Shndx *shndx; 344104838Sobrien Elf_Internal_Sym *isym; 345104838Sobrien Elf_Internal_Sym *isymend; 346130563Sobrien const struct elf_backend_data *bed; 347104838Sobrien size_t extsym_size; 348104838Sobrien bfd_size_type amt; 349104838Sobrien file_ptr pos; 350104838Sobrien 351104838Sobrien if (symcount == 0) 352104838Sobrien return intsym_buf; 353104838Sobrien 354104838Sobrien /* Normal syms might have section extension entries. */ 355104838Sobrien shndx_hdr = NULL; 356104838Sobrien if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr) 357104838Sobrien shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr; 358104838Sobrien 359104838Sobrien /* Read the symbols. */ 360104838Sobrien alloc_ext = NULL; 361104838Sobrien alloc_extshndx = NULL; 362104838Sobrien bed = get_elf_backend_data (ibfd); 363104838Sobrien extsym_size = bed->s->sizeof_sym; 364104838Sobrien amt = symcount * extsym_size; 365104838Sobrien pos = symtab_hdr->sh_offset + symoffset * extsym_size; 366104838Sobrien if (extsym_buf == NULL) 367104838Sobrien { 368218822Sdim alloc_ext = bfd_malloc2 (symcount, extsym_size); 369104838Sobrien extsym_buf = alloc_ext; 370104838Sobrien } 371104838Sobrien if (extsym_buf == NULL 372104838Sobrien || bfd_seek (ibfd, pos, SEEK_SET) != 0 373104838Sobrien || bfd_bread (extsym_buf, amt, ibfd) != amt) 374104838Sobrien { 375104838Sobrien intsym_buf = NULL; 376104838Sobrien goto out; 377104838Sobrien } 378104838Sobrien 379104838Sobrien if (shndx_hdr == NULL || shndx_hdr->sh_size == 0) 380104838Sobrien extshndx_buf = NULL; 381104838Sobrien else 382104838Sobrien { 383104838Sobrien amt = symcount * sizeof (Elf_External_Sym_Shndx); 384104838Sobrien pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx); 385104838Sobrien if (extshndx_buf == NULL) 386104838Sobrien { 387218822Sdim alloc_extshndx = bfd_malloc2 (symcount, 388218822Sdim sizeof (Elf_External_Sym_Shndx)); 389104838Sobrien extshndx_buf = alloc_extshndx; 390104838Sobrien } 391104838Sobrien if (extshndx_buf == NULL 392104838Sobrien || bfd_seek (ibfd, pos, SEEK_SET) != 0 393104838Sobrien || bfd_bread (extshndx_buf, amt, ibfd) != amt) 394104838Sobrien { 395104838Sobrien intsym_buf = NULL; 396104838Sobrien goto out; 397104838Sobrien } 398104838Sobrien } 399104838Sobrien 400104838Sobrien if (intsym_buf == NULL) 401104838Sobrien { 402218822Sdim intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym)); 403104838Sobrien if (intsym_buf == NULL) 404104838Sobrien goto out; 405104838Sobrien } 406104838Sobrien 407104838Sobrien /* Convert the symbols to internal form. */ 408104838Sobrien isymend = intsym_buf + symcount; 409104838Sobrien for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf; 410104838Sobrien isym < isymend; 411104838Sobrien esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL) 412218822Sdim if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym)) 413218822Sdim { 414218822Sdim symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size; 415218822Sdim (*_bfd_error_handler) (_("%B symbol number %lu references " 416218822Sdim "nonexistent SHT_SYMTAB_SHNDX section"), 417218822Sdim ibfd, (unsigned long) symoffset); 418218822Sdim intsym_buf = NULL; 419218822Sdim goto out; 420218822Sdim } 421104838Sobrien 422104838Sobrien out: 423104838Sobrien if (alloc_ext != NULL) 424104838Sobrien free (alloc_ext); 425104838Sobrien if (alloc_extshndx != NULL) 426104838Sobrien free (alloc_extshndx); 427104838Sobrien 428104838Sobrien return intsym_buf; 429104838Sobrien} 430104838Sobrien 431130563Sobrien/* Look up a symbol name. */ 432130563Sobrienconst char * 433218822Sdimbfd_elf_sym_name (bfd *abfd, 434218822Sdim Elf_Internal_Shdr *symtab_hdr, 435218822Sdim Elf_Internal_Sym *isym, 436218822Sdim asection *sym_sec) 437130563Sobrien{ 438218822Sdim const char *name; 439130563Sobrien unsigned int iname = isym->st_name; 440218822Sdim unsigned int shindex = symtab_hdr->sh_link; 441218822Sdim 442218822Sdim if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION 443218822Sdim /* Check for a bogus st_shndx to avoid crashing. */ 444218822Sdim && isym->st_shndx < elf_numsections (abfd) 445218822Sdim && !(isym->st_shndx >= SHN_LORESERVE && isym->st_shndx <= SHN_HIRESERVE)) 446130563Sobrien { 447130563Sobrien iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name; 448130563Sobrien shindex = elf_elfheader (abfd)->e_shstrndx; 449130563Sobrien } 450130563Sobrien 451218822Sdim name = bfd_elf_string_from_elf_section (abfd, shindex, iname); 452218822Sdim if (name == NULL) 453218822Sdim name = "(null)"; 454218822Sdim else if (sym_sec && *name == '\0') 455218822Sdim name = bfd_section_name (abfd, sym_sec); 456218822Sdim 457218822Sdim return name; 458130563Sobrien} 459130563Sobrien 46089860Sobrien/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP 46189860Sobrien sections. The first element is the flags, the rest are section 46289860Sobrien pointers. */ 46389860Sobrien 46489860Sobrientypedef union elf_internal_group { 46589860Sobrien Elf_Internal_Shdr *shdr; 46689860Sobrien unsigned int flags; 46789860Sobrien} Elf_Internal_Group; 46889860Sobrien 469104838Sobrien/* Return the name of the group signature symbol. Why isn't the 470104838Sobrien signature just a string? */ 471104838Sobrien 472104838Sobrienstatic const char * 473130563Sobriengroup_signature (bfd *abfd, Elf_Internal_Shdr *ghdr) 474104838Sobrien{ 475104838Sobrien Elf_Internal_Shdr *hdr; 476104838Sobrien unsigned char esym[sizeof (Elf64_External_Sym)]; 477104838Sobrien Elf_External_Sym_Shndx eshndx; 478104838Sobrien Elf_Internal_Sym isym; 479104838Sobrien 480218822Sdim /* First we need to ensure the symbol table is available. Make sure 481218822Sdim that it is a symbol table section. */ 482218822Sdim hdr = elf_elfsections (abfd) [ghdr->sh_link]; 483218822Sdim if (hdr->sh_type != SHT_SYMTAB 484218822Sdim || ! bfd_section_from_shdr (abfd, ghdr->sh_link)) 485104838Sobrien return NULL; 486104838Sobrien 487104838Sobrien /* Go read the symbol. */ 488104838Sobrien hdr = &elf_tdata (abfd)->symtab_hdr; 489104838Sobrien if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info, 490104838Sobrien &isym, esym, &eshndx) == NULL) 491104838Sobrien return NULL; 492104838Sobrien 493218822Sdim return bfd_elf_sym_name (abfd, hdr, &isym, NULL); 494104838Sobrien} 495104838Sobrien 49689860Sobrien/* Set next_in_group list pointer, and group name for NEWSECT. */ 49789860Sobrien 498130563Sobrienstatic bfd_boolean 499130563Sobriensetup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) 50089860Sobrien{ 50189860Sobrien unsigned int num_group = elf_tdata (abfd)->num_group; 50289860Sobrien 50389860Sobrien /* If num_group is zero, read in all SHT_GROUP sections. The count 50489860Sobrien is set to -1 if there are no SHT_GROUP sections. */ 50589860Sobrien if (num_group == 0) 50689860Sobrien { 50789860Sobrien unsigned int i, shnum; 50889860Sobrien 50989860Sobrien /* First count the number of groups. If we have a SHT_GROUP 51089860Sobrien section with just a flag word (ie. sh_size is 4), ignore it. */ 51189860Sobrien shnum = elf_numsections (abfd); 51289860Sobrien num_group = 0; 513218822Sdim 514218822Sdim#define IS_VALID_GROUP_SECTION_HEADER(shdr) \ 515218822Sdim ( (shdr)->sh_type == SHT_GROUP \ 516218822Sdim && (shdr)->sh_size >= (2 * GRP_ENTRY_SIZE) \ 517218822Sdim && (shdr)->sh_entsize == GRP_ENTRY_SIZE \ 518218822Sdim && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0) 519218822Sdim 52089860Sobrien for (i = 0; i < shnum; i++) 52189860Sobrien { 52289860Sobrien Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i]; 523218822Sdim 524218822Sdim if (IS_VALID_GROUP_SECTION_HEADER (shdr)) 52589860Sobrien num_group += 1; 52689860Sobrien } 52789860Sobrien 52889860Sobrien if (num_group == 0) 52989860Sobrien { 530218822Sdim num_group = (unsigned) -1; 531218822Sdim elf_tdata (abfd)->num_group = num_group; 532218822Sdim } 533218822Sdim else 534218822Sdim { 53589860Sobrien /* We keep a list of elf section headers for group sections, 53689860Sobrien so we can find them quickly. */ 537218822Sdim bfd_size_type amt; 538218822Sdim 539218822Sdim elf_tdata (abfd)->num_group = num_group; 540218822Sdim elf_tdata (abfd)->group_sect_ptr 541218822Sdim = bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *)); 54289860Sobrien if (elf_tdata (abfd)->group_sect_ptr == NULL) 543130563Sobrien return FALSE; 54489860Sobrien 54589860Sobrien num_group = 0; 54689860Sobrien for (i = 0; i < shnum; i++) 54789860Sobrien { 54889860Sobrien Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i]; 549218822Sdim 550218822Sdim if (IS_VALID_GROUP_SECTION_HEADER (shdr)) 55189860Sobrien { 55289860Sobrien unsigned char *src; 55389860Sobrien Elf_Internal_Group *dest; 55489860Sobrien 55589860Sobrien /* Add to list of sections. */ 55689860Sobrien elf_tdata (abfd)->group_sect_ptr[num_group] = shdr; 55789860Sobrien num_group += 1; 55889860Sobrien 55989860Sobrien /* Read the raw contents. */ 56089860Sobrien BFD_ASSERT (sizeof (*dest) >= 4); 56189860Sobrien amt = shdr->sh_size * sizeof (*dest) / 4; 562218822Sdim shdr->contents = bfd_alloc2 (abfd, shdr->sh_size, 563218822Sdim sizeof (*dest) / 4); 564218822Sdim /* PR binutils/4110: Handle corrupt group headers. */ 565218822Sdim if (shdr->contents == NULL) 566218822Sdim { 567218822Sdim _bfd_error_handler 568218822Sdim (_("%B: Corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size); 569218822Sdim bfd_set_error (bfd_error_bad_value); 570218822Sdim return FALSE; 571218822Sdim } 572218822Sdim 573218822Sdim memset (shdr->contents, 0, amt); 574218822Sdim 575218822Sdim if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0 57689860Sobrien || (bfd_bread (shdr->contents, shdr->sh_size, abfd) 57789860Sobrien != shdr->sh_size)) 578130563Sobrien return FALSE; 57989860Sobrien 58089860Sobrien /* Translate raw contents, a flag word followed by an 58189860Sobrien array of elf section indices all in target byte order, 58289860Sobrien to the flag word followed by an array of elf section 58389860Sobrien pointers. */ 58489860Sobrien src = shdr->contents + shdr->sh_size; 58589860Sobrien dest = (Elf_Internal_Group *) (shdr->contents + amt); 58689860Sobrien while (1) 58789860Sobrien { 58889860Sobrien unsigned int idx; 58989860Sobrien 59089860Sobrien src -= 4; 59189860Sobrien --dest; 59289860Sobrien idx = H_GET_32 (abfd, src); 59389860Sobrien if (src == shdr->contents) 59489860Sobrien { 59589860Sobrien dest->flags = idx; 596104838Sobrien if (shdr->bfd_section != NULL && (idx & GRP_COMDAT)) 597104838Sobrien shdr->bfd_section->flags 598104838Sobrien |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; 59989860Sobrien break; 60089860Sobrien } 60189860Sobrien if (idx >= shnum) 60289860Sobrien { 60389860Sobrien ((*_bfd_error_handler) 604218822Sdim (_("%B: invalid SHT_GROUP entry"), abfd)); 60589860Sobrien idx = 0; 60689860Sobrien } 60789860Sobrien dest->shdr = elf_elfsections (abfd)[idx]; 60889860Sobrien } 60989860Sobrien } 61089860Sobrien } 61189860Sobrien } 61289860Sobrien } 61389860Sobrien 61489860Sobrien if (num_group != (unsigned) -1) 61589860Sobrien { 61689860Sobrien unsigned int i; 61789860Sobrien 61889860Sobrien for (i = 0; i < num_group; i++) 61989860Sobrien { 62089860Sobrien Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i]; 62189860Sobrien Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents; 62289860Sobrien unsigned int n_elt = shdr->sh_size / 4; 62389860Sobrien 62489860Sobrien /* Look through this group's sections to see if current 62589860Sobrien section is a member. */ 62689860Sobrien while (--n_elt != 0) 62789860Sobrien if ((++idx)->shdr == hdr) 62889860Sobrien { 62989860Sobrien asection *s = NULL; 63089860Sobrien 63189860Sobrien /* We are a member of this group. Go looking through 63289860Sobrien other members to see if any others are linked via 63389860Sobrien next_in_group. */ 63489860Sobrien idx = (Elf_Internal_Group *) shdr->contents; 63589860Sobrien n_elt = shdr->sh_size / 4; 63689860Sobrien while (--n_elt != 0) 63789860Sobrien if ((s = (++idx)->shdr->bfd_section) != NULL 63889860Sobrien && elf_next_in_group (s) != NULL) 63989860Sobrien break; 64089860Sobrien if (n_elt != 0) 64189860Sobrien { 64289860Sobrien /* Snarf the group name from other member, and 64389860Sobrien insert current section in circular list. */ 64489860Sobrien elf_group_name (newsect) = elf_group_name (s); 64589860Sobrien elf_next_in_group (newsect) = elf_next_in_group (s); 64689860Sobrien elf_next_in_group (s) = newsect; 64789860Sobrien } 64889860Sobrien else 64989860Sobrien { 65089860Sobrien const char *gname; 65189860Sobrien 652104838Sobrien gname = group_signature (abfd, shdr); 653104838Sobrien if (gname == NULL) 654130563Sobrien return FALSE; 65589860Sobrien elf_group_name (newsect) = gname; 65689860Sobrien 65789860Sobrien /* Start a circular list with one element. */ 65889860Sobrien elf_next_in_group (newsect) = newsect; 65989860Sobrien } 660104838Sobrien 661104838Sobrien /* If the group section has been created, point to the 662104838Sobrien new member. */ 66389860Sobrien if (shdr->bfd_section != NULL) 66489860Sobrien elf_next_in_group (shdr->bfd_section) = newsect; 665104838Sobrien 66689860Sobrien i = num_group - 1; 66789860Sobrien break; 66889860Sobrien } 66989860Sobrien } 67089860Sobrien } 67189860Sobrien 67289860Sobrien if (elf_group_name (newsect) == NULL) 67389860Sobrien { 674218822Sdim (*_bfd_error_handler) (_("%B: no group info for section %A"), 675218822Sdim abfd, newsect); 67689860Sobrien } 677130563Sobrien return TRUE; 67889860Sobrien} 67989860Sobrien 680130563Sobrienbfd_boolean 681218822Sdim_bfd_elf_setup_sections (bfd *abfd) 682104838Sobrien{ 683218822Sdim unsigned int i; 684218822Sdim unsigned int num_group = elf_tdata (abfd)->num_group; 685218822Sdim bfd_boolean result = TRUE; 686218822Sdim asection *s; 687104838Sobrien 688218822Sdim /* Process SHF_LINK_ORDER. */ 689218822Sdim for (s = abfd->sections; s != NULL; s = s->next) 690104838Sobrien { 691218822Sdim Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr; 692218822Sdim if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0) 693218822Sdim { 694218822Sdim unsigned int elfsec = this_hdr->sh_link; 695218822Sdim /* FIXME: The old Intel compiler and old strip/objcopy may 696218822Sdim not set the sh_link or sh_info fields. Hence we could 697218822Sdim get the situation where elfsec is 0. */ 698218822Sdim if (elfsec == 0) 699218822Sdim { 700218822Sdim const struct elf_backend_data *bed 701218822Sdim = get_elf_backend_data (abfd); 702218822Sdim if (bed->link_order_error_handler) 703218822Sdim bed->link_order_error_handler 704218822Sdim (_("%B: warning: sh_link not set for section `%A'"), 705218822Sdim abfd, s); 706218822Sdim } 707218822Sdim else 708218822Sdim { 709218822Sdim asection *link; 710218822Sdim 711218822Sdim this_hdr = elf_elfsections (abfd)[elfsec]; 712218822Sdim 713218822Sdim /* PR 1991, 2008: 714218822Sdim Some strip/objcopy may leave an incorrect value in 715218822Sdim sh_link. We don't want to proceed. */ 716218822Sdim link = this_hdr->bfd_section; 717218822Sdim if (link == NULL) 718218822Sdim { 719218822Sdim (*_bfd_error_handler) 720218822Sdim (_("%B: sh_link [%d] in section `%A' is incorrect"), 721218822Sdim s->owner, s, elfsec); 722218822Sdim result = FALSE; 723218822Sdim } 724218822Sdim 725218822Sdim elf_linked_to_section (s) = link; 726218822Sdim } 727218822Sdim } 728104838Sobrien } 729218822Sdim 730218822Sdim /* Process section groups. */ 731218822Sdim if (num_group == (unsigned) -1) 732218822Sdim return result; 733218822Sdim 734218822Sdim for (i = 0; i < num_group; i++) 735218822Sdim { 736218822Sdim Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i]; 737218822Sdim Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents; 738218822Sdim unsigned int n_elt = shdr->sh_size / 4; 739218822Sdim 740218822Sdim while (--n_elt != 0) 741218822Sdim if ((++idx)->shdr->bfd_section) 742218822Sdim elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section; 743218822Sdim else if (idx->shdr->sh_type == SHT_RELA 744218822Sdim || idx->shdr->sh_type == SHT_REL) 745218822Sdim /* We won't include relocation sections in section groups in 746218822Sdim output object files. We adjust the group section size here 747218822Sdim so that relocatable link will work correctly when 748218822Sdim relocation sections are in section group in input object 749218822Sdim files. */ 750218822Sdim shdr->bfd_section->size -= 4; 751218822Sdim else 752218822Sdim { 753218822Sdim /* There are some unknown sections in the group. */ 754218822Sdim (*_bfd_error_handler) 755218822Sdim (_("%B: unknown [%d] section `%s' in group [%s]"), 756218822Sdim abfd, 757218822Sdim (unsigned int) idx->shdr->sh_type, 758218822Sdim bfd_elf_string_from_elf_section (abfd, 759218822Sdim (elf_elfheader (abfd) 760218822Sdim ->e_shstrndx), 761218822Sdim idx->shdr->sh_name), 762218822Sdim shdr->bfd_section->name); 763218822Sdim result = FALSE; 764218822Sdim } 765218822Sdim } 766218822Sdim return result; 767104838Sobrien} 768104838Sobrien 769218822Sdimbfd_boolean 770218822Sdimbfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec) 771218822Sdim{ 772218822Sdim return elf_next_in_group (sec) != NULL; 773218822Sdim} 774218822Sdim 77533965Sjdp/* Make a BFD section from an ELF section. We store a pointer to the 77633965Sjdp BFD section in the bfd_section field of the header. */ 77733965Sjdp 778130563Sobrienbfd_boolean 779130563Sobrien_bfd_elf_make_section_from_shdr (bfd *abfd, 780130563Sobrien Elf_Internal_Shdr *hdr, 781218822Sdim const char *name, 782218822Sdim int shindex) 78333965Sjdp{ 78433965Sjdp asection *newsect; 78533965Sjdp flagword flags; 786130563Sobrien const struct elf_backend_data *bed; 78733965Sjdp 78833965Sjdp if (hdr->bfd_section != NULL) 78933965Sjdp { 79033965Sjdp BFD_ASSERT (strcmp (name, 79133965Sjdp bfd_get_section_name (abfd, hdr->bfd_section)) == 0); 792130563Sobrien return TRUE; 79333965Sjdp } 79433965Sjdp 79533965Sjdp newsect = bfd_make_section_anyway (abfd, name); 79633965Sjdp if (newsect == NULL) 797130563Sobrien return FALSE; 79833965Sjdp 799218822Sdim hdr->bfd_section = newsect; 800218822Sdim elf_section_data (newsect)->this_hdr = *hdr; 801218822Sdim elf_section_data (newsect)->this_idx = shindex; 802218822Sdim 803130563Sobrien /* Always use the real type/flags. */ 804130563Sobrien elf_section_type (newsect) = hdr->sh_type; 805130563Sobrien elf_section_flags (newsect) = hdr->sh_flags; 806130563Sobrien 80733965Sjdp newsect->filepos = hdr->sh_offset; 80833965Sjdp 80933965Sjdp if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr) 81033965Sjdp || ! bfd_set_section_size (abfd, newsect, hdr->sh_size) 81133965Sjdp || ! bfd_set_section_alignment (abfd, newsect, 81289860Sobrien bfd_log2 ((bfd_vma) hdr->sh_addralign))) 813130563Sobrien return FALSE; 81433965Sjdp 81533965Sjdp flags = SEC_NO_FLAGS; 81633965Sjdp if (hdr->sh_type != SHT_NOBITS) 81733965Sjdp flags |= SEC_HAS_CONTENTS; 81889860Sobrien if (hdr->sh_type == SHT_GROUP) 81989860Sobrien flags |= SEC_GROUP | SEC_EXCLUDE; 82033965Sjdp if ((hdr->sh_flags & SHF_ALLOC) != 0) 82133965Sjdp { 82233965Sjdp flags |= SEC_ALLOC; 82333965Sjdp if (hdr->sh_type != SHT_NOBITS) 82433965Sjdp flags |= SEC_LOAD; 82533965Sjdp } 82633965Sjdp if ((hdr->sh_flags & SHF_WRITE) == 0) 82733965Sjdp flags |= SEC_READONLY; 82833965Sjdp if ((hdr->sh_flags & SHF_EXECINSTR) != 0) 82933965Sjdp flags |= SEC_CODE; 83033965Sjdp else if ((flags & SEC_LOAD) != 0) 83133965Sjdp flags |= SEC_DATA; 83289860Sobrien if ((hdr->sh_flags & SHF_MERGE) != 0) 83389860Sobrien { 83489860Sobrien flags |= SEC_MERGE; 83589860Sobrien newsect->entsize = hdr->sh_entsize; 83689860Sobrien if ((hdr->sh_flags & SHF_STRINGS) != 0) 83789860Sobrien flags |= SEC_STRINGS; 83889860Sobrien } 83989860Sobrien if (hdr->sh_flags & SHF_GROUP) 84089860Sobrien if (!setup_group (abfd, hdr, newsect)) 841130563Sobrien return FALSE; 842104838Sobrien if ((hdr->sh_flags & SHF_TLS) != 0) 843104838Sobrien flags |= SEC_THREAD_LOCAL; 84433965Sjdp 845218822Sdim if ((flags & SEC_ALLOC) == 0) 84677301Sobrien { 847218822Sdim /* The debugging sections appear to be recognized only by name, 848218822Sdim not any sort of flag. Their SEC_ALLOC bits are cleared. */ 849218822Sdim static const struct 850218822Sdim { 851218822Sdim const char *name; 852218822Sdim int len; 853218822Sdim } debug_sections [] = 854218822Sdim { 855218822Sdim { STRING_COMMA_LEN ("debug") }, /* 'd' */ 856218822Sdim { NULL, 0 }, /* 'e' */ 857218822Sdim { NULL, 0 }, /* 'f' */ 858218822Sdim { STRING_COMMA_LEN ("gnu.linkonce.wi.") }, /* 'g' */ 859218822Sdim { NULL, 0 }, /* 'h' */ 860218822Sdim { NULL, 0 }, /* 'i' */ 861218822Sdim { NULL, 0 }, /* 'j' */ 862218822Sdim { NULL, 0 }, /* 'k' */ 863218822Sdim { STRING_COMMA_LEN ("line") }, /* 'l' */ 864218822Sdim { NULL, 0 }, /* 'm' */ 865218822Sdim { NULL, 0 }, /* 'n' */ 866218822Sdim { NULL, 0 }, /* 'o' */ 867218822Sdim { NULL, 0 }, /* 'p' */ 868218822Sdim { NULL, 0 }, /* 'q' */ 869218822Sdim { NULL, 0 }, /* 'r' */ 870218822Sdim { STRING_COMMA_LEN ("stab") } /* 's' */ 871218822Sdim }; 87233965Sjdp 873218822Sdim if (name [0] == '.') 874218822Sdim { 875218822Sdim int i = name [1] - 'd'; 876218822Sdim if (i >= 0 877218822Sdim && i < (int) ARRAY_SIZE (debug_sections) 878218822Sdim && debug_sections [i].name != NULL 879218822Sdim && strncmp (&name [1], debug_sections [i].name, 880218822Sdim debug_sections [i].len) == 0) 881218822Sdim flags |= SEC_DEBUGGING; 882218822Sdim } 883218822Sdim } 88477301Sobrien 88533965Sjdp /* As a GNU extension, if the name begins with .gnu.linkonce, we 88633965Sjdp only link a single copy of the section. This is used to support 88733965Sjdp g++. g++ will emit each template expansion in its own section. 88833965Sjdp The symbols will be defined as weak, so that multiple definitions 88933965Sjdp are permitted. The GNU linker extension is to actually discard 89033965Sjdp all but one of the sections. */ 891218822Sdim if (CONST_STRNEQ (name, ".gnu.linkonce") 892104838Sobrien && elf_next_in_group (newsect) == NULL) 89333965Sjdp flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; 89433965Sjdp 89577301Sobrien bed = get_elf_backend_data (abfd); 89677301Sobrien if (bed->elf_backend_section_flags) 89777301Sobrien if (! bed->elf_backend_section_flags (&flags, hdr)) 898130563Sobrien return FALSE; 89977301Sobrien 90033965Sjdp if (! bfd_set_section_flags (abfd, newsect, flags)) 901130563Sobrien return FALSE; 90233965Sjdp 90333965Sjdp if ((flags & SEC_ALLOC) != 0) 90433965Sjdp { 90533965Sjdp Elf_Internal_Phdr *phdr; 90633965Sjdp unsigned int i; 90733965Sjdp 90860508Sobrien /* Look through the phdrs to see if we need to adjust the lma. 909218822Sdim If all the p_paddr fields are zero, we ignore them, since 910218822Sdim some ELF linkers produce such output. */ 91133965Sjdp phdr = elf_tdata (abfd)->phdr; 91233965Sjdp for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) 91333965Sjdp { 91460508Sobrien if (phdr->p_paddr != 0) 91560508Sobrien break; 91660508Sobrien } 91760508Sobrien if (i < elf_elfheader (abfd)->e_phnum) 91860508Sobrien { 91960508Sobrien phdr = elf_tdata (abfd)->phdr; 92060508Sobrien for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) 92133965Sjdp { 92289860Sobrien /* This section is part of this segment if its file 92389860Sobrien offset plus size lies within the segment's memory 92489860Sobrien span and, if the section is loaded, the extent of the 925104838Sobrien loaded data lies within the extent of the segment. 92694542Sobrien 92794542Sobrien Note - we used to check the p_paddr field as well, and 92894542Sobrien refuse to set the LMA if it was 0. This is wrong 92994542Sobrien though, as a perfectly valid initialised segment can 93094542Sobrien have a p_paddr of zero. Some architectures, eg ARM, 931218822Sdim place special significance on the address 0 and 932218822Sdim executables need to be able to have a segment which 933218822Sdim covers this address. */ 93460508Sobrien if (phdr->p_type == PT_LOAD 93589860Sobrien && (bfd_vma) hdr->sh_offset >= phdr->p_offset 93689860Sobrien && (hdr->sh_offset + hdr->sh_size 93789860Sobrien <= phdr->p_offset + phdr->p_memsz) 93860508Sobrien && ((flags & SEC_LOAD) == 0 93994542Sobrien || (hdr->sh_offset + hdr->sh_size 94094542Sobrien <= phdr->p_offset + phdr->p_filesz))) 94160508Sobrien { 94294542Sobrien if ((flags & SEC_LOAD) == 0) 94394542Sobrien newsect->lma = (phdr->p_paddr 94494542Sobrien + hdr->sh_addr - phdr->p_vaddr); 94594542Sobrien else 94694542Sobrien /* We used to use the same adjustment for SEC_LOAD 94794542Sobrien sections, but that doesn't work if the segment 94894542Sobrien is packed with code from multiple VMAs. 94994542Sobrien Instead we calculate the section LMA based on 95094542Sobrien the segment LMA. It is assumed that the 95194542Sobrien segment will contain sections with contiguous 95294542Sobrien LMAs, even if the VMAs are not. */ 95394542Sobrien newsect->lma = (phdr->p_paddr 95494542Sobrien + hdr->sh_offset - phdr->p_offset); 95594542Sobrien 95694542Sobrien /* With contiguous segments, we can't tell from file 95794542Sobrien offsets whether a section with zero size should 95894542Sobrien be placed at the end of one segment or the 95994542Sobrien beginning of the next. Decide based on vaddr. */ 96094542Sobrien if (hdr->sh_addr >= phdr->p_vaddr 96194542Sobrien && (hdr->sh_addr + hdr->sh_size 96294542Sobrien <= phdr->p_vaddr + phdr->p_memsz)) 96394542Sobrien break; 96460508Sobrien } 96533965Sjdp } 96633965Sjdp } 96733965Sjdp } 96833965Sjdp 969130563Sobrien return TRUE; 97033965Sjdp} 97133965Sjdp 97233965Sjdp/* 97333965SjdpINTERNAL_FUNCTION 97433965Sjdp bfd_elf_find_section 97533965Sjdp 97633965SjdpSYNOPSIS 97733965Sjdp struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name); 97833965Sjdp 97933965SjdpDESCRIPTION 98033965Sjdp Helper functions for GDB to locate the string tables. 98133965Sjdp Since BFD hides string tables from callers, GDB needs to use an 98233965Sjdp internal hook to find them. Sun's .stabstr, in particular, 98333965Sjdp isn't even pointed to by the .stab section, so ordinary 98433965Sjdp mechanisms wouldn't work to find it, even if we had some. 98533965Sjdp*/ 98633965Sjdp 98733965Sjdpstruct elf_internal_shdr * 988130563Sobrienbfd_elf_find_section (bfd *abfd, char *name) 98933965Sjdp{ 99033965Sjdp Elf_Internal_Shdr **i_shdrp; 99133965Sjdp char *shstrtab; 99233965Sjdp unsigned int max; 99333965Sjdp unsigned int i; 99433965Sjdp 99533965Sjdp i_shdrp = elf_elfsections (abfd); 99633965Sjdp if (i_shdrp != NULL) 99733965Sjdp { 99889860Sobrien shstrtab = bfd_elf_get_str_section (abfd, 99989860Sobrien elf_elfheader (abfd)->e_shstrndx); 100033965Sjdp if (shstrtab != NULL) 100133965Sjdp { 100289860Sobrien max = elf_numsections (abfd); 100333965Sjdp for (i = 1; i < max; i++) 100433965Sjdp if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name)) 100533965Sjdp return i_shdrp[i]; 100633965Sjdp } 100733965Sjdp } 100833965Sjdp return 0; 100933965Sjdp} 101033965Sjdp 101133965Sjdpconst char *const bfd_elf_section_type_names[] = { 101233965Sjdp "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB", 101333965Sjdp "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE", 101433965Sjdp "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM", 101533965Sjdp}; 101633965Sjdp 1017130563Sobrien/* ELF relocs are against symbols. If we are producing relocatable 101833965Sjdp output, and the reloc is against an external symbol, and nothing 101933965Sjdp has given us any additional addend, the resulting reloc will also 102033965Sjdp be against the same symbol. In such a case, we don't want to 102133965Sjdp change anything about the way the reloc is handled, since it will 102233965Sjdp all be done at final link time. Rather than put special case code 102333965Sjdp into bfd_perform_relocation, all the reloc types use this howto 102433965Sjdp function. It just short circuits the reloc if producing 1025130563Sobrien relocatable output against an external symbol. */ 102633965Sjdp 102733965Sjdpbfd_reloc_status_type 1028130563Sobrienbfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, 1029130563Sobrien arelent *reloc_entry, 1030130563Sobrien asymbol *symbol, 1031130563Sobrien void *data ATTRIBUTE_UNUSED, 1032130563Sobrien asection *input_section, 1033130563Sobrien bfd *output_bfd, 1034130563Sobrien char **error_message ATTRIBUTE_UNUSED) 103533965Sjdp{ 1036130563Sobrien if (output_bfd != NULL 103733965Sjdp && (symbol->flags & BSF_SECTION_SYM) == 0 103833965Sjdp && (! reloc_entry->howto->partial_inplace 103933965Sjdp || reloc_entry->addend == 0)) 104033965Sjdp { 104133965Sjdp reloc_entry->address += input_section->output_offset; 104233965Sjdp return bfd_reloc_ok; 104333965Sjdp } 104433965Sjdp 104533965Sjdp return bfd_reloc_continue; 104633965Sjdp} 104733965Sjdp 104889860Sobrien/* Make sure sec_info_type is cleared if sec_info is cleared too. */ 104989860Sobrien 105089860Sobrienstatic void 1051130563Sobrienmerge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED, 1052130563Sobrien asection *sec) 105389860Sobrien{ 1054130563Sobrien BFD_ASSERT (sec->sec_info_type == ELF_INFO_TYPE_MERGE); 1055130563Sobrien sec->sec_info_type = ELF_INFO_TYPE_NONE; 105689860Sobrien} 105789860Sobrien 105889860Sobrien/* Finish SHF_MERGE section merging. */ 105989860Sobrien 1060130563Sobrienbfd_boolean 1061130563Sobrien_bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info) 106289860Sobrien{ 1063218822Sdim bfd *ibfd; 1064218822Sdim asection *sec; 1065218822Sdim 1066130563Sobrien if (!is_elf_hash_table (info->hash)) 1067130563Sobrien return FALSE; 1068218822Sdim 1069218822Sdim for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) 1070218822Sdim if ((ibfd->flags & DYNAMIC) == 0) 1071218822Sdim for (sec = ibfd->sections; sec != NULL; sec = sec->next) 1072218822Sdim if ((sec->flags & SEC_MERGE) != 0 1073218822Sdim && !bfd_is_abs_section (sec->output_section)) 1074218822Sdim { 1075218822Sdim struct bfd_elf_section_data *secdata; 1076218822Sdim 1077218822Sdim secdata = elf_section_data (sec); 1078218822Sdim if (! _bfd_add_merge_section (abfd, 1079218822Sdim &elf_hash_table (info)->merge_info, 1080218822Sdim sec, &secdata->sec_info)) 1081218822Sdim return FALSE; 1082218822Sdim else if (secdata->sec_info) 1083218822Sdim sec->sec_info_type = ELF_INFO_TYPE_MERGE; 1084218822Sdim } 1085218822Sdim 1086218822Sdim if (elf_hash_table (info)->merge_info != NULL) 1087218822Sdim _bfd_merge_sections (abfd, info, elf_hash_table (info)->merge_info, 108889860Sobrien merge_sections_remove_hook); 1089130563Sobrien return TRUE; 109089860Sobrien} 1091104838Sobrien 1092104838Sobrienvoid 1093130563Sobrien_bfd_elf_link_just_syms (asection *sec, struct bfd_link_info *info) 1094104838Sobrien{ 1095104838Sobrien sec->output_section = bfd_abs_section_ptr; 1096104838Sobrien sec->output_offset = sec->vma; 1097130563Sobrien if (!is_elf_hash_table (info->hash)) 1098104838Sobrien return; 1099104838Sobrien 1100130563Sobrien sec->sec_info_type = ELF_INFO_TYPE_JUST_SYMS; 1101104838Sobrien} 110289860Sobrien 110389860Sobrien/* Copy the program header and other data from one object module to 110489860Sobrien another. */ 110589860Sobrien 1106130563Sobrienbfd_boolean 1107130563Sobrien_bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) 110889860Sobrien{ 110989860Sobrien if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 111089860Sobrien || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 1111130563Sobrien return TRUE; 111289860Sobrien 111389860Sobrien BFD_ASSERT (!elf_flags_init (obfd) 111489860Sobrien || (elf_elfheader (obfd)->e_flags 111589860Sobrien == elf_elfheader (ibfd)->e_flags)); 111689860Sobrien 111789860Sobrien elf_gp (obfd) = elf_gp (ibfd); 111889860Sobrien elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; 1119130563Sobrien elf_flags_init (obfd) = TRUE; 1120218822Sdim 1121218822Sdim /* Copy object attributes. */ 1122218822Sdim _bfd_elf_copy_obj_attributes (ibfd, obfd); 1123218822Sdim 1124130563Sobrien return TRUE; 112589860Sobrien} 112689860Sobrien 1127218822Sdimstatic const char * 1128218822Sdimget_segment_type (unsigned int p_type) 1129218822Sdim{ 1130218822Sdim const char *pt; 1131218822Sdim switch (p_type) 1132218822Sdim { 1133218822Sdim case PT_NULL: pt = "NULL"; break; 1134218822Sdim case PT_LOAD: pt = "LOAD"; break; 1135218822Sdim case PT_DYNAMIC: pt = "DYNAMIC"; break; 1136218822Sdim case PT_INTERP: pt = "INTERP"; break; 1137218822Sdim case PT_NOTE: pt = "NOTE"; break; 1138218822Sdim case PT_SHLIB: pt = "SHLIB"; break; 1139218822Sdim case PT_PHDR: pt = "PHDR"; break; 1140218822Sdim case PT_TLS: pt = "TLS"; break; 1141218822Sdim case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break; 1142218822Sdim case PT_GNU_STACK: pt = "STACK"; break; 1143218822Sdim case PT_GNU_RELRO: pt = "RELRO"; break; 1144218822Sdim default: pt = NULL; break; 1145218822Sdim } 1146218822Sdim return pt; 1147218822Sdim} 1148218822Sdim 114933965Sjdp/* Print out the program headers. */ 115033965Sjdp 1151130563Sobrienbfd_boolean 1152130563Sobrien_bfd_elf_print_private_bfd_data (bfd *abfd, void *farg) 115333965Sjdp{ 1154130563Sobrien FILE *f = farg; 115533965Sjdp Elf_Internal_Phdr *p; 115633965Sjdp asection *s; 115733965Sjdp bfd_byte *dynbuf = NULL; 115833965Sjdp 115933965Sjdp p = elf_tdata (abfd)->phdr; 116033965Sjdp if (p != NULL) 116133965Sjdp { 116233965Sjdp unsigned int i, c; 116333965Sjdp 116460508Sobrien fprintf (f, _("\nProgram Header:\n")); 116533965Sjdp c = elf_elfheader (abfd)->e_phnum; 116633965Sjdp for (i = 0; i < c; i++, p++) 116733965Sjdp { 1168218822Sdim const char *pt = get_segment_type (p->p_type); 116933965Sjdp char buf[20]; 117033965Sjdp 1171218822Sdim if (pt == NULL) 117233965Sjdp { 1173218822Sdim sprintf (buf, "0x%lx", p->p_type); 1174218822Sdim pt = buf; 117533965Sjdp } 117689860Sobrien fprintf (f, "%8s off 0x", pt); 117789860Sobrien bfd_fprintf_vma (abfd, f, p->p_offset); 117833965Sjdp fprintf (f, " vaddr 0x"); 117989860Sobrien bfd_fprintf_vma (abfd, f, p->p_vaddr); 118033965Sjdp fprintf (f, " paddr 0x"); 118189860Sobrien bfd_fprintf_vma (abfd, f, p->p_paddr); 118233965Sjdp fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align)); 118333965Sjdp fprintf (f, " filesz 0x"); 118489860Sobrien bfd_fprintf_vma (abfd, f, p->p_filesz); 118533965Sjdp fprintf (f, " memsz 0x"); 118689860Sobrien bfd_fprintf_vma (abfd, f, p->p_memsz); 118733965Sjdp fprintf (f, " flags %c%c%c", 118833965Sjdp (p->p_flags & PF_R) != 0 ? 'r' : '-', 118933965Sjdp (p->p_flags & PF_W) != 0 ? 'w' : '-', 119033965Sjdp (p->p_flags & PF_X) != 0 ? 'x' : '-'); 119189860Sobrien if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0) 119289860Sobrien fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)); 119333965Sjdp fprintf (f, "\n"); 119433965Sjdp } 119533965Sjdp } 119633965Sjdp 119733965Sjdp s = bfd_get_section_by_name (abfd, ".dynamic"); 119833965Sjdp if (s != NULL) 119933965Sjdp { 120033965Sjdp int elfsec; 120189860Sobrien unsigned long shlink; 120233965Sjdp bfd_byte *extdyn, *extdynend; 120333965Sjdp size_t extdynsize; 1204130563Sobrien void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); 120533965Sjdp 120660508Sobrien fprintf (f, _("\nDynamic Section:\n")); 120733965Sjdp 1208218822Sdim if (!bfd_malloc_and_get_section (abfd, s, &dynbuf)) 120933965Sjdp goto error_return; 121033965Sjdp 121133965Sjdp elfsec = _bfd_elf_section_from_bfd_section (abfd, s); 121233965Sjdp if (elfsec == -1) 121333965Sjdp goto error_return; 121489860Sobrien shlink = elf_elfsections (abfd)[elfsec]->sh_link; 121533965Sjdp 121633965Sjdp extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn; 121733965Sjdp swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in; 121833965Sjdp 121933965Sjdp extdyn = dynbuf; 1220218822Sdim extdynend = extdyn + s->size; 122133965Sjdp for (; extdyn < extdynend; extdyn += extdynsize) 122233965Sjdp { 122333965Sjdp Elf_Internal_Dyn dyn; 122433965Sjdp const char *name; 122533965Sjdp char ab[20]; 1226130563Sobrien bfd_boolean stringp; 122733965Sjdp 1228130563Sobrien (*swap_dyn_in) (abfd, extdyn, &dyn); 122933965Sjdp 123033965Sjdp if (dyn.d_tag == DT_NULL) 123133965Sjdp break; 123233965Sjdp 1233130563Sobrien stringp = FALSE; 123433965Sjdp switch (dyn.d_tag) 123533965Sjdp { 123633965Sjdp default: 123733965Sjdp sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag); 123833965Sjdp name = ab; 123933965Sjdp break; 124033965Sjdp 1241130563Sobrien case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break; 124233965Sjdp case DT_PLTRELSZ: name = "PLTRELSZ"; break; 124333965Sjdp case DT_PLTGOT: name = "PLTGOT"; break; 124433965Sjdp case DT_HASH: name = "HASH"; break; 124533965Sjdp case DT_STRTAB: name = "STRTAB"; break; 124633965Sjdp case DT_SYMTAB: name = "SYMTAB"; break; 124733965Sjdp case DT_RELA: name = "RELA"; break; 124833965Sjdp case DT_RELASZ: name = "RELASZ"; break; 124933965Sjdp case DT_RELAENT: name = "RELAENT"; break; 125033965Sjdp case DT_STRSZ: name = "STRSZ"; break; 125133965Sjdp case DT_SYMENT: name = "SYMENT"; break; 125233965Sjdp case DT_INIT: name = "INIT"; break; 125333965Sjdp case DT_FINI: name = "FINI"; break; 1254130563Sobrien case DT_SONAME: name = "SONAME"; stringp = TRUE; break; 1255130563Sobrien case DT_RPATH: name = "RPATH"; stringp = TRUE; break; 125633965Sjdp case DT_SYMBOLIC: name = "SYMBOLIC"; break; 125733965Sjdp case DT_REL: name = "REL"; break; 125833965Sjdp case DT_RELSZ: name = "RELSZ"; break; 125933965Sjdp case DT_RELENT: name = "RELENT"; break; 126033965Sjdp case DT_PLTREL: name = "PLTREL"; break; 126133965Sjdp case DT_DEBUG: name = "DEBUG"; break; 126233965Sjdp case DT_TEXTREL: name = "TEXTREL"; break; 126333965Sjdp case DT_JMPREL: name = "JMPREL"; break; 126477301Sobrien case DT_BIND_NOW: name = "BIND_NOW"; break; 126577301Sobrien case DT_INIT_ARRAY: name = "INIT_ARRAY"; break; 126677301Sobrien case DT_FINI_ARRAY: name = "FINI_ARRAY"; break; 126777301Sobrien case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break; 126877301Sobrien case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break; 1269130563Sobrien case DT_RUNPATH: name = "RUNPATH"; stringp = TRUE; break; 127077301Sobrien case DT_FLAGS: name = "FLAGS"; break; 127177301Sobrien case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break; 127277301Sobrien case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break; 127377301Sobrien case DT_CHECKSUM: name = "CHECKSUM"; break; 127477301Sobrien case DT_PLTPADSZ: name = "PLTPADSZ"; break; 127577301Sobrien case DT_MOVEENT: name = "MOVEENT"; break; 127677301Sobrien case DT_MOVESZ: name = "MOVESZ"; break; 127777301Sobrien case DT_FEATURE: name = "FEATURE"; break; 127877301Sobrien case DT_POSFLAG_1: name = "POSFLAG_1"; break; 127977301Sobrien case DT_SYMINSZ: name = "SYMINSZ"; break; 128077301Sobrien case DT_SYMINENT: name = "SYMINENT"; break; 1281130563Sobrien case DT_CONFIG: name = "CONFIG"; stringp = TRUE; break; 1282130563Sobrien case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = TRUE; break; 1283130563Sobrien case DT_AUDIT: name = "AUDIT"; stringp = TRUE; break; 128477301Sobrien case DT_PLTPAD: name = "PLTPAD"; break; 128577301Sobrien case DT_MOVETAB: name = "MOVETAB"; break; 128677301Sobrien case DT_SYMINFO: name = "SYMINFO"; break; 128777301Sobrien case DT_RELACOUNT: name = "RELACOUNT"; break; 128877301Sobrien case DT_RELCOUNT: name = "RELCOUNT"; break; 128977301Sobrien case DT_FLAGS_1: name = "FLAGS_1"; break; 129033965Sjdp case DT_VERSYM: name = "VERSYM"; break; 129133965Sjdp case DT_VERDEF: name = "VERDEF"; break; 129233965Sjdp case DT_VERDEFNUM: name = "VERDEFNUM"; break; 129333965Sjdp case DT_VERNEED: name = "VERNEED"; break; 129433965Sjdp case DT_VERNEEDNUM: name = "VERNEEDNUM"; break; 1295130563Sobrien case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break; 129677301Sobrien case DT_USED: name = "USED"; break; 1297130563Sobrien case DT_FILTER: name = "FILTER"; stringp = TRUE; break; 1298218822Sdim case DT_GNU_HASH: name = "GNU_HASH"; break; 129933965Sjdp } 130033965Sjdp 130133965Sjdp fprintf (f, " %-11s ", name); 130233965Sjdp if (! stringp) 130333965Sjdp fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val); 130433965Sjdp else 130533965Sjdp { 130633965Sjdp const char *string; 130789860Sobrien unsigned int tagv = dyn.d_un.d_val; 130833965Sjdp 130989860Sobrien string = bfd_elf_string_from_elf_section (abfd, shlink, tagv); 131033965Sjdp if (string == NULL) 131133965Sjdp goto error_return; 131233965Sjdp fprintf (f, "%s", string); 131333965Sjdp } 131433965Sjdp fprintf (f, "\n"); 131533965Sjdp } 131633965Sjdp 131733965Sjdp free (dynbuf); 131833965Sjdp dynbuf = NULL; 131933965Sjdp } 132033965Sjdp 132133965Sjdp if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL) 132233965Sjdp || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL)) 132333965Sjdp { 1324218822Sdim if (! _bfd_elf_slurp_version_tables (abfd, FALSE)) 1325130563Sobrien return FALSE; 132633965Sjdp } 132733965Sjdp 132833965Sjdp if (elf_dynverdef (abfd) != 0) 132933965Sjdp { 133033965Sjdp Elf_Internal_Verdef *t; 133133965Sjdp 133260508Sobrien fprintf (f, _("\nVersion definitions:\n")); 133333965Sjdp for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef) 133433965Sjdp { 133533965Sjdp fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx, 1336218822Sdim t->vd_flags, t->vd_hash, 1337218822Sdim t->vd_nodename ? t->vd_nodename : "<corrupt>"); 1338218822Sdim if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL) 133933965Sjdp { 134033965Sjdp Elf_Internal_Verdaux *a; 134133965Sjdp 134233965Sjdp fprintf (f, "\t"); 134333965Sjdp for (a = t->vd_auxptr->vda_nextptr; 134433965Sjdp a != NULL; 134533965Sjdp a = a->vda_nextptr) 1346218822Sdim fprintf (f, "%s ", 1347218822Sdim a->vda_nodename ? a->vda_nodename : "<corrupt>"); 134833965Sjdp fprintf (f, "\n"); 134933965Sjdp } 135033965Sjdp } 135133965Sjdp } 135233965Sjdp 135333965Sjdp if (elf_dynverref (abfd) != 0) 135433965Sjdp { 135533965Sjdp Elf_Internal_Verneed *t; 135633965Sjdp 135760508Sobrien fprintf (f, _("\nVersion References:\n")); 135833965Sjdp for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref) 135933965Sjdp { 136033965Sjdp Elf_Internal_Vernaux *a; 136133965Sjdp 1362218822Sdim fprintf (f, _(" required from %s:\n"), 1363218822Sdim t->vn_filename ? t->vn_filename : "<corrupt>"); 136433965Sjdp for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 136533965Sjdp fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash, 1366218822Sdim a->vna_flags, a->vna_other, 1367218822Sdim a->vna_nodename ? a->vna_nodename : "<corrupt>"); 136833965Sjdp } 136933965Sjdp } 137033965Sjdp 1371130563Sobrien return TRUE; 137233965Sjdp 137333965Sjdp error_return: 137433965Sjdp if (dynbuf != NULL) 137533965Sjdp free (dynbuf); 1376130563Sobrien return FALSE; 137733965Sjdp} 137833965Sjdp 137933965Sjdp/* Display ELF-specific fields of a symbol. */ 138033965Sjdp 138133965Sjdpvoid 1382130563Sobrienbfd_elf_print_symbol (bfd *abfd, 1383130563Sobrien void *filep, 1384130563Sobrien asymbol *symbol, 1385130563Sobrien bfd_print_symbol_type how) 138633965Sjdp{ 1387130563Sobrien FILE *file = filep; 138833965Sjdp switch (how) 138933965Sjdp { 139033965Sjdp case bfd_print_symbol_name: 139133965Sjdp fprintf (file, "%s", symbol->name); 139233965Sjdp break; 139333965Sjdp case bfd_print_symbol_more: 139433965Sjdp fprintf (file, "elf "); 139589860Sobrien bfd_fprintf_vma (abfd, file, symbol->value); 139633965Sjdp fprintf (file, " %lx", (long) symbol->flags); 139733965Sjdp break; 139833965Sjdp case bfd_print_symbol_all: 139933965Sjdp { 140078831Sobrien const char *section_name; 140178831Sobrien const char *name = NULL; 1402130563Sobrien const struct elf_backend_data *bed; 140360508Sobrien unsigned char st_other; 140489860Sobrien bfd_vma val; 140577301Sobrien 140633965Sjdp section_name = symbol->section ? symbol->section->name : "(*none*)"; 140760508Sobrien 140860508Sobrien bed = get_elf_backend_data (abfd); 140960508Sobrien if (bed->elf_backend_print_symbol_all) 141077301Sobrien name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol); 141160508Sobrien 141260508Sobrien if (name == NULL) 141360508Sobrien { 141477301Sobrien name = symbol->name; 1415130563Sobrien bfd_print_symbol_vandf (abfd, file, symbol); 141660508Sobrien } 141760508Sobrien 141833965Sjdp fprintf (file, " %s\t", section_name); 141933965Sjdp /* Print the "other" value for a symbol. For common symbols, 142033965Sjdp we've already printed the size; now print the alignment. 142133965Sjdp For other symbols, we have no specified alignment, and 142233965Sjdp we've printed the address; now print the size. */ 142389860Sobrien if (bfd_is_com_section (symbol->section)) 142489860Sobrien val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value; 142589860Sobrien else 142689860Sobrien val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size; 142789860Sobrien bfd_fprintf_vma (abfd, file, val); 142833965Sjdp 142933965Sjdp /* If we have version information, print it. */ 143033965Sjdp if (elf_tdata (abfd)->dynversym_section != 0 143133965Sjdp && (elf_tdata (abfd)->dynverdef_section != 0 143233965Sjdp || elf_tdata (abfd)->dynverref_section != 0)) 143333965Sjdp { 143433965Sjdp unsigned int vernum; 143533965Sjdp const char *version_string; 143633965Sjdp 143733965Sjdp vernum = ((elf_symbol_type *) symbol)->version & VERSYM_VERSION; 143833965Sjdp 143933965Sjdp if (vernum == 0) 144033965Sjdp version_string = ""; 144133965Sjdp else if (vernum == 1) 144233965Sjdp version_string = "Base"; 144333965Sjdp else if (vernum <= elf_tdata (abfd)->cverdefs) 144433965Sjdp version_string = 144533965Sjdp elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; 144633965Sjdp else 144733965Sjdp { 144833965Sjdp Elf_Internal_Verneed *t; 144933965Sjdp 145033965Sjdp version_string = ""; 145133965Sjdp for (t = elf_tdata (abfd)->verref; 145233965Sjdp t != NULL; 145333965Sjdp t = t->vn_nextref) 145433965Sjdp { 145533965Sjdp Elf_Internal_Vernaux *a; 145633965Sjdp 145733965Sjdp for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 145833965Sjdp { 145933965Sjdp if (a->vna_other == vernum) 146033965Sjdp { 146133965Sjdp version_string = a->vna_nodename; 146233965Sjdp break; 146333965Sjdp } 146433965Sjdp } 146533965Sjdp } 146633965Sjdp } 146733965Sjdp 146833965Sjdp if ((((elf_symbol_type *) symbol)->version & VERSYM_HIDDEN) == 0) 146933965Sjdp fprintf (file, " %-11s", version_string); 147033965Sjdp else 147133965Sjdp { 147233965Sjdp int i; 147333965Sjdp 147433965Sjdp fprintf (file, " (%s)", version_string); 147533965Sjdp for (i = 10 - strlen (version_string); i > 0; --i) 147633965Sjdp putc (' ', file); 147733965Sjdp } 147833965Sjdp } 147933965Sjdp 148033965Sjdp /* If the st_other field is not zero, print it. */ 148160508Sobrien st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other; 148277301Sobrien 148360508Sobrien switch (st_other) 148460508Sobrien { 148560508Sobrien case 0: break; 148660508Sobrien case STV_INTERNAL: fprintf (file, " .internal"); break; 148760508Sobrien case STV_HIDDEN: fprintf (file, " .hidden"); break; 148860508Sobrien case STV_PROTECTED: fprintf (file, " .protected"); break; 148960508Sobrien default: 149060508Sobrien /* Some other non-defined flags are also present, so print 149160508Sobrien everything hex. */ 149260508Sobrien fprintf (file, " 0x%02x", (unsigned int) st_other); 149360508Sobrien } 149433965Sjdp 149560508Sobrien fprintf (file, " %s", name); 149633965Sjdp } 149733965Sjdp break; 149833965Sjdp } 149933965Sjdp} 150033965Sjdp 150133965Sjdp/* Create an entry in an ELF linker hash table. */ 150233965Sjdp 150333965Sjdpstruct bfd_hash_entry * 1504130563Sobrien_bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry, 1505130563Sobrien struct bfd_hash_table *table, 1506130563Sobrien const char *string) 150733965Sjdp{ 150833965Sjdp /* Allocate the structure if it has not already been allocated by a 150933965Sjdp subclass. */ 151089860Sobrien if (entry == NULL) 151189860Sobrien { 151289860Sobrien entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)); 151389860Sobrien if (entry == NULL) 151489860Sobrien return entry; 151589860Sobrien } 151633965Sjdp 151733965Sjdp /* Call the allocation method of the superclass. */ 151889860Sobrien entry = _bfd_link_hash_newfunc (entry, table, string); 151989860Sobrien if (entry != NULL) 152033965Sjdp { 152189860Sobrien struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry; 152289860Sobrien struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table; 152389860Sobrien 152433965Sjdp /* Set local fields. */ 152533965Sjdp ret->indx = -1; 152633965Sjdp ret->dynindx = -1; 1527218822Sdim ret->got = htab->init_got_refcount; 1528218822Sdim ret->plt = htab->init_plt_refcount; 1529218822Sdim memset (&ret->size, 0, (sizeof (struct elf_link_hash_entry) 1530218822Sdim - offsetof (struct elf_link_hash_entry, size))); 153133965Sjdp /* Assume that we have been called by a non-ELF symbol reader. 1532218822Sdim This flag is then reset by the code which reads an ELF input 1533218822Sdim file. This ensures that a symbol created by a non-ELF symbol 1534218822Sdim reader will have the flag set correctly. */ 1535218822Sdim ret->non_elf = 1; 153633965Sjdp } 153733965Sjdp 153889860Sobrien return entry; 153933965Sjdp} 154033965Sjdp 154160508Sobrien/* Copy data from an indirect symbol to its direct symbol, hiding the 154289860Sobrien old indirect symbol. Also used for copying flags to a weakdef. */ 154360508Sobrien 154460508Sobrienvoid 1545218822Sdim_bfd_elf_link_hash_copy_indirect (struct bfd_link_info *info, 1546130563Sobrien struct elf_link_hash_entry *dir, 1547130563Sobrien struct elf_link_hash_entry *ind) 154860508Sobrien{ 1549218822Sdim struct elf_link_hash_table *htab; 155089860Sobrien 155160508Sobrien /* Copy down any references that we may have already seen to the 155260508Sobrien symbol which just became indirect. */ 155360508Sobrien 1554218822Sdim dir->ref_dynamic |= ind->ref_dynamic; 1555218822Sdim dir->ref_regular |= ind->ref_regular; 1556218822Sdim dir->ref_regular_nonweak |= ind->ref_regular_nonweak; 1557218822Sdim dir->non_got_ref |= ind->non_got_ref; 1558218822Sdim dir->needs_plt |= ind->needs_plt; 1559218822Sdim dir->pointer_equality_needed |= ind->pointer_equality_needed; 156060508Sobrien 156189860Sobrien if (ind->root.type != bfd_link_hash_indirect) 156289860Sobrien return; 156389860Sobrien 156489860Sobrien /* Copy over the global and procedure linkage table refcount entries. 156560508Sobrien These may have been already set up by a check_relocs routine. */ 1566218822Sdim htab = elf_hash_table (info); 1567218822Sdim if (ind->got.refcount > htab->init_got_refcount.refcount) 156860508Sobrien { 1569218822Sdim if (dir->got.refcount < 0) 1570218822Sdim dir->got.refcount = 0; 1571218822Sdim dir->got.refcount += ind->got.refcount; 1572218822Sdim ind->got.refcount = htab->init_got_refcount.refcount; 157360508Sobrien } 157460508Sobrien 1575218822Sdim if (ind->plt.refcount > htab->init_plt_refcount.refcount) 157660508Sobrien { 1577218822Sdim if (dir->plt.refcount < 0) 1578218822Sdim dir->plt.refcount = 0; 1579218822Sdim dir->plt.refcount += ind->plt.refcount; 1580218822Sdim ind->plt.refcount = htab->init_plt_refcount.refcount; 158160508Sobrien } 158260508Sobrien 1583218822Sdim if (ind->dynindx != -1) 158460508Sobrien { 1585218822Sdim if (dir->dynindx != -1) 1586218822Sdim _bfd_elf_strtab_delref (htab->dynstr, dir->dynstr_index); 158760508Sobrien dir->dynindx = ind->dynindx; 158860508Sobrien dir->dynstr_index = ind->dynstr_index; 158960508Sobrien ind->dynindx = -1; 159060508Sobrien ind->dynstr_index = 0; 159160508Sobrien } 159260508Sobrien} 159360508Sobrien 159460508Sobrienvoid 1595130563Sobrien_bfd_elf_link_hash_hide_symbol (struct bfd_link_info *info, 1596130563Sobrien struct elf_link_hash_entry *h, 1597130563Sobrien bfd_boolean force_local) 159860508Sobrien{ 1599218822Sdim h->plt = elf_hash_table (info)->init_plt_offset; 1600218822Sdim h->needs_plt = 0; 160189860Sobrien if (force_local) 160289860Sobrien { 1603218822Sdim h->forced_local = 1; 160489860Sobrien if (h->dynindx != -1) 160589860Sobrien { 160689860Sobrien h->dynindx = -1; 160789860Sobrien _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr, 160889860Sobrien h->dynstr_index); 160989860Sobrien } 161089860Sobrien } 161160508Sobrien} 161260508Sobrien 161333965Sjdp/* Initialize an ELF linker hash table. */ 161433965Sjdp 1615130563Sobrienbfd_boolean 1616130563Sobrien_bfd_elf_link_hash_table_init 1617130563Sobrien (struct elf_link_hash_table *table, 1618130563Sobrien bfd *abfd, 1619130563Sobrien struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, 1620130563Sobrien struct bfd_hash_table *, 1621218822Sdim const char *), 1622218822Sdim unsigned int entsize) 162333965Sjdp{ 1624130563Sobrien bfd_boolean ret; 1625218822Sdim int can_refcount = get_elf_backend_data (abfd)->can_refcount; 162689860Sobrien 1627218822Sdim memset (table, 0, sizeof * table); 1628218822Sdim table->init_got_refcount.refcount = can_refcount - 1; 1629218822Sdim table->init_plt_refcount.refcount = can_refcount - 1; 1630218822Sdim table->init_got_offset.offset = -(bfd_vma) 1; 1631218822Sdim table->init_plt_offset.offset = -(bfd_vma) 1; 163233965Sjdp /* The first dynamic symbol is a dummy. */ 163333965Sjdp table->dynsymcount = 1; 1634130563Sobrien 1635218822Sdim ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize); 163689860Sobrien table->root.type = bfd_link_elf_hash_table; 163789860Sobrien 163889860Sobrien return ret; 163933965Sjdp} 164033965Sjdp 164133965Sjdp/* Create an ELF linker hash table. */ 164233965Sjdp 164333965Sjdpstruct bfd_link_hash_table * 1644130563Sobrien_bfd_elf_link_hash_table_create (bfd *abfd) 164533965Sjdp{ 164633965Sjdp struct elf_link_hash_table *ret; 164789860Sobrien bfd_size_type amt = sizeof (struct elf_link_hash_table); 164833965Sjdp 1649130563Sobrien ret = bfd_malloc (amt); 1650130563Sobrien if (ret == NULL) 165133965Sjdp return NULL; 165233965Sjdp 1653218822Sdim if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc, 1654218822Sdim sizeof (struct elf_link_hash_entry))) 165533965Sjdp { 1656104838Sobrien free (ret); 165733965Sjdp return NULL; 165833965Sjdp } 165933965Sjdp 166033965Sjdp return &ret->root; 166133965Sjdp} 166233965Sjdp 166333965Sjdp/* This is a hook for the ELF emulation code in the generic linker to 166433965Sjdp tell the backend linker what file name to use for the DT_NEEDED 1665130563Sobrien entry for a dynamic object. */ 166633965Sjdp 166733965Sjdpvoid 1668130563Sobrienbfd_elf_set_dt_needed_name (bfd *abfd, const char *name) 166933965Sjdp{ 167033965Sjdp if (bfd_get_flavour (abfd) == bfd_target_elf_flavour 167133965Sjdp && bfd_get_format (abfd) == bfd_object) 167233965Sjdp elf_dt_name (abfd) = name; 167333965Sjdp} 167433965Sjdp 1675218822Sdimint 1676218822Sdimbfd_elf_get_dyn_lib_class (bfd *abfd) 1677218822Sdim{ 1678218822Sdim int lib_class; 1679218822Sdim if (bfd_get_flavour (abfd) == bfd_target_elf_flavour 1680218822Sdim && bfd_get_format (abfd) == bfd_object) 1681218822Sdim lib_class = elf_dyn_lib_class (abfd); 1682218822Sdim else 1683218822Sdim lib_class = 0; 1684218822Sdim return lib_class; 1685218822Sdim} 1686218822Sdim 168777301Sobrienvoid 1688218822Sdimbfd_elf_set_dyn_lib_class (bfd *abfd, enum dynamic_lib_link_class lib_class) 168977301Sobrien{ 169077301Sobrien if (bfd_get_flavour (abfd) == bfd_target_elf_flavour 169177301Sobrien && bfd_get_format (abfd) == bfd_object) 1692130563Sobrien elf_dyn_lib_class (abfd) = lib_class; 169377301Sobrien} 169477301Sobrien 169533965Sjdp/* Get the list of DT_NEEDED entries for a link. This is a hook for 169660508Sobrien the linker ELF emulation code. */ 169733965Sjdp 169833965Sjdpstruct bfd_link_needed_list * 1699130563Sobrienbfd_elf_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED, 1700130563Sobrien struct bfd_link_info *info) 170133965Sjdp{ 1702130563Sobrien if (! is_elf_hash_table (info->hash)) 170333965Sjdp return NULL; 170433965Sjdp return elf_hash_table (info)->needed; 170533965Sjdp} 170633965Sjdp 170777301Sobrien/* Get the list of DT_RPATH/DT_RUNPATH entries for a link. This is a 170877301Sobrien hook for the linker ELF emulation code. */ 170977301Sobrien 171077301Sobrienstruct bfd_link_needed_list * 1711130563Sobrienbfd_elf_get_runpath_list (bfd *abfd ATTRIBUTE_UNUSED, 1712130563Sobrien struct bfd_link_info *info) 171377301Sobrien{ 1714130563Sobrien if (! is_elf_hash_table (info->hash)) 171577301Sobrien return NULL; 171677301Sobrien return elf_hash_table (info)->runpath; 171777301Sobrien} 171877301Sobrien 171933965Sjdp/* Get the name actually used for a dynamic object for a link. This 172033965Sjdp is the SONAME entry if there is one. Otherwise, it is the string 172133965Sjdp passed to bfd_elf_set_dt_needed_name, or it is the filename. */ 172233965Sjdp 172333965Sjdpconst char * 1724130563Sobrienbfd_elf_get_dt_soname (bfd *abfd) 172533965Sjdp{ 172633965Sjdp if (bfd_get_flavour (abfd) == bfd_target_elf_flavour 172733965Sjdp && bfd_get_format (abfd) == bfd_object) 172833965Sjdp return elf_dt_name (abfd); 172933965Sjdp return NULL; 173033965Sjdp} 173138891Sjdp 173238891Sjdp/* Get the list of DT_NEEDED entries from a BFD. This is a hook for 173338891Sjdp the ELF linker emulation code. */ 173438891Sjdp 1735130563Sobrienbfd_boolean 1736130563Sobrienbfd_elf_get_bfd_needed_list (bfd *abfd, 1737130563Sobrien struct bfd_link_needed_list **pneeded) 173838891Sjdp{ 173938891Sjdp asection *s; 174038891Sjdp bfd_byte *dynbuf = NULL; 174138891Sjdp int elfsec; 174289860Sobrien unsigned long shlink; 174338891Sjdp bfd_byte *extdyn, *extdynend; 174438891Sjdp size_t extdynsize; 1745130563Sobrien void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); 174638891Sjdp 174738891Sjdp *pneeded = NULL; 174838891Sjdp 174938891Sjdp if (bfd_get_flavour (abfd) != bfd_target_elf_flavour 175038891Sjdp || bfd_get_format (abfd) != bfd_object) 1751130563Sobrien return TRUE; 175238891Sjdp 175338891Sjdp s = bfd_get_section_by_name (abfd, ".dynamic"); 1754218822Sdim if (s == NULL || s->size == 0) 1755130563Sobrien return TRUE; 175638891Sjdp 1757218822Sdim if (!bfd_malloc_and_get_section (abfd, s, &dynbuf)) 175838891Sjdp goto error_return; 175938891Sjdp 176038891Sjdp elfsec = _bfd_elf_section_from_bfd_section (abfd, s); 176138891Sjdp if (elfsec == -1) 176238891Sjdp goto error_return; 176338891Sjdp 176489860Sobrien shlink = elf_elfsections (abfd)[elfsec]->sh_link; 176538891Sjdp 176638891Sjdp extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn; 176738891Sjdp swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in; 176838891Sjdp 176938891Sjdp extdyn = dynbuf; 1770218822Sdim extdynend = extdyn + s->size; 177138891Sjdp for (; extdyn < extdynend; extdyn += extdynsize) 177238891Sjdp { 177338891Sjdp Elf_Internal_Dyn dyn; 177438891Sjdp 1775130563Sobrien (*swap_dyn_in) (abfd, extdyn, &dyn); 177638891Sjdp 177738891Sjdp if (dyn.d_tag == DT_NULL) 177838891Sjdp break; 177938891Sjdp 178038891Sjdp if (dyn.d_tag == DT_NEEDED) 178138891Sjdp { 178238891Sjdp const char *string; 178338891Sjdp struct bfd_link_needed_list *l; 178489860Sobrien unsigned int tagv = dyn.d_un.d_val; 178589860Sobrien bfd_size_type amt; 178638891Sjdp 178789860Sobrien string = bfd_elf_string_from_elf_section (abfd, shlink, tagv); 178838891Sjdp if (string == NULL) 178938891Sjdp goto error_return; 179038891Sjdp 179189860Sobrien amt = sizeof *l; 1792130563Sobrien l = bfd_alloc (abfd, amt); 179338891Sjdp if (l == NULL) 179438891Sjdp goto error_return; 179538891Sjdp 179638891Sjdp l->by = abfd; 179738891Sjdp l->name = string; 179838891Sjdp l->next = *pneeded; 179938891Sjdp *pneeded = l; 180038891Sjdp } 180138891Sjdp } 180238891Sjdp 180338891Sjdp free (dynbuf); 180438891Sjdp 1805130563Sobrien return TRUE; 180638891Sjdp 180738891Sjdp error_return: 180838891Sjdp if (dynbuf != NULL) 180938891Sjdp free (dynbuf); 1810130563Sobrien return FALSE; 181138891Sjdp} 181233965Sjdp 181333965Sjdp/* Allocate an ELF string table--force the first byte to be zero. */ 181433965Sjdp 181533965Sjdpstruct bfd_strtab_hash * 1816130563Sobrien_bfd_elf_stringtab_init (void) 181733965Sjdp{ 181833965Sjdp struct bfd_strtab_hash *ret; 181933965Sjdp 182033965Sjdp ret = _bfd_stringtab_init (); 182133965Sjdp if (ret != NULL) 182233965Sjdp { 182333965Sjdp bfd_size_type loc; 182433965Sjdp 1825130563Sobrien loc = _bfd_stringtab_add (ret, "", TRUE, FALSE); 182633965Sjdp BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1); 182733965Sjdp if (loc == (bfd_size_type) -1) 182833965Sjdp { 182933965Sjdp _bfd_stringtab_free (ret); 183033965Sjdp ret = NULL; 183133965Sjdp } 183233965Sjdp } 183333965Sjdp return ret; 183433965Sjdp} 183533965Sjdp 183633965Sjdp/* ELF .o/exec file reading */ 183733965Sjdp 183877301Sobrien/* Create a new bfd section from an ELF section header. */ 183933965Sjdp 1840130563Sobrienbfd_boolean 1841130563Sobrienbfd_section_from_shdr (bfd *abfd, unsigned int shindex) 184233965Sjdp{ 184333965Sjdp Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex]; 184433965Sjdp Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd); 1845130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 1846104838Sobrien const char *name; 184733965Sjdp 1848218822Sdim name = bfd_elf_string_from_elf_section (abfd, 1849218822Sdim elf_elfheader (abfd)->e_shstrndx, 1850218822Sdim hdr->sh_name); 1851218822Sdim if (name == NULL) 1852218822Sdim return FALSE; 185333965Sjdp 185433965Sjdp switch (hdr->sh_type) 185533965Sjdp { 185633965Sjdp case SHT_NULL: 185733965Sjdp /* Inactive section. Throw it away. */ 1858130563Sobrien return TRUE; 185933965Sjdp 186033965Sjdp case SHT_PROGBITS: /* Normal section with contents. */ 186133965Sjdp case SHT_NOBITS: /* .bss section. */ 186233965Sjdp case SHT_HASH: /* .hash section. */ 186333965Sjdp case SHT_NOTE: /* .note section. */ 186494542Sobrien case SHT_INIT_ARRAY: /* .init_array section. */ 186594542Sobrien case SHT_FINI_ARRAY: /* .fini_array section. */ 186694542Sobrien case SHT_PREINIT_ARRAY: /* .preinit_array section. */ 1867218822Sdim case SHT_GNU_LIBLIST: /* .gnu.liblist section. */ 1868218822Sdim case SHT_GNU_HASH: /* .gnu.hash section. */ 1869218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); 187033965Sjdp 1871104838Sobrien case SHT_DYNAMIC: /* Dynamic linking information. */ 1872218822Sdim if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) 1873130563Sobrien return FALSE; 1874218822Sdim if (hdr->sh_link > elf_numsections (abfd) 1875218822Sdim || elf_elfsections (abfd)[hdr->sh_link] == NULL) 1876218822Sdim return FALSE; 1877104838Sobrien if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB) 1878104838Sobrien { 1879104838Sobrien Elf_Internal_Shdr *dynsymhdr; 1880104838Sobrien 1881104838Sobrien /* The shared libraries distributed with hpux11 have a bogus 1882104838Sobrien sh_link field for the ".dynamic" section. Find the 1883104838Sobrien string table for the ".dynsym" section instead. */ 1884104838Sobrien if (elf_dynsymtab (abfd) != 0) 1885104838Sobrien { 1886104838Sobrien dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)]; 1887104838Sobrien hdr->sh_link = dynsymhdr->sh_link; 1888104838Sobrien } 1889104838Sobrien else 1890104838Sobrien { 1891104838Sobrien unsigned int i, num_sec; 1892104838Sobrien 1893104838Sobrien num_sec = elf_numsections (abfd); 1894104838Sobrien for (i = 1; i < num_sec; i++) 1895104838Sobrien { 1896104838Sobrien dynsymhdr = elf_elfsections (abfd)[i]; 1897104838Sobrien if (dynsymhdr->sh_type == SHT_DYNSYM) 1898104838Sobrien { 1899104838Sobrien hdr->sh_link = dynsymhdr->sh_link; 1900104838Sobrien break; 1901104838Sobrien } 1902104838Sobrien } 1903104838Sobrien } 1904104838Sobrien } 1905104838Sobrien break; 1906104838Sobrien 190733965Sjdp case SHT_SYMTAB: /* A symbol table */ 190833965Sjdp if (elf_onesymtab (abfd) == shindex) 1909130563Sobrien return TRUE; 191033965Sjdp 1911218822Sdim if (hdr->sh_entsize != bed->s->sizeof_sym) 1912218822Sdim return FALSE; 191333965Sjdp BFD_ASSERT (elf_onesymtab (abfd) == 0); 191433965Sjdp elf_onesymtab (abfd) = shindex; 191533965Sjdp elf_tdata (abfd)->symtab_hdr = *hdr; 191633965Sjdp elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr; 191733965Sjdp abfd->flags |= HAS_SYMS; 191833965Sjdp 191933965Sjdp /* Sometimes a shared object will map in the symbol table. If 1920218822Sdim SHF_ALLOC is set, and this is a shared object, then we also 1921218822Sdim treat this section as a BFD section. We can not base the 1922218822Sdim decision purely on SHF_ALLOC, because that flag is sometimes 1923218822Sdim set in a relocatable object file, which would confuse the 1924218822Sdim linker. */ 192533965Sjdp if ((hdr->sh_flags & SHF_ALLOC) != 0 192633965Sjdp && (abfd->flags & DYNAMIC) != 0 1927218822Sdim && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name, 1928218822Sdim shindex)) 1929130563Sobrien return FALSE; 193033965Sjdp 1931218822Sdim /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we 1932218822Sdim can't read symbols without that section loaded as well. It 1933218822Sdim is most likely specified by the next section header. */ 1934218822Sdim if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex) 1935218822Sdim { 1936218822Sdim unsigned int i, num_sec; 1937218822Sdim 1938218822Sdim num_sec = elf_numsections (abfd); 1939218822Sdim for (i = shindex + 1; i < num_sec; i++) 1940218822Sdim { 1941218822Sdim Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; 1942218822Sdim if (hdr2->sh_type == SHT_SYMTAB_SHNDX 1943218822Sdim && hdr2->sh_link == shindex) 1944218822Sdim break; 1945218822Sdim } 1946218822Sdim if (i == num_sec) 1947218822Sdim for (i = 1; i < shindex; i++) 1948218822Sdim { 1949218822Sdim Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; 1950218822Sdim if (hdr2->sh_type == SHT_SYMTAB_SHNDX 1951218822Sdim && hdr2->sh_link == shindex) 1952218822Sdim break; 1953218822Sdim } 1954218822Sdim if (i != shindex) 1955218822Sdim return bfd_section_from_shdr (abfd, i); 1956218822Sdim } 1957130563Sobrien return TRUE; 195833965Sjdp 195933965Sjdp case SHT_DYNSYM: /* A dynamic symbol table */ 196033965Sjdp if (elf_dynsymtab (abfd) == shindex) 1961130563Sobrien return TRUE; 196233965Sjdp 1963218822Sdim if (hdr->sh_entsize != bed->s->sizeof_sym) 1964218822Sdim return FALSE; 196533965Sjdp BFD_ASSERT (elf_dynsymtab (abfd) == 0); 196633965Sjdp elf_dynsymtab (abfd) = shindex; 196733965Sjdp elf_tdata (abfd)->dynsymtab_hdr = *hdr; 196833965Sjdp elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr; 196933965Sjdp abfd->flags |= HAS_SYMS; 197033965Sjdp 197133965Sjdp /* Besides being a symbol table, we also treat this as a regular 197233965Sjdp section, so that objcopy can handle it. */ 1973218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); 197433965Sjdp 197589860Sobrien case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections */ 197689860Sobrien if (elf_symtab_shndx (abfd) == shindex) 1977130563Sobrien return TRUE; 197889860Sobrien 1979218822Sdim BFD_ASSERT (elf_symtab_shndx (abfd) == 0); 198089860Sobrien elf_symtab_shndx (abfd) = shindex; 198189860Sobrien elf_tdata (abfd)->symtab_shndx_hdr = *hdr; 198289860Sobrien elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr; 1983130563Sobrien return TRUE; 198489860Sobrien 198533965Sjdp case SHT_STRTAB: /* A string table */ 198633965Sjdp if (hdr->bfd_section != NULL) 1987130563Sobrien return TRUE; 198833965Sjdp if (ehdr->e_shstrndx == shindex) 198933965Sjdp { 199033965Sjdp elf_tdata (abfd)->shstrtab_hdr = *hdr; 199133965Sjdp elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr; 1992130563Sobrien return TRUE; 199333965Sjdp } 1994218822Sdim if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex) 1995218822Sdim { 1996218822Sdim symtab_strtab: 1997218822Sdim elf_tdata (abfd)->strtab_hdr = *hdr; 1998218822Sdim elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr; 1999218822Sdim return TRUE; 2000218822Sdim } 2001218822Sdim if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex) 2002218822Sdim { 2003218822Sdim dynsymtab_strtab: 2004218822Sdim elf_tdata (abfd)->dynstrtab_hdr = *hdr; 2005218822Sdim hdr = &elf_tdata (abfd)->dynstrtab_hdr; 2006218822Sdim elf_elfsections (abfd)[shindex] = hdr; 2007218822Sdim /* We also treat this as a regular section, so that objcopy 2008218822Sdim can handle it. */ 2009218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, 2010218822Sdim shindex); 2011218822Sdim } 201233965Sjdp 2013218822Sdim /* If the string table isn't one of the above, then treat it as a 2014218822Sdim regular section. We need to scan all the headers to be sure, 2015218822Sdim just in case this strtab section appeared before the above. */ 2016218822Sdim if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0) 2017218822Sdim { 2018218822Sdim unsigned int i, num_sec; 201933965Sjdp 2020218822Sdim num_sec = elf_numsections (abfd); 2021218822Sdim for (i = 1; i < num_sec; i++) 2022218822Sdim { 2023218822Sdim Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; 2024218822Sdim if (hdr2->sh_link == shindex) 2025218822Sdim { 2026218822Sdim /* Prevent endless recursion on broken objects. */ 2027218822Sdim if (i == shindex) 2028218822Sdim return FALSE; 2029218822Sdim if (! bfd_section_from_shdr (abfd, i)) 2030218822Sdim return FALSE; 2031218822Sdim if (elf_onesymtab (abfd) == i) 2032218822Sdim goto symtab_strtab; 2033218822Sdim if (elf_dynsymtab (abfd) == i) 2034218822Sdim goto dynsymtab_strtab; 2035218822Sdim } 2036218822Sdim } 2037218822Sdim } 2038218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); 203933965Sjdp 204033965Sjdp case SHT_REL: 204133965Sjdp case SHT_RELA: 204233965Sjdp /* *These* do a lot of work -- but build no sections! */ 204333965Sjdp { 204433965Sjdp asection *target_sect; 204533965Sjdp Elf_Internal_Shdr *hdr2; 204689860Sobrien unsigned int num_sec = elf_numsections (abfd); 204733965Sjdp 2048218822Sdim if (hdr->sh_entsize 2049218822Sdim != (bfd_size_type) (hdr->sh_type == SHT_REL 2050218822Sdim ? bed->s->sizeof_rel : bed->s->sizeof_rela)) 2051218822Sdim return FALSE; 2052218822Sdim 205360508Sobrien /* Check for a bogus link to avoid crashing. */ 205489860Sobrien if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE) 205589860Sobrien || hdr->sh_link >= num_sec) 205660508Sobrien { 205760508Sobrien ((*_bfd_error_handler) 2058218822Sdim (_("%B: invalid link %lu for reloc section %s (index %u)"), 2059218822Sdim abfd, hdr->sh_link, name, shindex)); 2060218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, 2061218822Sdim shindex); 206260508Sobrien } 206360508Sobrien 206433965Sjdp /* For some incomprehensible reason Oracle distributes 206533965Sjdp libraries for Solaris in which some of the objects have 206633965Sjdp bogus sh_link fields. It would be nice if we could just 206733965Sjdp reject them, but, unfortunately, some people need to use 206833965Sjdp them. We scan through the section headers; if we find only 206933965Sjdp one suitable symbol table, we clobber the sh_link to point 207033965Sjdp to it. I hope this doesn't break anything. */ 207133965Sjdp if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB 207233965Sjdp && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM) 207333965Sjdp { 207489860Sobrien unsigned int scan; 207533965Sjdp int found; 207633965Sjdp 207733965Sjdp found = 0; 207889860Sobrien for (scan = 1; scan < num_sec; scan++) 207933965Sjdp { 208033965Sjdp if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB 208133965Sjdp || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM) 208233965Sjdp { 208333965Sjdp if (found != 0) 208433965Sjdp { 208533965Sjdp found = 0; 208633965Sjdp break; 208733965Sjdp } 208833965Sjdp found = scan; 208933965Sjdp } 209033965Sjdp } 209133965Sjdp if (found != 0) 209233965Sjdp hdr->sh_link = found; 209333965Sjdp } 209433965Sjdp 209533965Sjdp /* Get the symbol table. */ 2096218822Sdim if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB 2097218822Sdim || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM) 209833965Sjdp && ! bfd_section_from_shdr (abfd, hdr->sh_link)) 2099130563Sobrien return FALSE; 210033965Sjdp 210133965Sjdp /* If this reloc section does not use the main symbol table we 210233965Sjdp don't treat it as a reloc section. BFD can't adequately 210333965Sjdp represent such a section, so at least for now, we don't 210477301Sobrien try. We just present it as a normal section. We also 210577301Sobrien can't use it as a reloc section if it points to the null 2106218822Sdim section, an invalid section, or another reloc section. */ 2107218822Sdim if (hdr->sh_link != elf_onesymtab (abfd) 2108218822Sdim || hdr->sh_info == SHN_UNDEF 2109218822Sdim || (hdr->sh_info >= SHN_LORESERVE && hdr->sh_info <= SHN_HIRESERVE) 2110218822Sdim || hdr->sh_info >= num_sec 2111218822Sdim || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL 2112218822Sdim || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA) 2113218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, 2114218822Sdim shindex); 211533965Sjdp 211633965Sjdp if (! bfd_section_from_shdr (abfd, hdr->sh_info)) 2117130563Sobrien return FALSE; 211833965Sjdp target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info); 211933965Sjdp if (target_sect == NULL) 2120130563Sobrien return FALSE; 212133965Sjdp 212233965Sjdp if ((target_sect->flags & SEC_RELOC) == 0 212333965Sjdp || target_sect->reloc_count == 0) 212433965Sjdp hdr2 = &elf_section_data (target_sect)->rel_hdr; 212533965Sjdp else 212633965Sjdp { 212789860Sobrien bfd_size_type amt; 212833965Sjdp BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL); 212989860Sobrien amt = sizeof (*hdr2); 2130130563Sobrien hdr2 = bfd_alloc (abfd, amt); 213133965Sjdp elf_section_data (target_sect)->rel_hdr2 = hdr2; 213233965Sjdp } 213333965Sjdp *hdr2 = *hdr; 213433965Sjdp elf_elfsections (abfd)[shindex] = hdr2; 213578831Sobrien target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr); 213633965Sjdp target_sect->flags |= SEC_RELOC; 213733965Sjdp target_sect->relocation = NULL; 213833965Sjdp target_sect->rel_filepos = hdr->sh_offset; 213960508Sobrien /* In the section to which the relocations apply, mark whether 214060508Sobrien its relocations are of the REL or RELA variety. */ 214160508Sobrien if (hdr->sh_size != 0) 2142130563Sobrien target_sect->use_rela_p = hdr->sh_type == SHT_RELA; 214333965Sjdp abfd->flags |= HAS_RELOC; 2144130563Sobrien return TRUE; 214533965Sjdp } 214633965Sjdp 214733965Sjdp case SHT_GNU_verdef: 214833965Sjdp elf_dynverdef (abfd) = shindex; 214933965Sjdp elf_tdata (abfd)->dynverdef_hdr = *hdr; 2150218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); 215133965Sjdp 215233965Sjdp case SHT_GNU_versym: 2153218822Sdim if (hdr->sh_entsize != sizeof (Elf_External_Versym)) 2154218822Sdim return FALSE; 215533965Sjdp elf_dynversym (abfd) = shindex; 215633965Sjdp elf_tdata (abfd)->dynversym_hdr = *hdr; 2157218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); 215833965Sjdp 215933965Sjdp case SHT_GNU_verneed: 216033965Sjdp elf_dynverref (abfd) = shindex; 216133965Sjdp elf_tdata (abfd)->dynverref_hdr = *hdr; 2162218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); 216333965Sjdp 216433965Sjdp case SHT_SHLIB: 2165130563Sobrien return TRUE; 216633965Sjdp 216789860Sobrien case SHT_GROUP: 2168104838Sobrien /* We need a BFD section for objcopy and relocatable linking, 2169104838Sobrien and it's handy to have the signature available as the section 2170104838Sobrien name. */ 2171218822Sdim if (! IS_VALID_GROUP_SECTION_HEADER (hdr)) 2172218822Sdim return FALSE; 2173104838Sobrien name = group_signature (abfd, hdr); 2174104838Sobrien if (name == NULL) 2175130563Sobrien return FALSE; 2176218822Sdim if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) 2177130563Sobrien return FALSE; 217889860Sobrien if (hdr->contents != NULL) 217989860Sobrien { 218089860Sobrien Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents; 2181218822Sdim unsigned int n_elt = hdr->sh_size / GRP_ENTRY_SIZE; 218289860Sobrien asection *s; 218389860Sobrien 2184104838Sobrien if (idx->flags & GRP_COMDAT) 2185104838Sobrien hdr->bfd_section->flags 2186104838Sobrien |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; 2187104838Sobrien 2188218822Sdim /* We try to keep the same section order as it comes in. */ 2189218822Sdim idx += n_elt; 219089860Sobrien while (--n_elt != 0) 2191218822Sdim { 2192218822Sdim --idx; 2193218822Sdim 2194218822Sdim if (idx->shdr != NULL 2195218822Sdim && (s = idx->shdr->bfd_section) != NULL 2196218822Sdim && elf_next_in_group (s) != NULL) 2197218822Sdim { 2198218822Sdim elf_next_in_group (hdr->bfd_section) = s; 2199218822Sdim break; 2200218822Sdim } 2201218822Sdim } 220289860Sobrien } 220389860Sobrien break; 220489860Sobrien 220533965Sjdp default: 2206218822Sdim /* Possibly an attributes section. */ 2207218822Sdim if (hdr->sh_type == SHT_GNU_ATTRIBUTES 2208218822Sdim || hdr->sh_type == bed->obj_attrs_section_type) 2209218822Sdim { 2210218822Sdim if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) 2211218822Sdim return FALSE; 2212218822Sdim _bfd_elf_parse_attributes (abfd, hdr); 2213218822Sdim return TRUE; 2214218822Sdim } 2215218822Sdim 221633965Sjdp /* Check for any processor-specific section types. */ 2217218822Sdim if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex)) 2218218822Sdim return TRUE; 2219218822Sdim 2220218822Sdim if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER) 2221218822Sdim { 2222218822Sdim if ((hdr->sh_flags & SHF_ALLOC) != 0) 2223218822Sdim /* FIXME: How to properly handle allocated section reserved 2224218822Sdim for applications? */ 2225218822Sdim (*_bfd_error_handler) 2226218822Sdim (_("%B: don't know how to handle allocated, application " 2227218822Sdim "specific section `%s' [0x%8x]"), 2228218822Sdim abfd, name, hdr->sh_type); 2229218822Sdim else 2230218822Sdim /* Allow sections reserved for applications. */ 2231218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, 2232218822Sdim shindex); 2233218822Sdim } 2234218822Sdim else if (hdr->sh_type >= SHT_LOPROC 2235218822Sdim && hdr->sh_type <= SHT_HIPROC) 2236218822Sdim /* FIXME: We should handle this section. */ 2237218822Sdim (*_bfd_error_handler) 2238218822Sdim (_("%B: don't know how to handle processor specific section " 2239218822Sdim "`%s' [0x%8x]"), 2240218822Sdim abfd, name, hdr->sh_type); 2241218822Sdim else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS) 2242218822Sdim { 2243218822Sdim /* Unrecognised OS-specific sections. */ 2244218822Sdim if ((hdr->sh_flags & SHF_OS_NONCONFORMING) != 0) 2245218822Sdim /* SHF_OS_NONCONFORMING indicates that special knowledge is 2246218822Sdim required to correctly process the section and the file should 2247218822Sdim be rejected with an error message. */ 2248218822Sdim (*_bfd_error_handler) 2249218822Sdim (_("%B: don't know how to handle OS specific section " 2250218822Sdim "`%s' [0x%8x]"), 2251218822Sdim abfd, name, hdr->sh_type); 2252218822Sdim else 2253218822Sdim /* Otherwise it should be processed. */ 2254218822Sdim return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); 2255218822Sdim } 2256218822Sdim else 2257218822Sdim /* FIXME: We should handle this section. */ 2258218822Sdim (*_bfd_error_handler) 2259218822Sdim (_("%B: don't know how to handle section `%s' [0x%8x]"), 2260218822Sdim abfd, name, hdr->sh_type); 2261218822Sdim 2262218822Sdim return FALSE; 226333965Sjdp } 226433965Sjdp 2265130563Sobrien return TRUE; 226633965Sjdp} 226733965Sjdp 226889860Sobrien/* Return the section for the local symbol specified by ABFD, R_SYMNDX. 226989860Sobrien Return SEC for sections that have no elf section, and NULL on error. */ 227089860Sobrien 227189860Sobrienasection * 2272130563Sobrienbfd_section_from_r_symndx (bfd *abfd, 2273130563Sobrien struct sym_sec_cache *cache, 2274130563Sobrien asection *sec, 2275130563Sobrien unsigned long r_symndx) 227689860Sobrien{ 227789860Sobrien Elf_Internal_Shdr *symtab_hdr; 2278104838Sobrien unsigned char esym[sizeof (Elf64_External_Sym)]; 2279104838Sobrien Elf_External_Sym_Shndx eshndx; 2280104838Sobrien Elf_Internal_Sym isym; 228189860Sobrien unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE; 228289860Sobrien 228389860Sobrien if (cache->abfd == abfd && cache->indx[ent] == r_symndx) 228489860Sobrien return cache->sec[ent]; 228589860Sobrien 228689860Sobrien symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 2287104838Sobrien if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx, 2288104838Sobrien &isym, esym, &eshndx) == NULL) 228989860Sobrien return NULL; 229089860Sobrien 229189860Sobrien if (cache->abfd != abfd) 229289860Sobrien { 229389860Sobrien memset (cache->indx, -1, sizeof (cache->indx)); 229489860Sobrien cache->abfd = abfd; 229589860Sobrien } 229689860Sobrien cache->indx[ent] = r_symndx; 229789860Sobrien cache->sec[ent] = sec; 2298130563Sobrien if ((isym.st_shndx != SHN_UNDEF && isym.st_shndx < SHN_LORESERVE) 2299130563Sobrien || isym.st_shndx > SHN_HIRESERVE) 230089860Sobrien { 230189860Sobrien asection *s; 2302104838Sobrien s = bfd_section_from_elf_index (abfd, isym.st_shndx); 230389860Sobrien if (s != NULL) 230489860Sobrien cache->sec[ent] = s; 230589860Sobrien } 230689860Sobrien return cache->sec[ent]; 230789860Sobrien} 230889860Sobrien 230933965Sjdp/* Given an ELF section number, retrieve the corresponding BFD 231033965Sjdp section. */ 231133965Sjdp 231233965Sjdpasection * 2313130563Sobrienbfd_section_from_elf_index (bfd *abfd, unsigned int index) 231433965Sjdp{ 231589860Sobrien if (index >= elf_numsections (abfd)) 231633965Sjdp return NULL; 231733965Sjdp return elf_elfsections (abfd)[index]->bfd_section; 231833965Sjdp} 231933965Sjdp 2320218822Sdimstatic const struct bfd_elf_special_section special_sections_b[] = 232133965Sjdp{ 2322218822Sdim { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, 2323218822Sdim { NULL, 0, 0, 0, 0 } 2324130563Sobrien}; 2325130563Sobrien 2326218822Sdimstatic const struct bfd_elf_special_section special_sections_c[] = 2327130563Sobrien{ 2328218822Sdim { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 }, 2329218822Sdim { NULL, 0, 0, 0, 0 } 2330218822Sdim}; 2331218822Sdim 2332218822Sdimstatic const struct bfd_elf_special_section special_sections_d[] = 2333218822Sdim{ 2334218822Sdim { STRING_COMMA_LEN (".data"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 2335218822Sdim { STRING_COMMA_LEN (".data1"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 2336218822Sdim { STRING_COMMA_LEN (".debug"), 0, SHT_PROGBITS, 0 }, 2337218822Sdim { STRING_COMMA_LEN (".debug_line"), 0, SHT_PROGBITS, 0 }, 2338218822Sdim { STRING_COMMA_LEN (".debug_info"), 0, SHT_PROGBITS, 0 }, 2339218822Sdim { STRING_COMMA_LEN (".debug_abbrev"), 0, SHT_PROGBITS, 0 }, 2340218822Sdim { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 }, 2341218822Sdim { STRING_COMMA_LEN (".dynamic"), 0, SHT_DYNAMIC, SHF_ALLOC }, 2342218822Sdim { STRING_COMMA_LEN (".dynstr"), 0, SHT_STRTAB, SHF_ALLOC }, 2343218822Sdim { STRING_COMMA_LEN (".dynsym"), 0, SHT_DYNSYM, SHF_ALLOC }, 2344218822Sdim { NULL, 0, 0, 0, 0 } 2345218822Sdim}; 2346218822Sdim 2347218822Sdimstatic const struct bfd_elf_special_section special_sections_f[] = 2348218822Sdim{ 2349218822Sdim { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, 2350218822Sdim { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE }, 2351218822Sdim { NULL, 0, 0, 0, 0 } 2352218822Sdim}; 2353218822Sdim 2354218822Sdimstatic const struct bfd_elf_special_section special_sections_g[] = 2355218822Sdim{ 2356218822Sdim { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, 2357218822Sdim { STRING_COMMA_LEN (".got"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 2358218822Sdim { STRING_COMMA_LEN (".gnu.version"), 0, SHT_GNU_versym, 0 }, 2359218822Sdim { STRING_COMMA_LEN (".gnu.version_d"), 0, SHT_GNU_verdef, 0 }, 2360218822Sdim { STRING_COMMA_LEN (".gnu.version_r"), 0, SHT_GNU_verneed, 0 }, 2361218822Sdim { STRING_COMMA_LEN (".gnu.liblist"), 0, SHT_GNU_LIBLIST, SHF_ALLOC }, 2362218822Sdim { STRING_COMMA_LEN (".gnu.conflict"), 0, SHT_RELA, SHF_ALLOC }, 2363218822Sdim { STRING_COMMA_LEN (".gnu.hash"), 0, SHT_GNU_HASH, SHF_ALLOC }, 2364218822Sdim { NULL, 0, 0, 0, 0 } 2365218822Sdim}; 2366218822Sdim 2367218822Sdimstatic const struct bfd_elf_special_section special_sections_h[] = 2368218822Sdim{ 2369218822Sdim { STRING_COMMA_LEN (".hash"), 0, SHT_HASH, SHF_ALLOC }, 2370218822Sdim { NULL, 0, 0, 0, 0 } 2371218822Sdim}; 2372218822Sdim 2373218822Sdimstatic const struct bfd_elf_special_section special_sections_i[] = 2374218822Sdim{ 2375218822Sdim { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, 2376218822Sdim { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE }, 2377218822Sdim { STRING_COMMA_LEN (".interp"), 0, SHT_PROGBITS, 0 }, 2378218822Sdim { NULL, 0, 0, 0, 0 } 2379218822Sdim}; 2380218822Sdim 2381218822Sdimstatic const struct bfd_elf_special_section special_sections_l[] = 2382218822Sdim{ 2383218822Sdim { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 }, 2384218822Sdim { NULL, 0, 0, 0, 0 } 2385218822Sdim}; 2386218822Sdim 2387218822Sdimstatic const struct bfd_elf_special_section special_sections_n[] = 2388218822Sdim{ 2389218822Sdim { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 }, 2390218822Sdim { STRING_COMMA_LEN (".note"), -1, SHT_NOTE, 0 }, 2391218822Sdim { NULL, 0, 0, 0, 0 } 2392218822Sdim}; 2393218822Sdim 2394218822Sdimstatic const struct bfd_elf_special_section special_sections_p[] = 2395218822Sdim{ 2396218822Sdim { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE }, 2397218822Sdim { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, 2398218822Sdim { NULL, 0, 0, 0, 0 } 2399218822Sdim}; 2400218822Sdim 2401218822Sdimstatic const struct bfd_elf_special_section special_sections_r[] = 2402218822Sdim{ 2403218822Sdim { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC }, 2404218822Sdim { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC }, 2405218822Sdim { STRING_COMMA_LEN (".rela"), -1, SHT_RELA, 0 }, 2406218822Sdim { STRING_COMMA_LEN (".rel"), -1, SHT_REL, 0 }, 2407218822Sdim { NULL, 0, 0, 0, 0 } 2408218822Sdim}; 2409218822Sdim 2410218822Sdimstatic const struct bfd_elf_special_section special_sections_s[] = 2411218822Sdim{ 2412218822Sdim { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 }, 2413218822Sdim { STRING_COMMA_LEN (".strtab"), 0, SHT_STRTAB, 0 }, 2414218822Sdim { STRING_COMMA_LEN (".symtab"), 0, SHT_SYMTAB, 0 }, 2415218822Sdim /* See struct bfd_elf_special_section declaration for the semantics of 2416218822Sdim this special case where .prefix_length != strlen (.prefix). */ 2417218822Sdim { ".stabstr", 5, 3, SHT_STRTAB, 0 }, 2418218822Sdim { NULL, 0, 0, 0, 0 } 2419218822Sdim}; 2420218822Sdim 2421218822Sdimstatic const struct bfd_elf_special_section special_sections_t[] = 2422218822Sdim{ 2423218822Sdim { STRING_COMMA_LEN (".text"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, 2424218822Sdim { STRING_COMMA_LEN (".tbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, 2425218822Sdim { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, 2426218822Sdim { NULL, 0, 0, 0, 0 } 2427218822Sdim}; 2428218822Sdim 2429218822Sdimstatic const struct bfd_elf_special_section *special_sections[] = 2430218822Sdim{ 2431218822Sdim special_sections_b, /* 'b' */ 2432218822Sdim special_sections_c, /* 'b' */ 2433218822Sdim special_sections_d, /* 'd' */ 2434218822Sdim NULL, /* 'e' */ 2435218822Sdim special_sections_f, /* 'f' */ 2436218822Sdim special_sections_g, /* 'g' */ 2437218822Sdim special_sections_h, /* 'h' */ 2438218822Sdim special_sections_i, /* 'i' */ 2439218822Sdim NULL, /* 'j' */ 2440218822Sdim NULL, /* 'k' */ 2441218822Sdim special_sections_l, /* 'l' */ 2442218822Sdim NULL, /* 'm' */ 2443218822Sdim special_sections_n, /* 'n' */ 2444218822Sdim NULL, /* 'o' */ 2445218822Sdim special_sections_p, /* 'p' */ 2446218822Sdim NULL, /* 'q' */ 2447218822Sdim special_sections_r, /* 'r' */ 2448218822Sdim special_sections_s, /* 's' */ 2449218822Sdim special_sections_t, /* 't' */ 2450218822Sdim}; 2451218822Sdim 2452218822Sdimconst struct bfd_elf_special_section * 2453218822Sdim_bfd_elf_get_special_section (const char *name, 2454218822Sdim const struct bfd_elf_special_section *spec, 2455218822Sdim unsigned int rela) 2456218822Sdim{ 2457130563Sobrien int i; 2458218822Sdim int len; 2459130563Sobrien 2460218822Sdim len = strlen (name); 2461218822Sdim 2462218822Sdim for (i = 0; spec[i].prefix != NULL; i++) 2463130563Sobrien { 2464130563Sobrien int suffix_len; 2465218822Sdim int prefix_len = spec[i].prefix_length; 2466130563Sobrien 2467130563Sobrien if (len < prefix_len) 2468130563Sobrien continue; 2469218822Sdim if (memcmp (name, spec[i].prefix, prefix_len) != 0) 2470130563Sobrien continue; 2471130563Sobrien 2472218822Sdim suffix_len = spec[i].suffix_length; 2473130563Sobrien if (suffix_len <= 0) 2474130563Sobrien { 2475130563Sobrien if (name[prefix_len] != 0) 2476130563Sobrien { 2477130563Sobrien if (suffix_len == 0) 2478130563Sobrien continue; 2479130563Sobrien if (name[prefix_len] != '.' 2480130563Sobrien && (suffix_len == -2 2481218822Sdim || (rela && spec[i].type == SHT_REL))) 2482130563Sobrien continue; 2483130563Sobrien } 2484130563Sobrien } 2485130563Sobrien else 2486130563Sobrien { 2487130563Sobrien if (len < prefix_len + suffix_len) 2488130563Sobrien continue; 2489130563Sobrien if (memcmp (name + len - suffix_len, 2490218822Sdim spec[i].prefix + prefix_len, 2491130563Sobrien suffix_len) != 0) 2492130563Sobrien continue; 2493130563Sobrien } 2494218822Sdim return &spec[i]; 2495130563Sobrien } 2496130563Sobrien 2497130563Sobrien return NULL; 2498130563Sobrien} 2499130563Sobrien 2500130563Sobrienconst struct bfd_elf_special_section * 2501218822Sdim_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec) 2502130563Sobrien{ 2503218822Sdim int i; 2504218822Sdim const struct bfd_elf_special_section *spec; 2505218822Sdim const struct elf_backend_data *bed; 2506130563Sobrien 2507130563Sobrien /* See if this is one of the special sections. */ 2508218822Sdim if (sec->name == NULL) 2509218822Sdim return NULL; 2510218822Sdim 2511218822Sdim bed = get_elf_backend_data (abfd); 2512218822Sdim spec = bed->special_sections; 2513218822Sdim if (spec) 2514130563Sobrien { 2515218822Sdim spec = _bfd_elf_get_special_section (sec->name, 2516218822Sdim bed->special_sections, 2517218822Sdim sec->use_rela_p); 2518218822Sdim if (spec != NULL) 2519218822Sdim return spec; 2520218822Sdim } 2521130563Sobrien 2522218822Sdim if (sec->name[0] != '.') 2523218822Sdim return NULL; 2524130563Sobrien 2525218822Sdim i = sec->name[1] - 'b'; 2526218822Sdim if (i < 0 || i > 't' - 'b') 2527218822Sdim return NULL; 2528130563Sobrien 2529218822Sdim spec = special_sections[i]; 2530218822Sdim 2531218822Sdim if (spec == NULL) 2532218822Sdim return NULL; 2533218822Sdim 2534218822Sdim return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p); 2535130563Sobrien} 2536130563Sobrien 2537130563Sobrienbfd_boolean 2538130563Sobrien_bfd_elf_new_section_hook (bfd *abfd, asection *sec) 2539130563Sobrien{ 254033965Sjdp struct bfd_elf_section_data *sdata; 2541218822Sdim const struct elf_backend_data *bed; 2542130563Sobrien const struct bfd_elf_special_section *ssect; 254333965Sjdp 2544130563Sobrien sdata = (struct bfd_elf_section_data *) sec->used_by_bfd; 2545130563Sobrien if (sdata == NULL) 2546130563Sobrien { 2547130563Sobrien sdata = bfd_zalloc (abfd, sizeof (*sdata)); 2548130563Sobrien if (sdata == NULL) 2549130563Sobrien return FALSE; 2550130563Sobrien sec->used_by_bfd = sdata; 2551130563Sobrien } 255260508Sobrien 2553218822Sdim /* Indicate whether or not this section should use RELA relocations. */ 2554218822Sdim bed = get_elf_backend_data (abfd); 2555218822Sdim sec->use_rela_p = bed->default_use_rela_p; 2556218822Sdim 2557218822Sdim /* When we read a file, we don't need to set ELF section type and 2558218822Sdim flags. They will be overridden in _bfd_elf_make_section_from_shdr 2559218822Sdim anyway. We will set ELF section type and flags for all linker 2560218822Sdim created sections. If user specifies BFD section flags, we will 2561218822Sdim set ELF section type and flags based on BFD section flags in 2562218822Sdim elf_fake_sections. */ 2563218822Sdim if ((!sec->flags && abfd->direction != read_direction) 2564218822Sdim || (sec->flags & SEC_LINKER_CREATED) != 0) 2565130563Sobrien { 2566218822Sdim ssect = (*bed->get_sec_type_attr) (abfd, sec); 2567218822Sdim if (ssect != NULL) 2568218822Sdim { 2569218822Sdim elf_section_type (sec) = ssect->type; 2570218822Sdim elf_section_flags (sec) = ssect->attr; 2571218822Sdim } 2572130563Sobrien } 2573130563Sobrien 2574218822Sdim return _bfd_generic_new_section_hook (abfd, sec); 257533965Sjdp} 257633965Sjdp 257733965Sjdp/* Create a new bfd section from an ELF program header. 257833965Sjdp 257933965Sjdp Since program segments have no names, we generate a synthetic name 258033965Sjdp of the form segment<NUM>, where NUM is generally the index in the 258133965Sjdp program header table. For segments that are split (see below) we 258233965Sjdp generate the names segment<NUM>a and segment<NUM>b. 258333965Sjdp 258433965Sjdp Note that some program segments may have a file size that is different than 258533965Sjdp (less than) the memory size. All this means is that at execution the 258633965Sjdp system must allocate the amount of memory specified by the memory size, 258733965Sjdp but only initialize it with the first "file size" bytes read from the 258833965Sjdp file. This would occur for example, with program segments consisting 258933965Sjdp of combined data+bss. 259033965Sjdp 259133965Sjdp To handle the above situation, this routine generates TWO bfd sections 259233965Sjdp for the single program segment. The first has the length specified by 259333965Sjdp the file size of the segment, and the second has the length specified 259433965Sjdp by the difference between the two sizes. In effect, the segment is split 259533965Sjdp into it's initialized and uninitialized parts. 259633965Sjdp 259733965Sjdp */ 259833965Sjdp 2599130563Sobrienbfd_boolean 2600130563Sobrien_bfd_elf_make_section_from_phdr (bfd *abfd, 2601130563Sobrien Elf_Internal_Phdr *hdr, 2602130563Sobrien int index, 2603130563Sobrien const char *typename) 260433965Sjdp{ 260533965Sjdp asection *newsect; 260633965Sjdp char *name; 260733965Sjdp char namebuf[64]; 2608104838Sobrien size_t len; 260933965Sjdp int split; 261033965Sjdp 261160508Sobrien split = ((hdr->p_memsz > 0) 261260508Sobrien && (hdr->p_filesz > 0) 261360508Sobrien && (hdr->p_memsz > hdr->p_filesz)); 261460508Sobrien sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : ""); 2615104838Sobrien len = strlen (namebuf) + 1; 2616130563Sobrien name = bfd_alloc (abfd, len); 261733965Sjdp if (!name) 2618130563Sobrien return FALSE; 2619104838Sobrien memcpy (name, namebuf, len); 262033965Sjdp newsect = bfd_make_section (abfd, name); 262133965Sjdp if (newsect == NULL) 2622130563Sobrien return FALSE; 262333965Sjdp newsect->vma = hdr->p_vaddr; 262433965Sjdp newsect->lma = hdr->p_paddr; 2625218822Sdim newsect->size = hdr->p_filesz; 262633965Sjdp newsect->filepos = hdr->p_offset; 262733965Sjdp newsect->flags |= SEC_HAS_CONTENTS; 2628130563Sobrien newsect->alignment_power = bfd_log2 (hdr->p_align); 262933965Sjdp if (hdr->p_type == PT_LOAD) 263033965Sjdp { 263133965Sjdp newsect->flags |= SEC_ALLOC; 263233965Sjdp newsect->flags |= SEC_LOAD; 263333965Sjdp if (hdr->p_flags & PF_X) 263433965Sjdp { 263533965Sjdp /* FIXME: all we known is that it has execute PERMISSION, 263677301Sobrien may be data. */ 263733965Sjdp newsect->flags |= SEC_CODE; 263833965Sjdp } 263933965Sjdp } 264033965Sjdp if (!(hdr->p_flags & PF_W)) 264133965Sjdp { 264233965Sjdp newsect->flags |= SEC_READONLY; 264333965Sjdp } 264433965Sjdp 264533965Sjdp if (split) 264633965Sjdp { 264760508Sobrien sprintf (namebuf, "%s%db", typename, index); 2648104838Sobrien len = strlen (namebuf) + 1; 2649130563Sobrien name = bfd_alloc (abfd, len); 265033965Sjdp if (!name) 2651130563Sobrien return FALSE; 2652104838Sobrien memcpy (name, namebuf, len); 265333965Sjdp newsect = bfd_make_section (abfd, name); 265433965Sjdp if (newsect == NULL) 2655130563Sobrien return FALSE; 265633965Sjdp newsect->vma = hdr->p_vaddr + hdr->p_filesz; 265733965Sjdp newsect->lma = hdr->p_paddr + hdr->p_filesz; 2658218822Sdim newsect->size = hdr->p_memsz - hdr->p_filesz; 265933965Sjdp if (hdr->p_type == PT_LOAD) 266033965Sjdp { 266133965Sjdp newsect->flags |= SEC_ALLOC; 266233965Sjdp if (hdr->p_flags & PF_X) 266333965Sjdp newsect->flags |= SEC_CODE; 266433965Sjdp } 266533965Sjdp if (!(hdr->p_flags & PF_W)) 266633965Sjdp newsect->flags |= SEC_READONLY; 266733965Sjdp } 266833965Sjdp 2669130563Sobrien return TRUE; 267033965Sjdp} 267133965Sjdp 2672130563Sobrienbfd_boolean 2673130563Sobrienbfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index) 267460508Sobrien{ 2675130563Sobrien const struct elf_backend_data *bed; 267660508Sobrien 267760508Sobrien switch (hdr->p_type) 267860508Sobrien { 267960508Sobrien case PT_NULL: 268060508Sobrien return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "null"); 268160508Sobrien 268260508Sobrien case PT_LOAD: 268360508Sobrien return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "load"); 268460508Sobrien 268560508Sobrien case PT_DYNAMIC: 268660508Sobrien return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "dynamic"); 268760508Sobrien 268860508Sobrien case PT_INTERP: 268960508Sobrien return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "interp"); 269060508Sobrien 269160508Sobrien case PT_NOTE: 269260508Sobrien if (! _bfd_elf_make_section_from_phdr (abfd, hdr, index, "note")) 2693130563Sobrien return FALSE; 2694130563Sobrien if (! elfcore_read_notes (abfd, hdr->p_offset, hdr->p_filesz)) 2695130563Sobrien return FALSE; 2696130563Sobrien return TRUE; 269760508Sobrien 269860508Sobrien case PT_SHLIB: 269960508Sobrien return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "shlib"); 270060508Sobrien 270160508Sobrien case PT_PHDR: 270260508Sobrien return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "phdr"); 270360508Sobrien 2704130563Sobrien case PT_GNU_EH_FRAME: 2705130563Sobrien return _bfd_elf_make_section_from_phdr (abfd, hdr, index, 2706130563Sobrien "eh_frame_hdr"); 2707130563Sobrien 2708130563Sobrien case PT_GNU_STACK: 2709130563Sobrien return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "stack"); 2710130563Sobrien 2711218822Sdim case PT_GNU_RELRO: 2712218822Sdim return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "relro"); 2713218822Sdim 271460508Sobrien default: 2715218822Sdim /* Check for any processor-specific program segment types. */ 271660508Sobrien bed = get_elf_backend_data (abfd); 2717218822Sdim return bed->elf_backend_section_from_phdr (abfd, hdr, index, "proc"); 271860508Sobrien } 271960508Sobrien} 272060508Sobrien 272160508Sobrien/* Initialize REL_HDR, the section-header for new section, containing 2722130563Sobrien relocations against ASECT. If USE_RELA_P is TRUE, we use RELA 272360508Sobrien relocations; otherwise, we use REL relocations. */ 272460508Sobrien 2725130563Sobrienbfd_boolean 2726130563Sobrien_bfd_elf_init_reloc_shdr (bfd *abfd, 2727130563Sobrien Elf_Internal_Shdr *rel_hdr, 2728130563Sobrien asection *asect, 2729130563Sobrien bfd_boolean use_rela_p) 273060508Sobrien{ 273160508Sobrien char *name; 2732130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 273389860Sobrien bfd_size_type amt = sizeof ".rela" + strlen (asect->name); 273460508Sobrien 273589860Sobrien name = bfd_alloc (abfd, amt); 273660508Sobrien if (name == NULL) 2737130563Sobrien return FALSE; 273860508Sobrien sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name); 273960508Sobrien rel_hdr->sh_name = 274089860Sobrien (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name, 2741130563Sobrien FALSE); 274260508Sobrien if (rel_hdr->sh_name == (unsigned int) -1) 2743130563Sobrien return FALSE; 274460508Sobrien rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL; 274560508Sobrien rel_hdr->sh_entsize = (use_rela_p 274660508Sobrien ? bed->s->sizeof_rela 274760508Sobrien : bed->s->sizeof_rel); 2748130563Sobrien rel_hdr->sh_addralign = 1 << bed->s->log_file_align; 274960508Sobrien rel_hdr->sh_flags = 0; 275060508Sobrien rel_hdr->sh_addr = 0; 275160508Sobrien rel_hdr->sh_size = 0; 275260508Sobrien rel_hdr->sh_offset = 0; 275360508Sobrien 2754130563Sobrien return TRUE; 275560508Sobrien} 275660508Sobrien 275733965Sjdp/* Set up an ELF internal section header for a section. */ 275833965Sjdp 275933965Sjdpstatic void 2760130563Sobrienelf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg) 276133965Sjdp{ 2762130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 2763130563Sobrien bfd_boolean *failedptr = failedptrarg; 276433965Sjdp Elf_Internal_Shdr *this_hdr; 2765218822Sdim unsigned int sh_type; 276633965Sjdp 276733965Sjdp if (*failedptr) 276833965Sjdp { 276933965Sjdp /* We already failed; just get out of the bfd_map_over_sections 2770218822Sdim loop. */ 277133965Sjdp return; 277233965Sjdp } 277333965Sjdp 277433965Sjdp this_hdr = &elf_section_data (asect)->this_hdr; 277533965Sjdp 2776130563Sobrien this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), 2777130563Sobrien asect->name, FALSE); 2778130563Sobrien if (this_hdr->sh_name == (unsigned int) -1) 277933965Sjdp { 2780130563Sobrien *failedptr = TRUE; 278133965Sjdp return; 278233965Sjdp } 278333965Sjdp 2784218822Sdim /* Don't clear sh_flags. Assembler may set additional bits. */ 278533965Sjdp 278633965Sjdp if ((asect->flags & SEC_ALLOC) != 0 278733965Sjdp || asect->user_set_vma) 278833965Sjdp this_hdr->sh_addr = asect->vma; 278933965Sjdp else 279033965Sjdp this_hdr->sh_addr = 0; 279133965Sjdp 279233965Sjdp this_hdr->sh_offset = 0; 2793218822Sdim this_hdr->sh_size = asect->size; 279433965Sjdp this_hdr->sh_link = 0; 279533965Sjdp this_hdr->sh_addralign = 1 << asect->alignment_power; 279633965Sjdp /* The sh_entsize and sh_info fields may have been set already by 279733965Sjdp copy_private_section_data. */ 279833965Sjdp 279933965Sjdp this_hdr->bfd_section = asect; 280033965Sjdp this_hdr->contents = NULL; 280133965Sjdp 2802130563Sobrien /* If the section type is unspecified, we set it based on 2803130563Sobrien asect->flags. */ 2804130563Sobrien if (this_hdr->sh_type == SHT_NULL) 280533965Sjdp { 2806218822Sdim if ((asect->flags & SEC_GROUP) != 0) 2807218822Sdim this_hdr->sh_type = SHT_GROUP; 2808218822Sdim else if ((asect->flags & SEC_ALLOC) != 0 2809218822Sdim && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) 2810218822Sdim || (asect->flags & SEC_NEVER_LOAD) != 0)) 2811130563Sobrien this_hdr->sh_type = SHT_NOBITS; 2812130563Sobrien else 2813130563Sobrien this_hdr->sh_type = SHT_PROGBITS; 281433965Sjdp } 2815130563Sobrien 2816130563Sobrien switch (this_hdr->sh_type) 281733965Sjdp { 2818130563Sobrien default: 2819130563Sobrien break; 2820130563Sobrien 2821130563Sobrien case SHT_STRTAB: 2822130563Sobrien case SHT_INIT_ARRAY: 2823130563Sobrien case SHT_FINI_ARRAY: 2824130563Sobrien case SHT_PREINIT_ARRAY: 2825130563Sobrien case SHT_NOTE: 2826130563Sobrien case SHT_NOBITS: 2827130563Sobrien case SHT_PROGBITS: 2828130563Sobrien break; 2829130563Sobrien 2830130563Sobrien case SHT_HASH: 2831130563Sobrien this_hdr->sh_entsize = bed->s->sizeof_hash_entry; 2832130563Sobrien break; 2833130563Sobrien 2834130563Sobrien case SHT_DYNSYM: 283533965Sjdp this_hdr->sh_entsize = bed->s->sizeof_sym; 2836130563Sobrien break; 2837130563Sobrien 2838130563Sobrien case SHT_DYNAMIC: 283933965Sjdp this_hdr->sh_entsize = bed->s->sizeof_dyn; 2840130563Sobrien break; 2841130563Sobrien 2842130563Sobrien case SHT_RELA: 2843130563Sobrien if (get_elf_backend_data (abfd)->may_use_rela_p) 2844130563Sobrien this_hdr->sh_entsize = bed->s->sizeof_rela; 2845130563Sobrien break; 2846130563Sobrien 2847130563Sobrien case SHT_REL: 2848130563Sobrien if (get_elf_backend_data (abfd)->may_use_rel_p) 2849130563Sobrien this_hdr->sh_entsize = bed->s->sizeof_rel; 2850130563Sobrien break; 2851130563Sobrien 2852130563Sobrien case SHT_GNU_versym: 285333965Sjdp this_hdr->sh_entsize = sizeof (Elf_External_Versym); 2854130563Sobrien break; 2855130563Sobrien 2856130563Sobrien case SHT_GNU_verdef: 285733965Sjdp this_hdr->sh_entsize = 0; 285833965Sjdp /* objcopy or strip will copy over sh_info, but may not set 2859218822Sdim cverdefs. The linker will set cverdefs, but sh_info will be 2860218822Sdim zero. */ 286133965Sjdp if (this_hdr->sh_info == 0) 286233965Sjdp this_hdr->sh_info = elf_tdata (abfd)->cverdefs; 286333965Sjdp else 286433965Sjdp BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0 286533965Sjdp || this_hdr->sh_info == elf_tdata (abfd)->cverdefs); 2866130563Sobrien break; 2867130563Sobrien 2868130563Sobrien case SHT_GNU_verneed: 286933965Sjdp this_hdr->sh_entsize = 0; 287033965Sjdp /* objcopy or strip will copy over sh_info, but may not set 2871218822Sdim cverrefs. The linker will set cverrefs, but sh_info will be 2872218822Sdim zero. */ 287333965Sjdp if (this_hdr->sh_info == 0) 287433965Sjdp this_hdr->sh_info = elf_tdata (abfd)->cverrefs; 287533965Sjdp else 287633965Sjdp BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0 287733965Sjdp || this_hdr->sh_info == elf_tdata (abfd)->cverrefs); 2878130563Sobrien break; 2879130563Sobrien 2880130563Sobrien case SHT_GROUP: 2881218822Sdim this_hdr->sh_entsize = GRP_ENTRY_SIZE; 2882130563Sobrien break; 2883218822Sdim 2884218822Sdim case SHT_GNU_HASH: 2885218822Sdim this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4; 2886218822Sdim break; 288789860Sobrien } 288833965Sjdp 288933965Sjdp if ((asect->flags & SEC_ALLOC) != 0) 289033965Sjdp this_hdr->sh_flags |= SHF_ALLOC; 289133965Sjdp if ((asect->flags & SEC_READONLY) == 0) 289233965Sjdp this_hdr->sh_flags |= SHF_WRITE; 289333965Sjdp if ((asect->flags & SEC_CODE) != 0) 289433965Sjdp this_hdr->sh_flags |= SHF_EXECINSTR; 289589860Sobrien if ((asect->flags & SEC_MERGE) != 0) 289689860Sobrien { 289789860Sobrien this_hdr->sh_flags |= SHF_MERGE; 289889860Sobrien this_hdr->sh_entsize = asect->entsize; 289989860Sobrien if ((asect->flags & SEC_STRINGS) != 0) 290089860Sobrien this_hdr->sh_flags |= SHF_STRINGS; 290189860Sobrien } 2902104838Sobrien if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL) 290389860Sobrien this_hdr->sh_flags |= SHF_GROUP; 2904104838Sobrien if ((asect->flags & SEC_THREAD_LOCAL) != 0) 2905104838Sobrien { 2906104838Sobrien this_hdr->sh_flags |= SHF_TLS; 2907218822Sdim if (asect->size == 0 2908218822Sdim && (asect->flags & SEC_HAS_CONTENTS) == 0) 2909104838Sobrien { 2910218822Sdim struct bfd_link_order *o = asect->map_tail.link_order; 2911130563Sobrien 2912104838Sobrien this_hdr->sh_size = 0; 2913218822Sdim if (o != NULL) 2914218822Sdim { 2915104838Sobrien this_hdr->sh_size = o->offset + o->size; 2916218822Sdim if (this_hdr->sh_size != 0) 2917218822Sdim this_hdr->sh_type = SHT_NOBITS; 2918218822Sdim } 2919104838Sobrien } 2920104838Sobrien } 292133965Sjdp 292233965Sjdp /* Check for processor-specific section types. */ 2923218822Sdim sh_type = this_hdr->sh_type; 292489860Sobrien if (bed->elf_backend_fake_sections 292589860Sobrien && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect)) 2926130563Sobrien *failedptr = TRUE; 292733965Sjdp 2928218822Sdim if (sh_type == SHT_NOBITS && asect->size != 0) 2929218822Sdim { 2930218822Sdim /* Don't change the header type from NOBITS if we are being 2931218822Sdim called for objcopy --only-keep-debug. */ 2932218822Sdim this_hdr->sh_type = sh_type; 2933218822Sdim } 2934218822Sdim 293533965Sjdp /* If the section has relocs, set up a section header for the 293660508Sobrien SHT_REL[A] section. If two relocation sections are required for 293760508Sobrien this section, it is up to the processor-specific back-end to 293877301Sobrien create the other. */ 293960508Sobrien if ((asect->flags & SEC_RELOC) != 0 294077301Sobrien && !_bfd_elf_init_reloc_shdr (abfd, 294160508Sobrien &elf_section_data (asect)->rel_hdr, 294277301Sobrien asect, 2943130563Sobrien asect->use_rela_p)) 2944130563Sobrien *failedptr = TRUE; 294533965Sjdp} 294633965Sjdp 294789860Sobrien/* Fill in the contents of a SHT_GROUP section. */ 294889860Sobrien 2949104838Sobrienvoid 2950130563Sobrienbfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) 295189860Sobrien{ 2952130563Sobrien bfd_boolean *failedptr = failedptrarg; 295389860Sobrien unsigned long symindx; 2954104838Sobrien asection *elt, *first; 295589860Sobrien unsigned char *loc; 2956130563Sobrien bfd_boolean gas; 295789860Sobrien 2958218822Sdim /* Ignore linker created group section. See elfNN_ia64_object_p in 2959218822Sdim elfxx-ia64.c. */ 2960218822Sdim if (((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP) 296189860Sobrien || *failedptr) 296289860Sobrien return; 296389860Sobrien 2964104838Sobrien symindx = 0; 2965104838Sobrien if (elf_group_id (sec) != NULL) 2966104838Sobrien symindx = elf_group_id (sec)->udata.i; 2967104838Sobrien 2968104838Sobrien if (symindx == 0) 2969104838Sobrien { 2970104838Sobrien /* If called from the assembler, swap_out_syms will have set up 2971104838Sobrien elf_section_syms; If called for "ld -r", use target_index. */ 2972104838Sobrien if (elf_section_syms (abfd) != NULL) 2973104838Sobrien symindx = elf_section_syms (abfd)[sec->index]->udata.i; 2974104838Sobrien else 2975104838Sobrien symindx = sec->target_index; 2976104838Sobrien } 297789860Sobrien elf_section_data (sec)->this_hdr.sh_info = symindx; 297889860Sobrien 2979104838Sobrien /* The contents won't be allocated for "ld -r" or objcopy. */ 2980130563Sobrien gas = TRUE; 298189860Sobrien if (sec->contents == NULL) 298289860Sobrien { 2983130563Sobrien gas = FALSE; 2984218822Sdim sec->contents = bfd_alloc (abfd, sec->size); 2985104838Sobrien 2986104838Sobrien /* Arrange for the section to be written out. */ 2987104838Sobrien elf_section_data (sec)->this_hdr.contents = sec->contents; 298889860Sobrien if (sec->contents == NULL) 298989860Sobrien { 2990130563Sobrien *failedptr = TRUE; 299189860Sobrien return; 299289860Sobrien } 299389860Sobrien } 299489860Sobrien 2995218822Sdim loc = sec->contents + sec->size; 299689860Sobrien 2997104838Sobrien /* Get the pointer to the first section in the group that gas 2998104838Sobrien squirreled away here. objcopy arranges for this to be set to the 2999104838Sobrien start of the input section group. */ 3000104838Sobrien first = elt = elf_next_in_group (sec); 300189860Sobrien 300289860Sobrien /* First element is a flag word. Rest of section is elf section 300389860Sobrien indices for all the sections of the group. Write them backwards 300489860Sobrien just to keep the group in the same order as given in .section 300589860Sobrien directives, not that it matters. */ 300689860Sobrien while (elt != NULL) 300789860Sobrien { 3008104838Sobrien asection *s; 3009104838Sobrien unsigned int idx; 3010104838Sobrien 301189860Sobrien loc -= 4; 3012104838Sobrien s = elt; 3013104838Sobrien if (!gas) 3014104838Sobrien s = s->output_section; 3015104838Sobrien idx = 0; 3016104838Sobrien if (s != NULL) 3017104838Sobrien idx = elf_section_data (s)->this_idx; 3018104838Sobrien H_PUT_32 (abfd, idx, loc); 301989860Sobrien elt = elf_next_in_group (elt); 3020104838Sobrien if (elt == first) 3021104838Sobrien break; 302289860Sobrien } 302389860Sobrien 3024218822Sdim if ((loc -= 4) != sec->contents) 3025104838Sobrien abort (); 3026104838Sobrien 3027104838Sobrien H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc); 302889860Sobrien} 302989860Sobrien 303033965Sjdp/* Assign all ELF section numbers. The dummy first section is handled here 303133965Sjdp too. The link/info pointers for the standard section types are filled 303233965Sjdp in here too, while we're at it. */ 303333965Sjdp 3034130563Sobrienstatic bfd_boolean 3035218822Sdimassign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) 303633965Sjdp{ 303733965Sjdp struct elf_obj_tdata *t = elf_tdata (abfd); 303833965Sjdp asection *sec; 303989860Sobrien unsigned int section_number, secn; 304033965Sjdp Elf_Internal_Shdr **i_shdrp; 3041218822Sdim struct bfd_elf_section_data *d; 304233965Sjdp 304333965Sjdp section_number = 1; 304433965Sjdp 304589860Sobrien _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd)); 304689860Sobrien 3047218822Sdim /* SHT_GROUP sections are in relocatable files only. */ 3048218822Sdim if (link_info == NULL || link_info->relocatable) 3049218822Sdim { 3050218822Sdim /* Put SHT_GROUP sections first. */ 3051218822Sdim for (sec = abfd->sections; sec != NULL; sec = sec->next) 3052218822Sdim { 3053218822Sdim d = elf_section_data (sec); 3054218822Sdim 3055218822Sdim if (d->this_hdr.sh_type == SHT_GROUP) 3056218822Sdim { 3057218822Sdim if (sec->flags & SEC_LINKER_CREATED) 3058218822Sdim { 3059218822Sdim /* Remove the linker created SHT_GROUP sections. */ 3060218822Sdim bfd_section_list_remove (abfd, sec); 3061218822Sdim abfd->section_count--; 3062218822Sdim } 3063218822Sdim else 3064218822Sdim { 3065218822Sdim if (section_number == SHN_LORESERVE) 3066218822Sdim section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; 3067218822Sdim d->this_idx = section_number++; 3068218822Sdim } 3069218822Sdim } 3070218822Sdim } 3071218822Sdim } 3072218822Sdim 307333965Sjdp for (sec = abfd->sections; sec; sec = sec->next) 307433965Sjdp { 3075218822Sdim d = elf_section_data (sec); 307633965Sjdp 3077218822Sdim if (d->this_hdr.sh_type != SHT_GROUP) 3078218822Sdim { 3079218822Sdim if (section_number == SHN_LORESERVE) 3080218822Sdim section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; 3081218822Sdim d->this_idx = section_number++; 3082218822Sdim } 308389860Sobrien _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name); 308433965Sjdp if ((sec->flags & SEC_RELOC) == 0) 308533965Sjdp d->rel_idx = 0; 308633965Sjdp else 308789860Sobrien { 308889860Sobrien if (section_number == SHN_LORESERVE) 308989860Sobrien section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; 309089860Sobrien d->rel_idx = section_number++; 309189860Sobrien _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name); 309289860Sobrien } 309360508Sobrien 309460508Sobrien if (d->rel_hdr2) 309589860Sobrien { 309689860Sobrien if (section_number == SHN_LORESERVE) 309789860Sobrien section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; 309889860Sobrien d->rel_idx2 = section_number++; 309989860Sobrien _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name); 310089860Sobrien } 310160508Sobrien else 310260508Sobrien d->rel_idx2 = 0; 310333965Sjdp } 310433965Sjdp 310589860Sobrien if (section_number == SHN_LORESERVE) 310689860Sobrien section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; 310733965Sjdp t->shstrtab_section = section_number++; 310889860Sobrien _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name); 310933965Sjdp elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section; 311033965Sjdp 311160508Sobrien if (bfd_get_symcount (abfd) > 0) 311233965Sjdp { 311389860Sobrien if (section_number == SHN_LORESERVE) 311489860Sobrien section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; 311533965Sjdp t->symtab_section = section_number++; 311689860Sobrien _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name); 311789860Sobrien if (section_number > SHN_LORESERVE - 2) 311889860Sobrien { 311989860Sobrien if (section_number == SHN_LORESERVE) 312089860Sobrien section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; 312189860Sobrien t->symtab_shndx_section = section_number++; 312289860Sobrien t->symtab_shndx_hdr.sh_name 312389860Sobrien = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), 3124130563Sobrien ".symtab_shndx", FALSE); 312589860Sobrien if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1) 3126130563Sobrien return FALSE; 312789860Sobrien } 312889860Sobrien if (section_number == SHN_LORESERVE) 312989860Sobrien section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE; 313033965Sjdp t->strtab_section = section_number++; 313189860Sobrien _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name); 313233965Sjdp } 313333965Sjdp 313489860Sobrien _bfd_elf_strtab_finalize (elf_shstrtab (abfd)); 313589860Sobrien t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd)); 313689860Sobrien 313789860Sobrien elf_numsections (abfd) = section_number; 313833965Sjdp elf_elfheader (abfd)->e_shnum = section_number; 313989860Sobrien if (section_number > SHN_LORESERVE) 314089860Sobrien elf_elfheader (abfd)->e_shnum -= SHN_HIRESERVE + 1 - SHN_LORESERVE; 314133965Sjdp 314233965Sjdp /* Set up the list of section header pointers, in agreement with the 314333965Sjdp indices. */ 3144218822Sdim i_shdrp = bfd_zalloc2 (abfd, section_number, sizeof (Elf_Internal_Shdr *)); 314533965Sjdp if (i_shdrp == NULL) 3146130563Sobrien return FALSE; 314733965Sjdp 3148218822Sdim i_shdrp[0] = bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr)); 314933965Sjdp if (i_shdrp[0] == NULL) 315033965Sjdp { 315133965Sjdp bfd_release (abfd, i_shdrp); 3152130563Sobrien return FALSE; 315333965Sjdp } 315433965Sjdp 315533965Sjdp elf_elfsections (abfd) = i_shdrp; 315633965Sjdp 315733965Sjdp i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr; 315860508Sobrien if (bfd_get_symcount (abfd) > 0) 315933965Sjdp { 316033965Sjdp i_shdrp[t->symtab_section] = &t->symtab_hdr; 316189860Sobrien if (elf_numsections (abfd) > SHN_LORESERVE) 316289860Sobrien { 316389860Sobrien i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr; 316489860Sobrien t->symtab_shndx_hdr.sh_link = t->symtab_section; 316589860Sobrien } 316633965Sjdp i_shdrp[t->strtab_section] = &t->strtab_hdr; 316733965Sjdp t->symtab_hdr.sh_link = t->strtab_section; 316833965Sjdp } 3169218822Sdim 317033965Sjdp for (sec = abfd->sections; sec; sec = sec->next) 317133965Sjdp { 317233965Sjdp struct bfd_elf_section_data *d = elf_section_data (sec); 317333965Sjdp asection *s; 317433965Sjdp const char *name; 317533965Sjdp 317633965Sjdp i_shdrp[d->this_idx] = &d->this_hdr; 317733965Sjdp if (d->rel_idx != 0) 317833965Sjdp i_shdrp[d->rel_idx] = &d->rel_hdr; 317960508Sobrien if (d->rel_idx2 != 0) 318060508Sobrien i_shdrp[d->rel_idx2] = d->rel_hdr2; 318133965Sjdp 318233965Sjdp /* Fill in the sh_link and sh_info fields while we're at it. */ 318333965Sjdp 318433965Sjdp /* sh_link of a reloc section is the section index of the symbol 318533965Sjdp table. sh_info is the section index of the section to which 318633965Sjdp the relocation entries apply. */ 318733965Sjdp if (d->rel_idx != 0) 318833965Sjdp { 318933965Sjdp d->rel_hdr.sh_link = t->symtab_section; 319033965Sjdp d->rel_hdr.sh_info = d->this_idx; 319133965Sjdp } 319260508Sobrien if (d->rel_idx2 != 0) 319360508Sobrien { 319460508Sobrien d->rel_hdr2->sh_link = t->symtab_section; 319560508Sobrien d->rel_hdr2->sh_info = d->this_idx; 319660508Sobrien } 319733965Sjdp 3198218822Sdim /* We need to set up sh_link for SHF_LINK_ORDER. */ 3199218822Sdim if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0) 3200218822Sdim { 3201218822Sdim s = elf_linked_to_section (sec); 3202218822Sdim if (s) 3203218822Sdim { 3204218822Sdim /* elf_linked_to_section points to the input section. */ 3205218822Sdim if (link_info != NULL) 3206218822Sdim { 3207218822Sdim /* Check discarded linkonce section. */ 3208218822Sdim if (elf_discarded_section (s)) 3209218822Sdim { 3210218822Sdim asection *kept; 3211218822Sdim (*_bfd_error_handler) 3212218822Sdim (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"), 3213218822Sdim abfd, d->this_hdr.bfd_section, 3214218822Sdim s, s->owner); 3215218822Sdim /* Point to the kept section if it has the same 3216218822Sdim size as the discarded one. */ 3217218822Sdim kept = _bfd_elf_check_kept_section (s, link_info); 3218218822Sdim if (kept == NULL) 3219218822Sdim { 3220218822Sdim bfd_set_error (bfd_error_bad_value); 3221218822Sdim return FALSE; 3222218822Sdim } 3223218822Sdim s = kept; 3224218822Sdim } 3225218822Sdim 3226218822Sdim s = s->output_section; 3227218822Sdim BFD_ASSERT (s != NULL); 3228218822Sdim } 3229218822Sdim else 3230218822Sdim { 3231218822Sdim /* Handle objcopy. */ 3232218822Sdim if (s->output_section == NULL) 3233218822Sdim { 3234218822Sdim (*_bfd_error_handler) 3235218822Sdim (_("%B: sh_link of section `%A' points to removed section `%A' of `%B'"), 3236218822Sdim abfd, d->this_hdr.bfd_section, s, s->owner); 3237218822Sdim bfd_set_error (bfd_error_bad_value); 3238218822Sdim return FALSE; 3239218822Sdim } 3240218822Sdim s = s->output_section; 3241218822Sdim } 3242218822Sdim d->this_hdr.sh_link = elf_section_data (s)->this_idx; 3243218822Sdim } 3244218822Sdim else 3245218822Sdim { 3246218822Sdim /* PR 290: 3247218822Sdim The Intel C compiler generates SHT_IA_64_UNWIND with 3248218822Sdim SHF_LINK_ORDER. But it doesn't set the sh_link or 3249218822Sdim sh_info fields. Hence we could get the situation 3250218822Sdim where s is NULL. */ 3251218822Sdim const struct elf_backend_data *bed 3252218822Sdim = get_elf_backend_data (abfd); 3253218822Sdim if (bed->link_order_error_handler) 3254218822Sdim bed->link_order_error_handler 3255218822Sdim (_("%B: warning: sh_link not set for section `%A'"), 3256218822Sdim abfd, sec); 3257218822Sdim } 3258218822Sdim } 3259218822Sdim 326033965Sjdp switch (d->this_hdr.sh_type) 326133965Sjdp { 326233965Sjdp case SHT_REL: 326333965Sjdp case SHT_RELA: 326433965Sjdp /* A reloc section which we are treating as a normal BFD 326533965Sjdp section. sh_link is the section index of the symbol 326633965Sjdp table. sh_info is the section index of the section to 326733965Sjdp which the relocation entries apply. We assume that an 326833965Sjdp allocated reloc section uses the dynamic symbol table. 326933965Sjdp FIXME: How can we be sure? */ 327033965Sjdp s = bfd_get_section_by_name (abfd, ".dynsym"); 327133965Sjdp if (s != NULL) 327233965Sjdp d->this_hdr.sh_link = elf_section_data (s)->this_idx; 327333965Sjdp 327433965Sjdp /* We look up the section the relocs apply to by name. */ 327533965Sjdp name = sec->name; 327633965Sjdp if (d->this_hdr.sh_type == SHT_REL) 327733965Sjdp name += 4; 327833965Sjdp else 327933965Sjdp name += 5; 328033965Sjdp s = bfd_get_section_by_name (abfd, name); 328133965Sjdp if (s != NULL) 328233965Sjdp d->this_hdr.sh_info = elf_section_data (s)->this_idx; 328333965Sjdp break; 328433965Sjdp 328533965Sjdp case SHT_STRTAB: 328633965Sjdp /* We assume that a section named .stab*str is a stabs 328733965Sjdp string section. We look for a section with the same name 328833965Sjdp but without the trailing ``str'', and set its sh_link 328933965Sjdp field to point to this section. */ 3290218822Sdim if (CONST_STRNEQ (sec->name, ".stab") 329133965Sjdp && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0) 329233965Sjdp { 329333965Sjdp size_t len; 329433965Sjdp char *alc; 329533965Sjdp 329633965Sjdp len = strlen (sec->name); 3297130563Sobrien alc = bfd_malloc (len - 2); 329833965Sjdp if (alc == NULL) 3299130563Sobrien return FALSE; 3300104838Sobrien memcpy (alc, sec->name, len - 3); 330133965Sjdp alc[len - 3] = '\0'; 330233965Sjdp s = bfd_get_section_by_name (abfd, alc); 330333965Sjdp free (alc); 330433965Sjdp if (s != NULL) 330533965Sjdp { 330633965Sjdp elf_section_data (s)->this_hdr.sh_link = d->this_idx; 330733965Sjdp 330833965Sjdp /* This is a .stab section. */ 3309104838Sobrien if (elf_section_data (s)->this_hdr.sh_entsize == 0) 3310104838Sobrien elf_section_data (s)->this_hdr.sh_entsize 3311104838Sobrien = 4 + 2 * bfd_get_arch_size (abfd) / 8; 331233965Sjdp } 331333965Sjdp } 331433965Sjdp break; 331533965Sjdp 331633965Sjdp case SHT_DYNAMIC: 331733965Sjdp case SHT_DYNSYM: 331833965Sjdp case SHT_GNU_verneed: 331933965Sjdp case SHT_GNU_verdef: 332033965Sjdp /* sh_link is the section header index of the string table 332133965Sjdp used for the dynamic entries, or the symbol table, or the 332233965Sjdp version strings. */ 332333965Sjdp s = bfd_get_section_by_name (abfd, ".dynstr"); 332433965Sjdp if (s != NULL) 332533965Sjdp d->this_hdr.sh_link = elf_section_data (s)->this_idx; 332633965Sjdp break; 332733965Sjdp 3328218822Sdim case SHT_GNU_LIBLIST: 3329218822Sdim /* sh_link is the section header index of the prelink library 3330218822Sdim list used for the dynamic entries, or the symbol table, or 3331218822Sdim the version strings. */ 3332218822Sdim s = bfd_get_section_by_name (abfd, (sec->flags & SEC_ALLOC) 3333218822Sdim ? ".dynstr" : ".gnu.libstr"); 3334218822Sdim if (s != NULL) 3335218822Sdim d->this_hdr.sh_link = elf_section_data (s)->this_idx; 3336218822Sdim break; 3337218822Sdim 333833965Sjdp case SHT_HASH: 3339218822Sdim case SHT_GNU_HASH: 334033965Sjdp case SHT_GNU_versym: 334133965Sjdp /* sh_link is the section header index of the symbol table 334233965Sjdp this hash table or version table is for. */ 334333965Sjdp s = bfd_get_section_by_name (abfd, ".dynsym"); 334433965Sjdp if (s != NULL) 334533965Sjdp d->this_hdr.sh_link = elf_section_data (s)->this_idx; 334633965Sjdp break; 334789860Sobrien 334889860Sobrien case SHT_GROUP: 334989860Sobrien d->this_hdr.sh_link = t->symtab_section; 335033965Sjdp } 335133965Sjdp } 335233965Sjdp 335389860Sobrien for (secn = 1; secn < section_number; ++secn) 335489860Sobrien if (i_shdrp[secn] == NULL) 335589860Sobrien i_shdrp[secn] = i_shdrp[0]; 335689860Sobrien else 335789860Sobrien i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd), 335889860Sobrien i_shdrp[secn]->sh_name); 3359130563Sobrien return TRUE; 336033965Sjdp} 336133965Sjdp 336233965Sjdp/* Map symbol from it's internal number to the external number, moving 336333965Sjdp all local symbols to be at the head of the list. */ 336433965Sjdp 3365218822Sdimstatic bfd_boolean 3366130563Sobriensym_is_global (bfd *abfd, asymbol *sym) 336733965Sjdp{ 336833965Sjdp /* If the backend has a special mapping, use it. */ 3369130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 3370130563Sobrien if (bed->elf_backend_sym_is_global) 3371130563Sobrien return (*bed->elf_backend_sym_is_global) (abfd, sym); 337233965Sjdp 337333965Sjdp return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0 337433965Sjdp || bfd_is_und_section (bfd_get_section (sym)) 337533965Sjdp || bfd_is_com_section (bfd_get_section (sym))); 337633965Sjdp} 337733965Sjdp 3378218822Sdim/* Don't output section symbols for sections that are not going to be 3379218822Sdim output. Also, don't output section symbols for reloc and other 3380218822Sdim special sections. */ 3381218822Sdim 3382130563Sobrienstatic bfd_boolean 3383218822Sdimignore_section_sym (bfd *abfd, asymbol *sym) 3384218822Sdim{ 3385218822Sdim return ((sym->flags & BSF_SECTION_SYM) != 0 3386218822Sdim && (sym->value != 0 3387218822Sdim || (sym->section->owner != abfd 3388218822Sdim && (sym->section->output_section->owner != abfd 3389218822Sdim || sym->section->output_offset != 0)))); 3390218822Sdim} 3391218822Sdim 3392218822Sdimstatic bfd_boolean 3393130563Sobrienelf_map_symbols (bfd *abfd) 339433965Sjdp{ 339589860Sobrien unsigned int symcount = bfd_get_symcount (abfd); 339633965Sjdp asymbol **syms = bfd_get_outsymbols (abfd); 339733965Sjdp asymbol **sect_syms; 339889860Sobrien unsigned int num_locals = 0; 339989860Sobrien unsigned int num_globals = 0; 340089860Sobrien unsigned int num_locals2 = 0; 340189860Sobrien unsigned int num_globals2 = 0; 340233965Sjdp int max_index = 0; 340389860Sobrien unsigned int idx; 340433965Sjdp asection *asect; 340533965Sjdp asymbol **new_syms; 340633965Sjdp 340733965Sjdp#ifdef DEBUG 340833965Sjdp fprintf (stderr, "elf_map_symbols\n"); 340933965Sjdp fflush (stderr); 341033965Sjdp#endif 341133965Sjdp 341233965Sjdp for (asect = abfd->sections; asect; asect = asect->next) 341333965Sjdp { 341433965Sjdp if (max_index < asect->index) 341533965Sjdp max_index = asect->index; 341633965Sjdp } 341733965Sjdp 341833965Sjdp max_index++; 3419218822Sdim sect_syms = bfd_zalloc2 (abfd, max_index, sizeof (asymbol *)); 342033965Sjdp if (sect_syms == NULL) 3421130563Sobrien return FALSE; 342233965Sjdp elf_section_syms (abfd) = sect_syms; 342389860Sobrien elf_num_section_syms (abfd) = max_index; 342433965Sjdp 342589860Sobrien /* Init sect_syms entries for any section symbols we have already 342689860Sobrien decided to output. */ 342733965Sjdp for (idx = 0; idx < symcount; idx++) 342833965Sjdp { 342989860Sobrien asymbol *sym = syms[idx]; 343077301Sobrien 343160508Sobrien if ((sym->flags & BSF_SECTION_SYM) != 0 3432218822Sdim && !ignore_section_sym (abfd, sym)) 343333965Sjdp { 3434218822Sdim asection *sec = sym->section; 343533965Sjdp 3436218822Sdim if (sec->owner != abfd) 3437218822Sdim sec = sec->output_section; 343860508Sobrien 3439218822Sdim sect_syms[sec->index] = syms[idx]; 344033965Sjdp } 344133965Sjdp } 344233965Sjdp 344333965Sjdp /* Classify all of the symbols. */ 344433965Sjdp for (idx = 0; idx < symcount; idx++) 344533965Sjdp { 3446218822Sdim if (ignore_section_sym (abfd, syms[idx])) 3447218822Sdim continue; 344833965Sjdp if (!sym_is_global (abfd, syms[idx])) 344933965Sjdp num_locals++; 345033965Sjdp else 345133965Sjdp num_globals++; 345233965Sjdp } 345389860Sobrien 3454218822Sdim /* We will be adding a section symbol for each normal BFD section. Most 345589860Sobrien sections will already have a section symbol in outsymbols, but 345689860Sobrien eg. SHT_GROUP sections will not, and we need the section symbol mapped 345789860Sobrien at least in that case. */ 345833965Sjdp for (asect = abfd->sections; asect; asect = asect->next) 345933965Sjdp { 346089860Sobrien if (sect_syms[asect->index] == NULL) 346133965Sjdp { 346289860Sobrien if (!sym_is_global (abfd, asect->symbol)) 346333965Sjdp num_locals++; 346433965Sjdp else 346533965Sjdp num_globals++; 346633965Sjdp } 346733965Sjdp } 346833965Sjdp 346933965Sjdp /* Now sort the symbols so the local symbols are first. */ 3470218822Sdim new_syms = bfd_alloc2 (abfd, num_locals + num_globals, sizeof (asymbol *)); 347189860Sobrien 347233965Sjdp if (new_syms == NULL) 3473130563Sobrien return FALSE; 347433965Sjdp 347533965Sjdp for (idx = 0; idx < symcount; idx++) 347633965Sjdp { 347733965Sjdp asymbol *sym = syms[idx]; 347889860Sobrien unsigned int i; 347933965Sjdp 3480218822Sdim if (ignore_section_sym (abfd, sym)) 3481218822Sdim continue; 348233965Sjdp if (!sym_is_global (abfd, sym)) 348333965Sjdp i = num_locals2++; 348433965Sjdp else 348533965Sjdp i = num_locals + num_globals2++; 348633965Sjdp new_syms[i] = sym; 348733965Sjdp sym->udata.i = i + 1; 348833965Sjdp } 348933965Sjdp for (asect = abfd->sections; asect; asect = asect->next) 349033965Sjdp { 349189860Sobrien if (sect_syms[asect->index] == NULL) 349233965Sjdp { 349389860Sobrien asymbol *sym = asect->symbol; 349489860Sobrien unsigned int i; 349533965Sjdp 349689860Sobrien sect_syms[asect->index] = sym; 349733965Sjdp if (!sym_is_global (abfd, sym)) 349833965Sjdp i = num_locals2++; 349933965Sjdp else 350033965Sjdp i = num_locals + num_globals2++; 350133965Sjdp new_syms[i] = sym; 350233965Sjdp sym->udata.i = i + 1; 350333965Sjdp } 350433965Sjdp } 350533965Sjdp 350633965Sjdp bfd_set_symtab (abfd, new_syms, num_locals + num_globals); 350733965Sjdp 350833965Sjdp elf_num_locals (abfd) = num_locals; 350933965Sjdp elf_num_globals (abfd) = num_globals; 3510130563Sobrien return TRUE; 351133965Sjdp} 351233965Sjdp 351333965Sjdp/* Align to the maximum file alignment that could be required for any 351433965Sjdp ELF data structure. */ 351533965Sjdp 3516130563Sobrienstatic inline file_ptr 3517130563Sobrienalign_file_position (file_ptr off, int align) 351833965Sjdp{ 351933965Sjdp return (off + align - 1) & ~(align - 1); 352033965Sjdp} 352133965Sjdp 352233965Sjdp/* Assign a file position to a section, optionally aligning to the 352333965Sjdp required section alignment. */ 352433965Sjdp 3525130563Sobrienfile_ptr 3526130563Sobrien_bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp, 3527130563Sobrien file_ptr offset, 3528130563Sobrien bfd_boolean align) 352933965Sjdp{ 353033965Sjdp if (align) 353133965Sjdp { 353233965Sjdp unsigned int al; 353333965Sjdp 353433965Sjdp al = i_shdrp->sh_addralign; 353533965Sjdp if (al > 1) 353633965Sjdp offset = BFD_ALIGN (offset, al); 353733965Sjdp } 353833965Sjdp i_shdrp->sh_offset = offset; 353933965Sjdp if (i_shdrp->bfd_section != NULL) 354033965Sjdp i_shdrp->bfd_section->filepos = offset; 354133965Sjdp if (i_shdrp->sh_type != SHT_NOBITS) 354233965Sjdp offset += i_shdrp->sh_size; 354333965Sjdp return offset; 354433965Sjdp} 354533965Sjdp 354633965Sjdp/* Compute the file positions we are going to put the sections at, and 354733965Sjdp otherwise prepare to begin writing out the ELF file. If LINK_INFO 354833965Sjdp is not NULL, this is being called by the ELF backend linker. */ 354933965Sjdp 3550130563Sobrienbfd_boolean 3551130563Sobrien_bfd_elf_compute_section_file_positions (bfd *abfd, 3552130563Sobrien struct bfd_link_info *link_info) 355333965Sjdp{ 3554130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 3555130563Sobrien bfd_boolean failed; 3556218822Sdim struct bfd_strtab_hash *strtab = NULL; 355733965Sjdp Elf_Internal_Shdr *shstrtab_hdr; 355833965Sjdp 355933965Sjdp if (abfd->output_has_begun) 3560130563Sobrien return TRUE; 356133965Sjdp 356233965Sjdp /* Do any elf backend specific processing first. */ 356333965Sjdp if (bed->elf_backend_begin_write_processing) 356433965Sjdp (*bed->elf_backend_begin_write_processing) (abfd, link_info); 356533965Sjdp 356633965Sjdp if (! prep_headers (abfd)) 3567130563Sobrien return FALSE; 356833965Sjdp 356960508Sobrien /* Post process the headers if necessary. */ 357060508Sobrien if (bed->elf_backend_post_process_headers) 357160508Sobrien (*bed->elf_backend_post_process_headers) (abfd, link_info); 357260508Sobrien 3573130563Sobrien failed = FALSE; 357433965Sjdp bfd_map_over_sections (abfd, elf_fake_sections, &failed); 357533965Sjdp if (failed) 3576130563Sobrien return FALSE; 357733965Sjdp 3578218822Sdim if (!assign_section_numbers (abfd, link_info)) 3579130563Sobrien return FALSE; 358033965Sjdp 358133965Sjdp /* The backend linker builds symbol table information itself. */ 358260508Sobrien if (link_info == NULL && bfd_get_symcount (abfd) > 0) 358333965Sjdp { 358460508Sobrien /* Non-zero if doing a relocatable link. */ 358560508Sobrien int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC)); 358660508Sobrien 358760508Sobrien if (! swap_out_syms (abfd, &strtab, relocatable_p)) 3588130563Sobrien return FALSE; 358933965Sjdp } 359033965Sjdp 3591104838Sobrien if (link_info == NULL) 359289860Sobrien { 3593104838Sobrien bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); 359489860Sobrien if (failed) 3595130563Sobrien return FALSE; 359689860Sobrien } 359789860Sobrien 359833965Sjdp shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr; 359933965Sjdp /* sh_name was set in prep_headers. */ 360033965Sjdp shstrtab_hdr->sh_type = SHT_STRTAB; 360133965Sjdp shstrtab_hdr->sh_flags = 0; 360233965Sjdp shstrtab_hdr->sh_addr = 0; 360389860Sobrien shstrtab_hdr->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd)); 360433965Sjdp shstrtab_hdr->sh_entsize = 0; 360533965Sjdp shstrtab_hdr->sh_link = 0; 360633965Sjdp shstrtab_hdr->sh_info = 0; 360733965Sjdp /* sh_offset is set in assign_file_positions_except_relocs. */ 360833965Sjdp shstrtab_hdr->sh_addralign = 1; 360933965Sjdp 3610130563Sobrien if (!assign_file_positions_except_relocs (abfd, link_info)) 3611130563Sobrien return FALSE; 361233965Sjdp 361360508Sobrien if (link_info == NULL && bfd_get_symcount (abfd) > 0) 361433965Sjdp { 361533965Sjdp file_ptr off; 361633965Sjdp Elf_Internal_Shdr *hdr; 361733965Sjdp 361833965Sjdp off = elf_tdata (abfd)->next_file_pos; 361933965Sjdp 362033965Sjdp hdr = &elf_tdata (abfd)->symtab_hdr; 3621130563Sobrien off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); 362233965Sjdp 362389860Sobrien hdr = &elf_tdata (abfd)->symtab_shndx_hdr; 362489860Sobrien if (hdr->sh_size != 0) 3625130563Sobrien off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); 362689860Sobrien 362733965Sjdp hdr = &elf_tdata (abfd)->strtab_hdr; 3628130563Sobrien off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); 362933965Sjdp 363033965Sjdp elf_tdata (abfd)->next_file_pos = off; 363133965Sjdp 363233965Sjdp /* Now that we know where the .strtab section goes, write it 3633218822Sdim out. */ 363433965Sjdp if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 363533965Sjdp || ! _bfd_stringtab_emit (abfd, strtab)) 3636130563Sobrien return FALSE; 363733965Sjdp _bfd_stringtab_free (strtab); 363833965Sjdp } 363933965Sjdp 3640130563Sobrien abfd->output_has_begun = TRUE; 364133965Sjdp 3642130563Sobrien return TRUE; 364333965Sjdp} 364433965Sjdp 3645218822Sdim/* Make an initial estimate of the size of the program header. If we 3646218822Sdim get the number wrong here, we'll redo section placement. */ 3647218822Sdim 3648218822Sdimstatic bfd_size_type 3649218822Sdimget_program_header_size (bfd *abfd, struct bfd_link_info *info) 3650218822Sdim{ 3651218822Sdim size_t segs; 3652218822Sdim asection *s; 3653218822Sdim const struct elf_backend_data *bed; 3654218822Sdim 3655218822Sdim /* Assume we will need exactly two PT_LOAD segments: one for text 3656218822Sdim and one for data. */ 3657218822Sdim segs = 2; 3658218822Sdim 3659218822Sdim s = bfd_get_section_by_name (abfd, ".interp"); 3660218822Sdim if (s != NULL && (s->flags & SEC_LOAD) != 0) 3661218822Sdim { 3662218822Sdim /* If we have a loadable interpreter section, we need a 3663218822Sdim PT_INTERP segment. In this case, assume we also need a 3664218822Sdim PT_PHDR segment, although that may not be true for all 3665218822Sdim targets. */ 3666218822Sdim segs += 2; 3667218822Sdim } 3668218822Sdim 3669218822Sdim if (bfd_get_section_by_name (abfd, ".dynamic") != NULL) 3670218822Sdim { 3671218822Sdim /* We need a PT_DYNAMIC segment. */ 3672218822Sdim ++segs; 3673218822Sdim 3674218822Sdim if (elf_tdata (abfd)->relro) 3675218822Sdim { 3676218822Sdim /* We need a PT_GNU_RELRO segment only when there is a 3677218822Sdim PT_DYNAMIC segment. */ 3678218822Sdim ++segs; 3679218822Sdim } 3680218822Sdim } 3681218822Sdim 3682218822Sdim if (elf_tdata (abfd)->eh_frame_hdr) 3683218822Sdim { 3684218822Sdim /* We need a PT_GNU_EH_FRAME segment. */ 3685218822Sdim ++segs; 3686218822Sdim } 3687218822Sdim 3688218822Sdim if (elf_tdata (abfd)->stack_flags) 3689218822Sdim { 3690218822Sdim /* We need a PT_GNU_STACK segment. */ 3691218822Sdim ++segs; 3692218822Sdim } 3693218822Sdim 3694218822Sdim for (s = abfd->sections; s != NULL; s = s->next) 3695218822Sdim { 3696218822Sdim if ((s->flags & SEC_LOAD) != 0 3697218822Sdim && CONST_STRNEQ (s->name, ".note")) 3698218822Sdim { 3699218822Sdim /* We need a PT_NOTE segment. */ 3700218822Sdim ++segs; 3701218822Sdim } 3702218822Sdim } 3703218822Sdim 3704218822Sdim for (s = abfd->sections; s != NULL; s = s->next) 3705218822Sdim { 3706218822Sdim if (s->flags & SEC_THREAD_LOCAL) 3707218822Sdim { 3708218822Sdim /* We need a PT_TLS segment. */ 3709218822Sdim ++segs; 3710218822Sdim break; 3711218822Sdim } 3712218822Sdim } 3713218822Sdim 3714218822Sdim /* Let the backend count up any program headers it might need. */ 3715218822Sdim bed = get_elf_backend_data (abfd); 3716218822Sdim if (bed->elf_backend_additional_program_headers) 3717218822Sdim { 3718218822Sdim int a; 3719218822Sdim 3720218822Sdim a = (*bed->elf_backend_additional_program_headers) (abfd, info); 3721218822Sdim if (a == -1) 3722218822Sdim abort (); 3723218822Sdim segs += a; 3724218822Sdim } 3725218822Sdim 3726218822Sdim return segs * bed->s->sizeof_phdr; 3727218822Sdim} 3728218822Sdim 372933965Sjdp/* Create a mapping from a set of sections to a program segment. */ 373033965Sjdp 3731130563Sobrienstatic struct elf_segment_map * 3732130563Sobrienmake_mapping (bfd *abfd, 3733130563Sobrien asection **sections, 3734130563Sobrien unsigned int from, 3735130563Sobrien unsigned int to, 3736130563Sobrien bfd_boolean phdr) 373733965Sjdp{ 373833965Sjdp struct elf_segment_map *m; 373933965Sjdp unsigned int i; 374033965Sjdp asection **hdrpp; 374189860Sobrien bfd_size_type amt; 374233965Sjdp 374389860Sobrien amt = sizeof (struct elf_segment_map); 374489860Sobrien amt += (to - from - 1) * sizeof (asection *); 3745130563Sobrien m = bfd_zalloc (abfd, amt); 374633965Sjdp if (m == NULL) 374733965Sjdp return NULL; 374833965Sjdp m->next = NULL; 374933965Sjdp m->p_type = PT_LOAD; 375033965Sjdp for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++) 375133965Sjdp m->sections[i - from] = *hdrpp; 375233965Sjdp m->count = to - from; 375333965Sjdp 375433965Sjdp if (from == 0 && phdr) 375533965Sjdp { 375633965Sjdp /* Include the headers in the first PT_LOAD segment. */ 375733965Sjdp m->includes_filehdr = 1; 375833965Sjdp m->includes_phdrs = 1; 375933965Sjdp } 376033965Sjdp 376133965Sjdp return m; 376233965Sjdp} 376333965Sjdp 3764218822Sdim/* Create the PT_DYNAMIC segment, which includes DYNSEC. Returns NULL 3765218822Sdim on failure. */ 376633965Sjdp 3767218822Sdimstruct elf_segment_map * 3768218822Sdim_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec) 376933965Sjdp{ 377033965Sjdp struct elf_segment_map *m; 377133965Sjdp 3772218822Sdim m = bfd_zalloc (abfd, sizeof (struct elf_segment_map)); 3773218822Sdim if (m == NULL) 3774218822Sdim return NULL; 3775218822Sdim m->next = NULL; 3776218822Sdim m->p_type = PT_DYNAMIC; 3777218822Sdim m->count = 1; 3778218822Sdim m->sections[0] = dynsec; 377933965Sjdp 3780218822Sdim return m; 3781218822Sdim} 378233965Sjdp 3783218822Sdim/* Possibly add or remove segments from the segment map. */ 378433965Sjdp 3785218822Sdimstatic bfd_boolean 3786218822Sdimelf_modify_segment_map (bfd *abfd, struct bfd_link_info *info) 3787218822Sdim{ 3788218822Sdim struct elf_segment_map **m; 3789218822Sdim const struct elf_backend_data *bed; 379033965Sjdp 3791218822Sdim /* The placement algorithm assumes that non allocated sections are 3792218822Sdim not in PT_LOAD segments. We ensure this here by removing such 3793218822Sdim sections from the segment map. We also remove excluded 3794218822Sdim sections. Finally, any PT_LOAD segment without sections is 3795218822Sdim removed. */ 3796218822Sdim m = &elf_tdata (abfd)->segment_map; 3797218822Sdim while (*m) 379833965Sjdp { 3799218822Sdim unsigned int i, new_count; 3800218822Sdim 3801218822Sdim for (new_count = 0, i = 0; i < (*m)->count; i++) 380233965Sjdp { 3803218822Sdim if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0 3804218822Sdim && (((*m)->sections[i]->flags & SEC_ALLOC) != 0 3805218822Sdim || (*m)->p_type != PT_LOAD)) 3806218822Sdim { 3807218822Sdim (*m)->sections[new_count] = (*m)->sections[i]; 3808218822Sdim new_count++; 3809218822Sdim } 381033965Sjdp } 3811218822Sdim (*m)->count = new_count; 3812218822Sdim 3813218822Sdim if ((*m)->p_type == PT_LOAD && (*m)->count == 0) 3814218822Sdim *m = (*m)->next; 3815218822Sdim else 3816218822Sdim m = &(*m)->next; 381733965Sjdp } 381833965Sjdp 3819218822Sdim bed = get_elf_backend_data (abfd); 3820218822Sdim if (bed->elf_backend_modify_segment_map != NULL) 3821218822Sdim { 3822218822Sdim if (!(*bed->elf_backend_modify_segment_map) (abfd, info)) 3823218822Sdim return FALSE; 3824218822Sdim } 382533965Sjdp 3826218822Sdim return TRUE; 3827218822Sdim} 382833965Sjdp 3829218822Sdim/* Set up a mapping from BFD sections to program segments. */ 383033965Sjdp 3831218822Sdimbfd_boolean 3832218822Sdim_bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) 3833218822Sdim{ 3834218822Sdim unsigned int count; 3835218822Sdim struct elf_segment_map *m; 3836218822Sdim asection **sections = NULL; 3837218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 3838218822Sdim 3839218822Sdim if (elf_tdata (abfd)->segment_map == NULL 3840218822Sdim && bfd_count_sections (abfd) != 0) 384133965Sjdp { 3842218822Sdim asection *s; 3843218822Sdim unsigned int i; 3844218822Sdim struct elf_segment_map *mfirst; 3845218822Sdim struct elf_segment_map **pm; 3846218822Sdim asection *last_hdr; 3847218822Sdim bfd_vma last_size; 3848218822Sdim unsigned int phdr_index; 3849218822Sdim bfd_vma maxpagesize; 3850218822Sdim asection **hdrpp; 3851218822Sdim bfd_boolean phdr_in_segment = TRUE; 3852218822Sdim bfd_boolean writable; 3853218822Sdim int tls_count = 0; 3854218822Sdim asection *first_tls = NULL; 3855218822Sdim asection *dynsec, *eh_frame_hdr; 3856218822Sdim bfd_size_type amt; 385733965Sjdp 3858218822Sdim /* Select the allocated sections, and sort them. */ 385933965Sjdp 3860218822Sdim sections = bfd_malloc2 (bfd_count_sections (abfd), sizeof (asection *)); 3861218822Sdim if (sections == NULL) 386233965Sjdp goto error_return; 386333965Sjdp 3864218822Sdim i = 0; 3865218822Sdim for (s = abfd->sections; s != NULL; s = s->next) 3866218822Sdim { 3867218822Sdim if ((s->flags & SEC_ALLOC) != 0) 3868218822Sdim { 3869218822Sdim sections[i] = s; 3870218822Sdim ++i; 3871218822Sdim } 3872218822Sdim } 3873218822Sdim BFD_ASSERT (i <= bfd_count_sections (abfd)); 3874218822Sdim count = i; 387533965Sjdp 3876218822Sdim qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections); 387733965Sjdp 3878218822Sdim /* Build the mapping. */ 387933965Sjdp 3880218822Sdim mfirst = NULL; 3881218822Sdim pm = &mfirst; 388233965Sjdp 3883218822Sdim /* If we have a .interp section, then create a PT_PHDR segment for 3884218822Sdim the program headers and a PT_INTERP segment for the .interp 3885218822Sdim section. */ 3886218822Sdim s = bfd_get_section_by_name (abfd, ".interp"); 3887218822Sdim if (s != NULL && (s->flags & SEC_LOAD) != 0) 3888218822Sdim { 3889218822Sdim amt = sizeof (struct elf_segment_map); 3890218822Sdim m = bfd_zalloc (abfd, amt); 3891218822Sdim if (m == NULL) 3892218822Sdim goto error_return; 3893218822Sdim m->next = NULL; 3894218822Sdim m->p_type = PT_PHDR; 3895218822Sdim /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not. */ 3896218822Sdim m->p_flags = PF_R | PF_X; 3897218822Sdim m->p_flags_valid = 1; 3898218822Sdim m->includes_phdrs = 1; 389933965Sjdp 3900218822Sdim *pm = m; 3901218822Sdim pm = &m->next; 390233965Sjdp 3903218822Sdim amt = sizeof (struct elf_segment_map); 3904218822Sdim m = bfd_zalloc (abfd, amt); 3905218822Sdim if (m == NULL) 3906218822Sdim goto error_return; 3907218822Sdim m->next = NULL; 3908218822Sdim m->p_type = PT_INTERP; 3909218822Sdim m->count = 1; 3910218822Sdim m->sections[0] = s; 391133965Sjdp 3912218822Sdim *pm = m; 3913218822Sdim pm = &m->next; 391433965Sjdp } 3915218822Sdim 3916218822Sdim /* Look through the sections. We put sections in the same program 3917218822Sdim segment when the start of the second section can be placed within 3918218822Sdim a few bytes of the end of the first section. */ 3919218822Sdim last_hdr = NULL; 3920218822Sdim last_size = 0; 3921218822Sdim phdr_index = 0; 3922218822Sdim maxpagesize = bed->maxpagesize; 3923218822Sdim writable = FALSE; 3924218822Sdim dynsec = bfd_get_section_by_name (abfd, ".dynamic"); 3925218822Sdim if (dynsec != NULL 3926218822Sdim && (dynsec->flags & SEC_LOAD) == 0) 3927218822Sdim dynsec = NULL; 3928218822Sdim 3929218822Sdim /* Deal with -Ttext or something similar such that the first section 3930218822Sdim is not adjacent to the program headers. This is an 3931218822Sdim approximation, since at this point we don't know exactly how many 3932218822Sdim program headers we will need. */ 3933218822Sdim if (count > 0) 393433965Sjdp { 3935218822Sdim bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size; 3936218822Sdim 3937218822Sdim if (phdr_size == (bfd_size_type) -1) 3938218822Sdim phdr_size = get_program_header_size (abfd, info); 3939218822Sdim if ((abfd->flags & D_PAGED) == 0 3940218822Sdim || sections[0]->lma < phdr_size 3941218822Sdim || sections[0]->lma % maxpagesize < phdr_size % maxpagesize) 3942218822Sdim phdr_in_segment = FALSE; 394333965Sjdp } 3944218822Sdim 3945218822Sdim for (i = 0, hdrpp = sections; i < count; i++, hdrpp++) 394633965Sjdp { 3947218822Sdim asection *hdr; 3948218822Sdim bfd_boolean new_segment; 394933965Sjdp 3950218822Sdim hdr = *hdrpp; 3951218822Sdim 3952218822Sdim /* See if this section and the last one will fit in the same 3953218822Sdim segment. */ 3954218822Sdim 3955218822Sdim if (last_hdr == NULL) 3956218822Sdim { 3957218822Sdim /* If we don't have a segment yet, then we don't need a new 3958218822Sdim one (we build the last one after this loop). */ 3959218822Sdim new_segment = FALSE; 3960218822Sdim } 3961218822Sdim else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma) 3962218822Sdim { 3963218822Sdim /* If this section has a different relation between the 3964218822Sdim virtual address and the load address, then we need a new 3965218822Sdim segment. */ 3966218822Sdim new_segment = TRUE; 3967218822Sdim } 3968218822Sdim else if (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) 3969218822Sdim < BFD_ALIGN (hdr->lma, maxpagesize)) 3970218822Sdim { 3971218822Sdim /* If putting this section in this segment would force us to 3972218822Sdim skip a page in the segment, then we need a new segment. */ 3973218822Sdim new_segment = TRUE; 3974218822Sdim } 3975218822Sdim else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0 3976218822Sdim && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0) 3977218822Sdim { 3978218822Sdim /* We don't want to put a loadable section after a 3979218822Sdim nonloadable section in the same segment. 3980218822Sdim Consider .tbss sections as loadable for this purpose. */ 3981218822Sdim new_segment = TRUE; 3982218822Sdim } 3983218822Sdim else if ((abfd->flags & D_PAGED) == 0) 3984218822Sdim { 3985218822Sdim /* If the file is not demand paged, which means that we 3986218822Sdim don't require the sections to be correctly aligned in the 3987218822Sdim file, then there is no other reason for a new segment. */ 3988218822Sdim new_segment = FALSE; 3989218822Sdim } 3990218822Sdim else if (! writable 3991218822Sdim && (hdr->flags & SEC_READONLY) == 0 3992218822Sdim && (((last_hdr->lma + last_size - 1) 3993218822Sdim & ~(maxpagesize - 1)) 3994218822Sdim != (hdr->lma & ~(maxpagesize - 1)))) 3995218822Sdim { 3996218822Sdim /* We don't want to put a writable section in a read only 3997218822Sdim segment, unless they are on the same page in memory 3998218822Sdim anyhow. We already know that the last section does not 3999218822Sdim bring us past the current section on the page, so the 4000218822Sdim only case in which the new section is not on the same 4001218822Sdim page as the previous section is when the previous section 4002218822Sdim ends precisely on a page boundary. */ 4003218822Sdim new_segment = TRUE; 4004218822Sdim } 4005218822Sdim else 4006218822Sdim { 4007218822Sdim /* Otherwise, we can use the same segment. */ 4008218822Sdim new_segment = FALSE; 4009218822Sdim } 4010218822Sdim 4011218822Sdim /* Allow interested parties a chance to override our decision. */ 4012218822Sdim if (last_hdr && info->callbacks->override_segment_assignment) 4013218822Sdim new_segment = info->callbacks->override_segment_assignment (info, abfd, hdr, last_hdr, new_segment); 4014218822Sdim 4015218822Sdim if (! new_segment) 4016218822Sdim { 4017218822Sdim if ((hdr->flags & SEC_READONLY) == 0) 4018218822Sdim writable = TRUE; 4019218822Sdim last_hdr = hdr; 4020218822Sdim /* .tbss sections effectively have zero size. */ 4021218822Sdim if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) 4022218822Sdim != SEC_THREAD_LOCAL) 4023218822Sdim last_size = hdr->size; 4024218822Sdim else 4025218822Sdim last_size = 0; 4026218822Sdim continue; 4027218822Sdim } 4028218822Sdim 4029218822Sdim /* We need a new program segment. We must create a new program 4030218822Sdim header holding all the sections from phdr_index until hdr. */ 4031218822Sdim 4032218822Sdim m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment); 4033218822Sdim if (m == NULL) 4034218822Sdim goto error_return; 4035218822Sdim 4036218822Sdim *pm = m; 4037218822Sdim pm = &m->next; 4038218822Sdim 403933965Sjdp if ((hdr->flags & SEC_READONLY) == 0) 4040130563Sobrien writable = TRUE; 4041218822Sdim else 4042218822Sdim writable = FALSE; 4043218822Sdim 404433965Sjdp last_hdr = hdr; 4045130563Sobrien /* .tbss sections effectively have zero size. */ 4046130563Sobrien if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL) 4047218822Sdim last_size = hdr->size; 4048130563Sobrien else 4049130563Sobrien last_size = 0; 4050218822Sdim phdr_index = i; 4051218822Sdim phdr_in_segment = FALSE; 405233965Sjdp } 405333965Sjdp 4054218822Sdim /* Create a final PT_LOAD program segment. */ 4055218822Sdim if (last_hdr != NULL) 4056218822Sdim { 4057218822Sdim m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment); 4058218822Sdim if (m == NULL) 4059218822Sdim goto error_return; 406033965Sjdp 4061218822Sdim *pm = m; 4062218822Sdim pm = &m->next; 4063218822Sdim } 406433965Sjdp 4065218822Sdim /* If there is a .dynamic section, throw in a PT_DYNAMIC segment. */ 4066218822Sdim if (dynsec != NULL) 4067218822Sdim { 4068218822Sdim m = _bfd_elf_make_dynamic_segment (abfd, dynsec); 4069218822Sdim if (m == NULL) 4070218822Sdim goto error_return; 4071218822Sdim *pm = m; 4072218822Sdim pm = &m->next; 4073218822Sdim } 407433965Sjdp 4075218822Sdim /* For each loadable .note section, add a PT_NOTE segment. We don't 4076218822Sdim use bfd_get_section_by_name, because if we link together 4077218822Sdim nonloadable .note sections and loadable .note sections, we will 4078218822Sdim generate two .note sections in the output file. FIXME: Using 4079218822Sdim names for section types is bogus anyhow. */ 4080218822Sdim for (s = abfd->sections; s != NULL; s = s->next) 4081218822Sdim { 4082218822Sdim if ((s->flags & SEC_LOAD) != 0 4083218822Sdim && CONST_STRNEQ (s->name, ".note")) 4084218822Sdim { 4085218822Sdim amt = sizeof (struct elf_segment_map); 4086218822Sdim m = bfd_zalloc (abfd, amt); 4087218822Sdim if (m == NULL) 4088218822Sdim goto error_return; 4089218822Sdim m->next = NULL; 4090218822Sdim m->p_type = PT_NOTE; 4091218822Sdim m->count = 1; 4092218822Sdim m->sections[0] = s; 409333965Sjdp 4094218822Sdim *pm = m; 4095218822Sdim pm = &m->next; 4096218822Sdim } 4097218822Sdim if (s->flags & SEC_THREAD_LOCAL) 4098218822Sdim { 4099218822Sdim if (! tls_count) 4100218822Sdim first_tls = s; 4101218822Sdim tls_count++; 4102218822Sdim } 4103218822Sdim } 410433965Sjdp 4105218822Sdim /* If there are any SHF_TLS output sections, add PT_TLS segment. */ 4106218822Sdim if (tls_count > 0) 4107218822Sdim { 4108218822Sdim int i; 410933965Sjdp 4110218822Sdim amt = sizeof (struct elf_segment_map); 4111218822Sdim amt += (tls_count - 1) * sizeof (asection *); 4112218822Sdim m = bfd_zalloc (abfd, amt); 4113218822Sdim if (m == NULL) 4114218822Sdim goto error_return; 4115218822Sdim m->next = NULL; 4116218822Sdim m->p_type = PT_TLS; 4117218822Sdim m->count = tls_count; 4118218822Sdim /* Mandated PF_R. */ 4119218822Sdim m->p_flags = PF_R; 4120218822Sdim m->p_flags_valid = 1; 4121218822Sdim for (i = 0; i < tls_count; ++i) 4122218822Sdim { 4123218822Sdim BFD_ASSERT (first_tls->flags & SEC_THREAD_LOCAL); 4124218822Sdim m->sections[i] = first_tls; 4125218822Sdim first_tls = first_tls->next; 4126218822Sdim } 412733965Sjdp 4128218822Sdim *pm = m; 4129218822Sdim pm = &m->next; 4130218822Sdim } 413133965Sjdp 4132218822Sdim /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME 4133218822Sdim segment. */ 4134218822Sdim eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr; 4135218822Sdim if (eh_frame_hdr != NULL 4136218822Sdim && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0) 413733965Sjdp { 413889860Sobrien amt = sizeof (struct elf_segment_map); 4139130563Sobrien m = bfd_zalloc (abfd, amt); 414033965Sjdp if (m == NULL) 414133965Sjdp goto error_return; 414233965Sjdp m->next = NULL; 4143218822Sdim m->p_type = PT_GNU_EH_FRAME; 414433965Sjdp m->count = 1; 4145218822Sdim m->sections[0] = eh_frame_hdr->output_section; 414633965Sjdp 414733965Sjdp *pm = m; 414833965Sjdp pm = &m->next; 414933965Sjdp } 4150218822Sdim 4151218822Sdim if (elf_tdata (abfd)->stack_flags) 4152104838Sobrien { 4153218822Sdim amt = sizeof (struct elf_segment_map); 4154218822Sdim m = bfd_zalloc (abfd, amt); 4155218822Sdim if (m == NULL) 4156218822Sdim goto error_return; 4157218822Sdim m->next = NULL; 4158218822Sdim m->p_type = PT_GNU_STACK; 4159218822Sdim m->p_flags = elf_tdata (abfd)->stack_flags; 4160218822Sdim m->p_flags_valid = 1; 4161218822Sdim 4162218822Sdim *pm = m; 4163218822Sdim pm = &m->next; 4164104838Sobrien } 416533965Sjdp 4166218822Sdim if (dynsec != NULL && elf_tdata (abfd)->relro) 4167218822Sdim { 4168218822Sdim /* We make a PT_GNU_RELRO segment only when there is a 4169218822Sdim PT_DYNAMIC segment. */ 4170218822Sdim amt = sizeof (struct elf_segment_map); 4171218822Sdim m = bfd_zalloc (abfd, amt); 4172218822Sdim if (m == NULL) 4173218822Sdim goto error_return; 4174218822Sdim m->next = NULL; 4175218822Sdim m->p_type = PT_GNU_RELRO; 4176218822Sdim m->p_flags = PF_R; 4177218822Sdim m->p_flags_valid = 1; 4178104838Sobrien 4179218822Sdim *pm = m; 4180218822Sdim pm = &m->next; 4181104838Sobrien } 4182104838Sobrien 4183218822Sdim free (sections); 4184218822Sdim elf_tdata (abfd)->segment_map = mfirst; 4185104838Sobrien } 4186104838Sobrien 4187218822Sdim if (!elf_modify_segment_map (abfd, info)) 4188218822Sdim return FALSE; 418989860Sobrien 4190218822Sdim for (count = 0, m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) 4191218822Sdim ++count; 4192218822Sdim elf_tdata (abfd)->program_header_size = count * bed->s->sizeof_phdr; 419389860Sobrien 4194130563Sobrien return TRUE; 419533965Sjdp 419633965Sjdp error_return: 419733965Sjdp if (sections != NULL) 419833965Sjdp free (sections); 4199130563Sobrien return FALSE; 420033965Sjdp} 420133965Sjdp 420260508Sobrien/* Sort sections by address. */ 420333965Sjdp 420433965Sjdpstatic int 4205130563Sobrienelf_sort_sections (const void *arg1, const void *arg2) 420633965Sjdp{ 420733965Sjdp const asection *sec1 = *(const asection **) arg1; 420833965Sjdp const asection *sec2 = *(const asection **) arg2; 4209130563Sobrien bfd_size_type size1, size2; 421033965Sjdp 421160508Sobrien /* Sort by LMA first, since this is the address used to 421260508Sobrien place the section into a segment. */ 421360508Sobrien if (sec1->lma < sec2->lma) 421433965Sjdp return -1; 421560508Sobrien else if (sec1->lma > sec2->lma) 421633965Sjdp return 1; 421733965Sjdp 421860508Sobrien /* Then sort by VMA. Normally the LMA and the VMA will be 421960508Sobrien the same, and this will do nothing. */ 422060508Sobrien if (sec1->vma < sec2->vma) 422133965Sjdp return -1; 422260508Sobrien else if (sec1->vma > sec2->vma) 422333965Sjdp return 1; 422433965Sjdp 422533965Sjdp /* Put !SEC_LOAD sections after SEC_LOAD ones. */ 422633965Sjdp 4227130563Sobrien#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0) 422833965Sjdp 422933965Sjdp if (TOEND (sec1)) 423038891Sjdp { 423138891Sjdp if (TOEND (sec2)) 423289860Sobrien { 423389860Sobrien /* If the indicies are the same, do not return 0 423489860Sobrien here, but continue to try the next comparison. */ 423589860Sobrien if (sec1->target_index - sec2->target_index != 0) 423689860Sobrien return sec1->target_index - sec2->target_index; 423789860Sobrien } 423860508Sobrien else 423938891Sjdp return 1; 424038891Sjdp } 424189860Sobrien else if (TOEND (sec2)) 424233965Sjdp return -1; 424333965Sjdp 424433965Sjdp#undef TOEND 424533965Sjdp 424689860Sobrien /* Sort by size, to put zero sized sections 424789860Sobrien before others at the same address. */ 424833965Sjdp 4249218822Sdim size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0; 4250218822Sdim size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0; 4251130563Sobrien 4252130563Sobrien if (size1 < size2) 425333965Sjdp return -1; 4254130563Sobrien if (size1 > size2) 425533965Sjdp return 1; 425633965Sjdp 425733965Sjdp return sec1->target_index - sec2->target_index; 425833965Sjdp} 425933965Sjdp 4260130563Sobrien/* Ian Lance Taylor writes: 4261130563Sobrien 4262130563Sobrien We shouldn't be using % with a negative signed number. That's just 4263130563Sobrien not good. We have to make sure either that the number is not 4264130563Sobrien negative, or that the number has an unsigned type. When the types 4265130563Sobrien are all the same size they wind up as unsigned. When file_ptr is a 4266130563Sobrien larger signed type, the arithmetic winds up as signed long long, 4267130563Sobrien which is wrong. 4268130563Sobrien 4269130563Sobrien What we're trying to say here is something like ``increase OFF by 4270130563Sobrien the least amount that will cause it to be equal to the VMA modulo 4271130563Sobrien the page size.'' */ 4272130563Sobrien/* In other words, something like: 4273130563Sobrien 4274130563Sobrien vma_offset = m->sections[0]->vma % bed->maxpagesize; 4275130563Sobrien off_offset = off % bed->maxpagesize; 4276130563Sobrien if (vma_offset < off_offset) 4277130563Sobrien adjustment = vma_offset + bed->maxpagesize - off_offset; 4278130563Sobrien else 4279130563Sobrien adjustment = vma_offset - off_offset; 4280218822Sdim 4281130563Sobrien which can can be collapsed into the expression below. */ 4282130563Sobrien 4283130563Sobrienstatic file_ptr 4284130563Sobrienvma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize) 4285130563Sobrien{ 4286130563Sobrien return ((vma - off) % maxpagesize); 4287130563Sobrien} 4288130563Sobrien 428933965Sjdp/* Assign file positions to the sections based on the mapping from 429033965Sjdp sections to segments. This function also sets up some fields in 4291218822Sdim the file header. */ 429233965Sjdp 4293130563Sobrienstatic bfd_boolean 4294218822Sdimassign_file_positions_for_load_sections (bfd *abfd, 4295218822Sdim struct bfd_link_info *link_info) 429633965Sjdp{ 429733965Sjdp const struct elf_backend_data *bed = get_elf_backend_data (abfd); 429833965Sjdp struct elf_segment_map *m; 429933965Sjdp Elf_Internal_Phdr *phdrs; 430033965Sjdp Elf_Internal_Phdr *p; 4301218822Sdim file_ptr off; 4302218822Sdim bfd_size_type maxpagesize; 4303218822Sdim unsigned int alloc; 4304218822Sdim unsigned int i, j; 430533965Sjdp 4306218822Sdim if (link_info == NULL 4307218822Sdim && !elf_modify_segment_map (abfd, link_info)) 4308218822Sdim return FALSE; 430933965Sjdp 4310218822Sdim alloc = 0; 431133965Sjdp for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) 4312218822Sdim ++alloc; 431333965Sjdp 431433965Sjdp elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr; 431533965Sjdp elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr; 4316218822Sdim elf_elfheader (abfd)->e_phnum = alloc; 431733965Sjdp 4318218822Sdim if (elf_tdata (abfd)->program_header_size == (bfd_size_type) -1) 4319218822Sdim elf_tdata (abfd)->program_header_size = alloc * bed->s->sizeof_phdr; 4320218822Sdim else 4321218822Sdim BFD_ASSERT (elf_tdata (abfd)->program_header_size 4322218822Sdim >= alloc * bed->s->sizeof_phdr); 432333965Sjdp 4324218822Sdim if (alloc == 0) 432533965Sjdp { 4326218822Sdim elf_tdata (abfd)->next_file_pos = bed->s->sizeof_ehdr; 4327218822Sdim return TRUE; 432833965Sjdp } 432933965Sjdp 4330218822Sdim phdrs = bfd_alloc2 (abfd, alloc, sizeof (Elf_Internal_Phdr)); 4331218822Sdim elf_tdata (abfd)->phdr = phdrs; 433233965Sjdp if (phdrs == NULL) 4333130563Sobrien return FALSE; 433433965Sjdp 4335218822Sdim maxpagesize = 1; 4336218822Sdim if ((abfd->flags & D_PAGED) != 0) 4337218822Sdim maxpagesize = bed->maxpagesize; 4338218822Sdim 433933965Sjdp off = bed->s->sizeof_ehdr; 434033965Sjdp off += alloc * bed->s->sizeof_phdr; 434133965Sjdp 4342218822Sdim for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0; 434333965Sjdp m != NULL; 4344218822Sdim m = m->next, p++, j++) 434533965Sjdp { 434633965Sjdp asection **secpp; 4347218822Sdim bfd_vma off_adjust; 4348218822Sdim bfd_boolean no_contents; 434933965Sjdp 435033965Sjdp /* If elf_segment_map is not from map_sections_to_segments, the 4351218822Sdim sections may not be correctly ordered. NOTE: sorting should 435289860Sobrien not be done to the PT_NOTE section of a corefile, which may 435389860Sobrien contain several pseudo-sections artificially created by bfd. 435489860Sobrien Sorting these pseudo-sections breaks things badly. */ 4355104838Sobrien if (m->count > 1 4356104838Sobrien && !(elf_elfheader (abfd)->e_type == ET_CORE 435789860Sobrien && m->p_type == PT_NOTE)) 435833965Sjdp qsort (m->sections, (size_t) m->count, sizeof (asection *), 435933965Sjdp elf_sort_sections); 436033965Sjdp 4361218822Sdim /* An ELF segment (described by Elf_Internal_Phdr) may contain a 4362218822Sdim number of sections with contents contributing to both p_filesz 4363218822Sdim and p_memsz, followed by a number of sections with no contents 4364218822Sdim that just contribute to p_memsz. In this loop, OFF tracks next 4365218822Sdim available file offset for PT_LOAD and PT_NOTE segments. */ 436633965Sjdp p->p_type = m->p_type; 436760508Sobrien p->p_flags = m->p_flags; 436833965Sjdp 436933965Sjdp if (m->count == 0) 437033965Sjdp p->p_vaddr = 0; 437133965Sjdp else 4372218822Sdim p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset; 437333965Sjdp 437433965Sjdp if (m->p_paddr_valid) 437533965Sjdp p->p_paddr = m->p_paddr; 437633965Sjdp else if (m->count == 0) 437733965Sjdp p->p_paddr = 0; 437833965Sjdp else 4379218822Sdim p->p_paddr = m->sections[0]->lma - m->p_vaddr_offset; 438033965Sjdp 438133965Sjdp if (p->p_type == PT_LOAD 438233965Sjdp && (abfd->flags & D_PAGED) != 0) 4383218822Sdim { 4384218822Sdim /* p_align in demand paged PT_LOAD segments effectively stores 4385218822Sdim the maximum page size. When copying an executable with 4386218822Sdim objcopy, we set m->p_align from the input file. Use this 4387218822Sdim value for maxpagesize rather than bed->maxpagesize, which 4388218822Sdim may be different. Note that we use maxpagesize for PT_TLS 4389218822Sdim segment alignment later in this function, so we are relying 4390218822Sdim on at least one PT_LOAD segment appearing before a PT_TLS 4391218822Sdim segment. */ 4392218822Sdim if (m->p_align_valid) 4393218822Sdim maxpagesize = m->p_align; 4394218822Sdim 4395218822Sdim p->p_align = maxpagesize; 4396218822Sdim } 439733965Sjdp else if (m->count == 0) 4398130563Sobrien p->p_align = 1 << bed->s->log_file_align; 4399218822Sdim else if (m->p_align_valid) 4400218822Sdim p->p_align = m->p_align; 440133965Sjdp else 440233965Sjdp p->p_align = 0; 440333965Sjdp 4404218822Sdim no_contents = FALSE; 4405218822Sdim off_adjust = 0; 4406218822Sdim if (p->p_type == PT_NOTE) 4407218822Sdim { 4408218822Sdim for (i = 0; i < m->count; i++) 4409218822Sdim elf_section_type (m->sections[i]) = SHT_NOTE; 4410218822Sdim } 4411218822Sdim else if (p->p_type == PT_LOAD 4412218822Sdim && m->count > 0) 4413218822Sdim { 4414218822Sdim bfd_size_type align; 4415218822Sdim unsigned int align_power = 0; 4416218822Sdim 4417218822Sdim if (m->p_align_valid) 4418218822Sdim align = p->p_align; 4419218822Sdim else 4420218822Sdim { 4421218822Sdim for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) 4422218822Sdim { 4423218822Sdim unsigned int secalign; 4424218822Sdim 4425218822Sdim secalign = bfd_get_section_alignment (abfd, *secpp); 4426218822Sdim if (secalign > align_power) 4427218822Sdim align_power = secalign; 4428218822Sdim } 4429218822Sdim align = (bfd_size_type) 1 << align_power; 4430218822Sdim if (align < maxpagesize) 4431218822Sdim align = maxpagesize; 4432218822Sdim } 4433218822Sdim 4434218822Sdim for (i = 0; i < m->count; i++) 4435218822Sdim if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) 4436218822Sdim /* If we aren't making room for this section, then 4437218822Sdim it must be SHT_NOBITS regardless of what we've 4438218822Sdim set via struct bfd_elf_special_section. */ 4439218822Sdim elf_section_type (m->sections[i]) = SHT_NOBITS; 4440218822Sdim 4441218822Sdim /* Find out whether this segment contains any loadable 4442218822Sdim sections. If the first section isn't loadable, the same 4443218822Sdim holds for any other sections. */ 4444218822Sdim i = 0; 4445218822Sdim while (elf_section_type (m->sections[i]) == SHT_NOBITS) 4446218822Sdim { 4447218822Sdim /* If a segment starts with .tbss, we need to look 4448218822Sdim at the next section to decide whether the segment 4449218822Sdim has any loadable sections. */ 4450218822Sdim if ((elf_section_flags (m->sections[i]) & SHF_TLS) == 0 4451218822Sdim || ++i >= m->count) 4452218822Sdim { 4453218822Sdim no_contents = TRUE; 4454218822Sdim break; 4455218822Sdim } 4456218822Sdim } 4457218822Sdim 4458218822Sdim off_adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align); 4459218822Sdim off += off_adjust; 4460218822Sdim if (no_contents) 4461218822Sdim { 4462218822Sdim /* We shouldn't need to align the segment on disk since 4463218822Sdim the segment doesn't need file space, but the gABI 4464218822Sdim arguably requires the alignment and glibc ld.so 4465218822Sdim checks it. So to comply with the alignment 4466218822Sdim requirement but not waste file space, we adjust 4467218822Sdim p_offset for just this segment. (OFF_ADJUST is 4468218822Sdim subtracted from OFF later.) This may put p_offset 4469218822Sdim past the end of file, but that shouldn't matter. */ 4470218822Sdim } 4471218822Sdim else 4472218822Sdim off_adjust = 0; 4473218822Sdim } 4474218822Sdim /* Make sure the .dynamic section is the first section in the 4475218822Sdim PT_DYNAMIC segment. */ 4476218822Sdim else if (p->p_type == PT_DYNAMIC 4477218822Sdim && m->count > 1 4478218822Sdim && strcmp (m->sections[0]->name, ".dynamic") != 0) 4479218822Sdim { 4480218822Sdim _bfd_error_handler 4481218822Sdim (_("%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"), 4482218822Sdim abfd); 4483218822Sdim bfd_set_error (bfd_error_bad_value); 4484218822Sdim return FALSE; 4485218822Sdim } 4486218822Sdim 448733965Sjdp p->p_offset = 0; 448833965Sjdp p->p_filesz = 0; 448933965Sjdp p->p_memsz = 0; 449033965Sjdp 449133965Sjdp if (m->includes_filehdr) 449233965Sjdp { 4493218822Sdim if (!m->p_flags_valid) 449433965Sjdp p->p_flags |= PF_R; 449533965Sjdp p->p_filesz = bed->s->sizeof_ehdr; 449633965Sjdp p->p_memsz = bed->s->sizeof_ehdr; 449733965Sjdp if (m->count > 0) 449833965Sjdp { 449933965Sjdp BFD_ASSERT (p->p_type == PT_LOAD); 450038891Sjdp 450138891Sjdp if (p->p_vaddr < (bfd_vma) off) 450238891Sjdp { 4503104838Sobrien (*_bfd_error_handler) 4504218822Sdim (_("%B: Not enough room for program headers, try linking with -N"), 4505218822Sdim abfd); 450638891Sjdp bfd_set_error (bfd_error_bad_value); 4507130563Sobrien return FALSE; 450838891Sjdp } 450960508Sobrien 451033965Sjdp p->p_vaddr -= off; 4511218822Sdim if (!m->p_paddr_valid) 451233965Sjdp p->p_paddr -= off; 451333965Sjdp } 451433965Sjdp } 451533965Sjdp 451633965Sjdp if (m->includes_phdrs) 451733965Sjdp { 4518218822Sdim if (!m->p_flags_valid) 451933965Sjdp p->p_flags |= PF_R; 452060508Sobrien 4521218822Sdim if (!m->includes_filehdr) 452233965Sjdp { 452333965Sjdp p->p_offset = bed->s->sizeof_ehdr; 452460508Sobrien 452533965Sjdp if (m->count > 0) 452633965Sjdp { 452733965Sjdp BFD_ASSERT (p->p_type == PT_LOAD); 452833965Sjdp p->p_vaddr -= off - p->p_offset; 4529218822Sdim if (!m->p_paddr_valid) 453033965Sjdp p->p_paddr -= off - p->p_offset; 453133965Sjdp } 453233965Sjdp } 453360508Sobrien 453433965Sjdp p->p_filesz += alloc * bed->s->sizeof_phdr; 453533965Sjdp p->p_memsz += alloc * bed->s->sizeof_phdr; 453633965Sjdp } 453733965Sjdp 453860508Sobrien if (p->p_type == PT_LOAD 453960508Sobrien || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)) 454033965Sjdp { 4541218822Sdim if (!m->includes_filehdr && !m->includes_phdrs) 454233965Sjdp p->p_offset = off; 454333965Sjdp else 454433965Sjdp { 454533965Sjdp file_ptr adjust; 454633965Sjdp 454733965Sjdp adjust = off - (p->p_offset + p->p_filesz); 4548218822Sdim if (!no_contents) 4549218822Sdim p->p_filesz += adjust; 455033965Sjdp p->p_memsz += adjust; 455133965Sjdp } 455233965Sjdp } 455333965Sjdp 4554218822Sdim /* Set up p_filesz, p_memsz, p_align and p_flags from the section 4555218822Sdim maps. Set filepos for sections in PT_LOAD segments, and in 4556218822Sdim core files, for sections in PT_NOTE segments. 4557218822Sdim assign_file_positions_for_non_load_sections will set filepos 4558218822Sdim for other sections and update p_filesz for other segments. */ 455933965Sjdp for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) 456033965Sjdp { 456133965Sjdp asection *sec; 456233965Sjdp bfd_size_type align; 4563218822Sdim Elf_Internal_Shdr *this_hdr; 456433965Sjdp 456533965Sjdp sec = *secpp; 4566218822Sdim this_hdr = &elf_section_data (sec)->this_hdr; 4567218822Sdim align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec); 456833965Sjdp 4569218822Sdim if (p->p_type == PT_LOAD 4570218822Sdim || p->p_type == PT_TLS) 457160508Sobrien { 4572218822Sdim bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_memsz); 457360508Sobrien 4574218822Sdim if (this_hdr->sh_type != SHT_NOBITS 4575218822Sdim || ((this_hdr->sh_flags & SHF_ALLOC) != 0 4576218822Sdim && ((this_hdr->sh_flags & SHF_TLS) == 0 4577218822Sdim || p->p_type == PT_TLS))) 4578130563Sobrien { 457960508Sobrien if (adjust < 0) 4580218822Sdim { 4581218822Sdim (*_bfd_error_handler) 4582218822Sdim (_("%B: section %A lma 0x%lx overlaps previous sections"), 4583218822Sdim abfd, sec, (unsigned long) sec->lma); 4584218822Sdim adjust = 0; 4585218822Sdim } 4586218822Sdim p->p_memsz += adjust; 458733965Sjdp 4588218822Sdim if (this_hdr->sh_type != SHT_NOBITS) 458960508Sobrien { 4590218822Sdim off += adjust; 4591218822Sdim p->p_filesz += adjust; 459260508Sobrien } 459338891Sjdp } 459433965Sjdp } 459533965Sjdp 459660508Sobrien if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core) 459760508Sobrien { 4598218822Sdim /* The section at i == 0 is the one that actually contains 4599218822Sdim everything. */ 460077301Sobrien if (i == 0) 460177301Sobrien { 4602218822Sdim this_hdr->sh_offset = sec->filepos = off; 4603218822Sdim off += this_hdr->sh_size; 4604218822Sdim p->p_filesz = this_hdr->sh_size; 4605218822Sdim p->p_memsz = 0; 4606218822Sdim p->p_align = 1; 460760508Sobrien } 460877301Sobrien else 460960508Sobrien { 4610218822Sdim /* The rest are fake sections that shouldn't be written. */ 461160508Sobrien sec->filepos = 0; 4612218822Sdim sec->size = 0; 4613218822Sdim sec->flags = 0; 4614218822Sdim continue; 461560508Sobrien } 461660508Sobrien } 461760508Sobrien else 461860508Sobrien { 4619218822Sdim if (p->p_type == PT_LOAD) 4620218822Sdim { 4621218822Sdim this_hdr->sh_offset = sec->filepos = off; 4622218822Sdim if (this_hdr->sh_type != SHT_NOBITS) 4623218822Sdim off += this_hdr->sh_size; 4624218822Sdim } 462533965Sjdp 4626218822Sdim if (this_hdr->sh_type != SHT_NOBITS) 4627104838Sobrien { 4628218822Sdim p->p_filesz += this_hdr->sh_size; 4629218822Sdim /* A load section without SHF_ALLOC is something like 4630218822Sdim a note section in a PT_NOTE segment. These take 4631218822Sdim file space but are not loaded into memory. */ 4632218822Sdim if ((this_hdr->sh_flags & SHF_ALLOC) != 0) 4633218822Sdim p->p_memsz += this_hdr->sh_size; 4634218822Sdim } 4635218822Sdim else if ((this_hdr->sh_flags & SHF_ALLOC) != 0) 4636218822Sdim { 4637218822Sdim if (p->p_type == PT_TLS) 4638218822Sdim p->p_memsz += this_hdr->sh_size; 4639104838Sobrien 4640218822Sdim /* .tbss is special. It doesn't contribute to p_memsz of 4641218822Sdim normal segments. */ 4642218822Sdim else if ((this_hdr->sh_flags & SHF_TLS) == 0) 4643218822Sdim p->p_memsz += this_hdr->sh_size; 4644104838Sobrien } 4645104838Sobrien 4646218822Sdim if (p->p_type == PT_GNU_RELRO) 4647218822Sdim p->p_align = 1; 4648218822Sdim else if (align > p->p_align 4649218822Sdim && !m->p_align_valid 4650218822Sdim && (p->p_type != PT_LOAD 4651218822Sdim || (abfd->flags & D_PAGED) == 0)) 465260508Sobrien p->p_align = align; 465360508Sobrien } 465433965Sjdp 4655218822Sdim if (!m->p_flags_valid) 465633965Sjdp { 465733965Sjdp p->p_flags |= PF_R; 4658218822Sdim if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0) 465933965Sjdp p->p_flags |= PF_X; 4660218822Sdim if ((this_hdr->sh_flags & SHF_WRITE) != 0) 466133965Sjdp p->p_flags |= PF_W; 466233965Sjdp } 466333965Sjdp } 4664218822Sdim off -= off_adjust; 466533965Sjdp 4666218822Sdim /* Check that all sections are in a PT_LOAD segment. 4667218822Sdim Don't check funky gdb generated core files. */ 4668218822Sdim if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core) 4669218822Sdim for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) 4670218822Sdim { 4671218822Sdim Elf_Internal_Shdr *this_hdr; 4672218822Sdim asection *sec; 467333965Sjdp 4674218822Sdim sec = *secpp; 4675218822Sdim this_hdr = &(elf_section_data(sec)->this_hdr); 4676218822Sdim if (this_hdr->sh_size != 0 4677218822Sdim && !ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, p)) 4678218822Sdim { 4679218822Sdim (*_bfd_error_handler) 4680218822Sdim (_("%B: section `%A' can't be allocated in segment %d"), 4681218822Sdim abfd, sec, j); 4682218822Sdim bfd_set_error (bfd_error_bad_value); 4683218822Sdim return FALSE; 4684218822Sdim } 4685218822Sdim } 468633965Sjdp } 468733965Sjdp 468833965Sjdp elf_tdata (abfd)->next_file_pos = off; 4689130563Sobrien return TRUE; 469033965Sjdp} 469133965Sjdp 4692218822Sdim/* Assign file positions for the other sections. */ 469333965Sjdp 4694218822Sdimstatic bfd_boolean 4695218822Sdimassign_file_positions_for_non_load_sections (bfd *abfd, 4696218822Sdim struct bfd_link_info *link_info) 469733965Sjdp{ 4698130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 4699218822Sdim Elf_Internal_Shdr **i_shdrpp; 4700218822Sdim Elf_Internal_Shdr **hdrpp; 4701218822Sdim Elf_Internal_Phdr *phdrs; 4702218822Sdim Elf_Internal_Phdr *p; 4703218822Sdim struct elf_segment_map *m; 4704218822Sdim bfd_vma filehdr_vaddr, filehdr_paddr; 4705218822Sdim bfd_vma phdrs_vaddr, phdrs_paddr; 4706218822Sdim file_ptr off; 4707218822Sdim unsigned int num_sec; 4708218822Sdim unsigned int i; 4709218822Sdim unsigned int count; 471033965Sjdp 4711218822Sdim i_shdrpp = elf_elfsections (abfd); 4712218822Sdim num_sec = elf_numsections (abfd); 4713218822Sdim off = elf_tdata (abfd)->next_file_pos; 4714218822Sdim for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++) 471533965Sjdp { 4716218822Sdim struct elf_obj_tdata *tdata = elf_tdata (abfd); 4717218822Sdim Elf_Internal_Shdr *hdr; 471833965Sjdp 4719218822Sdim hdr = *hdrpp; 4720218822Sdim if (hdr->bfd_section != NULL 4721218822Sdim && (hdr->bfd_section->filepos != 0 4722218822Sdim || (hdr->sh_type == SHT_NOBITS 4723218822Sdim && hdr->contents == NULL))) 4724218822Sdim BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos); 4725218822Sdim else if ((hdr->sh_flags & SHF_ALLOC) != 0) 4726218822Sdim { 4727218822Sdim if (hdr->sh_size != 0) 4728218822Sdim ((*_bfd_error_handler) 4729218822Sdim (_("%B: warning: allocated section `%s' not in segment"), 4730218822Sdim abfd, 4731218822Sdim (hdr->bfd_section == NULL 4732218822Sdim ? "*unknown*" 4733218822Sdim : hdr->bfd_section->name))); 4734218822Sdim /* We don't need to page align empty sections. */ 4735218822Sdim if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0) 4736218822Sdim off += vma_page_aligned_bias (hdr->sh_addr, off, 4737218822Sdim bed->maxpagesize); 4738218822Sdim else 4739218822Sdim off += vma_page_aligned_bias (hdr->sh_addr, off, 4740218822Sdim hdr->sh_addralign); 4741218822Sdim off = _bfd_elf_assign_file_position_for_section (hdr, off, 4742218822Sdim FALSE); 4743218822Sdim } 4744218822Sdim else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) 4745218822Sdim && hdr->bfd_section == NULL) 4746218822Sdim || hdr == i_shdrpp[tdata->symtab_section] 4747218822Sdim || hdr == i_shdrpp[tdata->symtab_shndx_section] 4748218822Sdim || hdr == i_shdrpp[tdata->strtab_section]) 4749218822Sdim hdr->sh_offset = -1; 4750218822Sdim else 4751218822Sdim off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); 475233965Sjdp 4753218822Sdim if (i == SHN_LORESERVE - 1) 4754218822Sdim { 4755218822Sdim i += SHN_HIRESERVE + 1 - SHN_LORESERVE; 4756218822Sdim hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE; 4757218822Sdim } 475833965Sjdp } 475933965Sjdp 4760218822Sdim /* Now that we have set the section file positions, we can set up 4761218822Sdim the file positions for the non PT_LOAD segments. */ 4762218822Sdim count = 0; 4763218822Sdim filehdr_vaddr = 0; 4764218822Sdim filehdr_paddr = 0; 4765218822Sdim phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr; 4766218822Sdim phdrs_paddr = 0; 4767218822Sdim phdrs = elf_tdata (abfd)->phdr; 4768218822Sdim for (m = elf_tdata (abfd)->segment_map, p = phdrs; 4769218822Sdim m != NULL; 4770218822Sdim m = m->next, p++) 477133965Sjdp { 4772218822Sdim ++count; 4773218822Sdim if (p->p_type != PT_LOAD) 4774218822Sdim continue; 477533965Sjdp 4776218822Sdim if (m->includes_filehdr) 477733965Sjdp { 4778218822Sdim filehdr_vaddr = p->p_vaddr; 4779218822Sdim filehdr_paddr = p->p_paddr; 478033965Sjdp } 4781218822Sdim if (m->includes_phdrs) 4782218822Sdim { 4783218822Sdim phdrs_vaddr = p->p_vaddr; 4784218822Sdim phdrs_paddr = p->p_paddr; 4785218822Sdim if (m->includes_filehdr) 4786218822Sdim { 4787218822Sdim phdrs_vaddr += bed->s->sizeof_ehdr; 4788218822Sdim phdrs_paddr += bed->s->sizeof_ehdr; 4789218822Sdim } 4790218822Sdim } 479133965Sjdp } 479233965Sjdp 4793218822Sdim for (m = elf_tdata (abfd)->segment_map, p = phdrs; 4794218822Sdim m != NULL; 4795218822Sdim m = m->next, p++) 4796104838Sobrien { 4797218822Sdim if (m->count != 0) 4798104838Sobrien { 4799218822Sdim if (p->p_type != PT_LOAD 4800218822Sdim && (p->p_type != PT_NOTE || bfd_get_format (abfd) != bfd_core)) 4801218822Sdim { 4802218822Sdim Elf_Internal_Shdr *hdr; 4803218822Sdim BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs); 4804218822Sdim 4805218822Sdim hdr = &elf_section_data (m->sections[m->count - 1])->this_hdr; 4806218822Sdim p->p_filesz = (m->sections[m->count - 1]->filepos 4807218822Sdim - m->sections[0]->filepos); 4808218822Sdim if (hdr->sh_type != SHT_NOBITS) 4809218822Sdim p->p_filesz += hdr->sh_size; 4810218822Sdim 4811218822Sdim p->p_offset = m->sections[0]->filepos; 4812218822Sdim } 4813104838Sobrien } 4814218822Sdim else 4815218822Sdim { 4816218822Sdim if (m->includes_filehdr) 4817218822Sdim { 4818218822Sdim p->p_vaddr = filehdr_vaddr; 4819218822Sdim if (! m->p_paddr_valid) 4820218822Sdim p->p_paddr = filehdr_paddr; 4821218822Sdim } 4822218822Sdim else if (m->includes_phdrs) 4823218822Sdim { 4824218822Sdim p->p_vaddr = phdrs_vaddr; 4825218822Sdim if (! m->p_paddr_valid) 4826218822Sdim p->p_paddr = phdrs_paddr; 4827218822Sdim } 4828218822Sdim else if (p->p_type == PT_GNU_RELRO) 4829218822Sdim { 4830218822Sdim Elf_Internal_Phdr *lp; 4831104838Sobrien 4832218822Sdim for (lp = phdrs; lp < phdrs + count; ++lp) 4833218822Sdim { 4834218822Sdim if (lp->p_type == PT_LOAD 4835218822Sdim && lp->p_vaddr <= link_info->relro_end 4836218822Sdim && lp->p_vaddr >= link_info->relro_start 4837218822Sdim && (lp->p_vaddr + lp->p_filesz 4838218822Sdim >= link_info->relro_end)) 4839218822Sdim break; 4840218822Sdim } 484133965Sjdp 4842218822Sdim if (lp < phdrs + count 4843218822Sdim && link_info->relro_end > lp->p_vaddr) 4844218822Sdim { 4845218822Sdim p->p_vaddr = lp->p_vaddr; 4846218822Sdim p->p_paddr = lp->p_paddr; 4847218822Sdim p->p_offset = lp->p_offset; 4848218822Sdim p->p_filesz = link_info->relro_end - lp->p_vaddr; 4849218822Sdim p->p_memsz = p->p_filesz; 4850218822Sdim p->p_align = 1; 4851218822Sdim p->p_flags = (lp->p_flags & ~PF_W); 4852218822Sdim } 4853218822Sdim else 4854218822Sdim { 4855218822Sdim memset (p, 0, sizeof *p); 4856218822Sdim p->p_type = PT_NULL; 4857218822Sdim } 4858218822Sdim } 4859218822Sdim } 486033965Sjdp } 486133965Sjdp 4862218822Sdim elf_tdata (abfd)->next_file_pos = off; 4863218822Sdim 4864218822Sdim return TRUE; 486533965Sjdp} 486633965Sjdp 486733965Sjdp/* Work out the file positions of all the sections. This is called by 486833965Sjdp _bfd_elf_compute_section_file_positions. All the section sizes and 486933965Sjdp VMAs must be known before this is called. 487033965Sjdp 4871218822Sdim Reloc sections come in two flavours: Those processed specially as 4872218822Sdim "side-channel" data attached to a section to which they apply, and 4873218822Sdim those that bfd doesn't process as relocations. The latter sort are 4874218822Sdim stored in a normal bfd section by bfd_section_from_shdr. We don't 4875218822Sdim consider the former sort here, unless they form part of the loadable 4876218822Sdim image. Reloc sections not assigned here will be handled later by 4877218822Sdim assign_file_positions_for_relocs. 487833965Sjdp 487933965Sjdp We also don't set the positions of the .symtab and .strtab here. */ 488033965Sjdp 4881130563Sobrienstatic bfd_boolean 4882130563Sobrienassign_file_positions_except_relocs (bfd *abfd, 4883130563Sobrien struct bfd_link_info *link_info) 488433965Sjdp{ 4885218822Sdim struct elf_obj_tdata *tdata = elf_tdata (abfd); 4886218822Sdim Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd); 488733965Sjdp file_ptr off; 4888130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 488933965Sjdp 489060508Sobrien if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 489160508Sobrien && bfd_get_format (abfd) != bfd_core) 489233965Sjdp { 4893218822Sdim Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); 4894218822Sdim unsigned int num_sec = elf_numsections (abfd); 489533965Sjdp Elf_Internal_Shdr **hdrpp; 489633965Sjdp unsigned int i; 489733965Sjdp 489833965Sjdp /* Start after the ELF header. */ 489933965Sjdp off = i_ehdrp->e_ehsize; 490033965Sjdp 490133965Sjdp /* We are not creating an executable, which means that we are 490233965Sjdp not creating a program header, and that the actual order of 490333965Sjdp the sections in the file is unimportant. */ 490489860Sobrien for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++) 490533965Sjdp { 490633965Sjdp Elf_Internal_Shdr *hdr; 490733965Sjdp 490833965Sjdp hdr = *hdrpp; 4909218822Sdim if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) 4910218822Sdim && hdr->bfd_section == NULL) 491189860Sobrien || i == tdata->symtab_section 491289860Sobrien || i == tdata->symtab_shndx_section 491389860Sobrien || i == tdata->strtab_section) 491433965Sjdp { 491533965Sjdp hdr->sh_offset = -1; 491633965Sjdp } 491789860Sobrien else 4918130563Sobrien off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); 491989860Sobrien 492089860Sobrien if (i == SHN_LORESERVE - 1) 492133965Sjdp { 492289860Sobrien i += SHN_HIRESERVE + 1 - SHN_LORESERVE; 492389860Sobrien hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE; 492433965Sjdp } 492533965Sjdp } 492633965Sjdp } 492733965Sjdp else 492833965Sjdp { 4929218822Sdim unsigned int alloc; 493033965Sjdp 493133965Sjdp /* Assign file positions for the loaded sections based on the 4932218822Sdim assignment of sections to segments. */ 4933218822Sdim if (!assign_file_positions_for_load_sections (abfd, link_info)) 4934130563Sobrien return FALSE; 493533965Sjdp 4936218822Sdim /* And for non-load sections. */ 4937218822Sdim if (!assign_file_positions_for_non_load_sections (abfd, link_info)) 4938218822Sdim return FALSE; 493933965Sjdp 4940218822Sdim if (bed->elf_backend_modify_program_headers != NULL) 494133965Sjdp { 4942218822Sdim if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info)) 4943218822Sdim return FALSE; 4944218822Sdim } 494533965Sjdp 4946218822Sdim /* Write out the program headers. */ 4947218822Sdim alloc = tdata->program_header_size / bed->s->sizeof_phdr; 4948218822Sdim if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0 4949218822Sdim || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0) 4950218822Sdim return FALSE; 495189860Sobrien 4952218822Sdim off = tdata->next_file_pos; 495333965Sjdp } 495433965Sjdp 495533965Sjdp /* Place the section headers. */ 4956130563Sobrien off = align_file_position (off, 1 << bed->s->log_file_align); 495733965Sjdp i_ehdrp->e_shoff = off; 495833965Sjdp off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize; 495933965Sjdp 4960218822Sdim tdata->next_file_pos = off; 496133965Sjdp 4962130563Sobrien return TRUE; 496333965Sjdp} 496433965Sjdp 4965130563Sobrienstatic bfd_boolean 4966130563Sobrienprep_headers (bfd *abfd) 496733965Sjdp{ 496833965Sjdp Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ 496960508Sobrien Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */ 497033965Sjdp Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ 497189860Sobrien struct elf_strtab_hash *shstrtab; 4972130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 497333965Sjdp 497433965Sjdp i_ehdrp = elf_elfheader (abfd); 497533965Sjdp i_shdrp = elf_elfsections (abfd); 497633965Sjdp 497789860Sobrien shstrtab = _bfd_elf_strtab_init (); 497833965Sjdp if (shstrtab == NULL) 4979130563Sobrien return FALSE; 498033965Sjdp 498133965Sjdp elf_shstrtab (abfd) = shstrtab; 498233965Sjdp 498333965Sjdp i_ehdrp->e_ident[EI_MAG0] = ELFMAG0; 498433965Sjdp i_ehdrp->e_ident[EI_MAG1] = ELFMAG1; 498533965Sjdp i_ehdrp->e_ident[EI_MAG2] = ELFMAG2; 498633965Sjdp i_ehdrp->e_ident[EI_MAG3] = ELFMAG3; 498733965Sjdp 498833965Sjdp i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass; 498933965Sjdp i_ehdrp->e_ident[EI_DATA] = 499033965Sjdp bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB; 499133965Sjdp i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current; 499233965Sjdp 499359342Sobrien i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 499459342Sobrien 499533965Sjdp if ((abfd->flags & DYNAMIC) != 0) 499633965Sjdp i_ehdrp->e_type = ET_DYN; 499733965Sjdp else if ((abfd->flags & EXEC_P) != 0) 499833965Sjdp i_ehdrp->e_type = ET_EXEC; 499960508Sobrien else if (bfd_get_format (abfd) == bfd_core) 500060508Sobrien i_ehdrp->e_type = ET_CORE; 500133965Sjdp else 500233965Sjdp i_ehdrp->e_type = ET_REL; 500333965Sjdp 500433965Sjdp switch (bfd_get_arch (abfd)) 500533965Sjdp { 500633965Sjdp case bfd_arch_unknown: 500733965Sjdp i_ehdrp->e_machine = EM_NONE; 500833965Sjdp break; 500989860Sobrien 501089860Sobrien /* There used to be a long list of cases here, each one setting 501189860Sobrien e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE 501289860Sobrien in the corresponding bfd definition. To avoid duplication, 501389860Sobrien the switch was removed. Machines that need special handling 501489860Sobrien can generally do it in elf_backend_final_write_processing(), 501589860Sobrien unless they need the information earlier than the final write. 501689860Sobrien Such need can generally be supplied by replacing the tests for 501789860Sobrien e_machine with the conditions used to determine it. */ 501889860Sobrien default: 5019130563Sobrien i_ehdrp->e_machine = bed->elf_machine_code; 5020130563Sobrien } 502189860Sobrien 502233965Sjdp i_ehdrp->e_version = bed->s->ev_current; 502333965Sjdp i_ehdrp->e_ehsize = bed->s->sizeof_ehdr; 502433965Sjdp 502577301Sobrien /* No program header, for now. */ 502633965Sjdp i_ehdrp->e_phoff = 0; 502733965Sjdp i_ehdrp->e_phentsize = 0; 502833965Sjdp i_ehdrp->e_phnum = 0; 502933965Sjdp 503077301Sobrien /* Each bfd section is section header entry. */ 503133965Sjdp i_ehdrp->e_entry = bfd_get_start_address (abfd); 503233965Sjdp i_ehdrp->e_shentsize = bed->s->sizeof_shdr; 503333965Sjdp 503477301Sobrien /* If we're building an executable, we'll need a program header table. */ 503533965Sjdp if (abfd->flags & EXEC_P) 5036218822Sdim /* It all happens later. */ 5037218822Sdim ; 503833965Sjdp else 503933965Sjdp { 504033965Sjdp i_ehdrp->e_phentsize = 0; 504133965Sjdp i_phdrp = 0; 504233965Sjdp i_ehdrp->e_phoff = 0; 504333965Sjdp } 504433965Sjdp 504533965Sjdp elf_tdata (abfd)->symtab_hdr.sh_name = 5046130563Sobrien (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", FALSE); 504733965Sjdp elf_tdata (abfd)->strtab_hdr.sh_name = 5048130563Sobrien (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", FALSE); 504933965Sjdp elf_tdata (abfd)->shstrtab_hdr.sh_name = 5050130563Sobrien (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE); 505133965Sjdp if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 505233965Sjdp || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 505333965Sjdp || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1) 5054130563Sobrien return FALSE; 505533965Sjdp 5056130563Sobrien return TRUE; 505733965Sjdp} 505833965Sjdp 505933965Sjdp/* Assign file positions for all the reloc sections which are not part 506033965Sjdp of the loadable file image. */ 506133965Sjdp 506233965Sjdpvoid 5063130563Sobrien_bfd_elf_assign_file_positions_for_relocs (bfd *abfd) 506433965Sjdp{ 506533965Sjdp file_ptr off; 506689860Sobrien unsigned int i, num_sec; 506733965Sjdp Elf_Internal_Shdr **shdrpp; 506833965Sjdp 506933965Sjdp off = elf_tdata (abfd)->next_file_pos; 507033965Sjdp 507189860Sobrien num_sec = elf_numsections (abfd); 507289860Sobrien for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++) 507333965Sjdp { 507433965Sjdp Elf_Internal_Shdr *shdrp; 507533965Sjdp 507633965Sjdp shdrp = *shdrpp; 507733965Sjdp if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA) 507833965Sjdp && shdrp->sh_offset == -1) 5079130563Sobrien off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE); 508033965Sjdp } 508133965Sjdp 508233965Sjdp elf_tdata (abfd)->next_file_pos = off; 508333965Sjdp} 508433965Sjdp 5085130563Sobrienbfd_boolean 5086130563Sobrien_bfd_elf_write_object_contents (bfd *abfd) 508733965Sjdp{ 5088130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 508933965Sjdp Elf_Internal_Ehdr *i_ehdrp; 509033965Sjdp Elf_Internal_Shdr **i_shdrp; 5091130563Sobrien bfd_boolean failed; 509289860Sobrien unsigned int count, num_sec; 509333965Sjdp 509433965Sjdp if (! abfd->output_has_begun 5095130563Sobrien && ! _bfd_elf_compute_section_file_positions (abfd, NULL)) 5096130563Sobrien return FALSE; 509733965Sjdp 509833965Sjdp i_shdrp = elf_elfsections (abfd); 509933965Sjdp i_ehdrp = elf_elfheader (abfd); 510033965Sjdp 5101130563Sobrien failed = FALSE; 510233965Sjdp bfd_map_over_sections (abfd, bed->s->write_relocs, &failed); 510333965Sjdp if (failed) 5104130563Sobrien return FALSE; 510560508Sobrien 510633965Sjdp _bfd_elf_assign_file_positions_for_relocs (abfd); 510733965Sjdp 510877301Sobrien /* After writing the headers, we need to write the sections too... */ 510989860Sobrien num_sec = elf_numsections (abfd); 511089860Sobrien for (count = 1; count < num_sec; count++) 511133965Sjdp { 511233965Sjdp if (bed->elf_backend_section_processing) 511333965Sjdp (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]); 511433965Sjdp if (i_shdrp[count]->contents) 511533965Sjdp { 511689860Sobrien bfd_size_type amt = i_shdrp[count]->sh_size; 511789860Sobrien 511833965Sjdp if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0 511989860Sobrien || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt) 5120130563Sobrien return FALSE; 512133965Sjdp } 512289860Sobrien if (count == SHN_LORESERVE - 1) 512389860Sobrien count += SHN_HIRESERVE + 1 - SHN_LORESERVE; 512433965Sjdp } 512533965Sjdp 512633965Sjdp /* Write out the section header names. */ 5127218822Sdim if (elf_shstrtab (abfd) != NULL 5128218822Sdim && (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0 5129218822Sdim || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd)))) 5130130563Sobrien return FALSE; 513133965Sjdp 513233965Sjdp if (bed->elf_backend_final_write_processing) 513333965Sjdp (*bed->elf_backend_final_write_processing) (abfd, 513433965Sjdp elf_tdata (abfd)->linker); 513533965Sjdp 513633965Sjdp return bed->s->write_shdrs_and_ehdr (abfd); 513733965Sjdp} 513833965Sjdp 5139130563Sobrienbfd_boolean 5140130563Sobrien_bfd_elf_write_corefile_contents (bfd *abfd) 514160508Sobrien{ 514277301Sobrien /* Hopefully this can be done just like an object file. */ 514360508Sobrien return _bfd_elf_write_object_contents (abfd); 514460508Sobrien} 514577301Sobrien 514677301Sobrien/* Given a section, search the header to find them. */ 514777301Sobrien 514833965Sjdpint 5149130563Sobrien_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect) 515033965Sjdp{ 5151130563Sobrien const struct elf_backend_data *bed; 515233965Sjdp int index; 515333965Sjdp 515489860Sobrien if (elf_section_data (asect) != NULL 515589860Sobrien && elf_section_data (asect)->this_idx != 0) 515689860Sobrien return elf_section_data (asect)->this_idx; 515789860Sobrien 515889860Sobrien if (bfd_is_abs_section (asect)) 515989860Sobrien index = SHN_ABS; 516089860Sobrien else if (bfd_is_com_section (asect)) 516189860Sobrien index = SHN_COMMON; 516289860Sobrien else if (bfd_is_und_section (asect)) 516389860Sobrien index = SHN_UNDEF; 516489860Sobrien else 5165218822Sdim index = -1; 516689860Sobrien 516789860Sobrien bed = get_elf_backend_data (abfd); 516833965Sjdp if (bed->elf_backend_section_from_bfd_section) 516933965Sjdp { 517089860Sobrien int retval = index; 517133965Sjdp 517289860Sobrien if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval)) 517389860Sobrien return retval; 517433965Sjdp } 517533965Sjdp 517689860Sobrien if (index == -1) 517789860Sobrien bfd_set_error (bfd_error_nonrepresentable_section); 517833965Sjdp 517989860Sobrien return index; 518033965Sjdp} 518133965Sjdp 518233965Sjdp/* Given a BFD symbol, return the index in the ELF symbol table, or -1 518333965Sjdp on error. */ 518433965Sjdp 518533965Sjdpint 5186130563Sobrien_bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr) 518733965Sjdp{ 518833965Sjdp asymbol *asym_ptr = *asym_ptr_ptr; 518933965Sjdp int idx; 519033965Sjdp flagword flags = asym_ptr->flags; 519133965Sjdp 519233965Sjdp /* When gas creates relocations against local labels, it creates its 519333965Sjdp own symbol for the section, but does put the symbol into the 519433965Sjdp symbol chain, so udata is 0. When the linker is generating 519533965Sjdp relocatable output, this section symbol may be for one of the 519633965Sjdp input sections rather than the output section. */ 519733965Sjdp if (asym_ptr->udata.i == 0 519833965Sjdp && (flags & BSF_SECTION_SYM) 519933965Sjdp && asym_ptr->section) 520033965Sjdp { 5201218822Sdim asection *sec; 520233965Sjdp int indx; 520333965Sjdp 5204218822Sdim sec = asym_ptr->section; 5205218822Sdim if (sec->owner != abfd && sec->output_section != NULL) 5206218822Sdim sec = sec->output_section; 5207218822Sdim if (sec->owner == abfd 5208218822Sdim && (indx = sec->index) < elf_num_section_syms (abfd) 520989860Sobrien && elf_section_syms (abfd)[indx] != NULL) 521033965Sjdp asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i; 521133965Sjdp } 521233965Sjdp 521333965Sjdp idx = asym_ptr->udata.i; 521433965Sjdp 521533965Sjdp if (idx == 0) 521633965Sjdp { 521733965Sjdp /* This case can occur when using --strip-symbol on a symbol 5218218822Sdim which is used in a relocation entry. */ 521933965Sjdp (*_bfd_error_handler) 5220218822Sdim (_("%B: symbol `%s' required but not present"), 5221218822Sdim abfd, bfd_asymbol_name (asym_ptr)); 522233965Sjdp bfd_set_error (bfd_error_no_symbols); 522333965Sjdp return -1; 522433965Sjdp } 522533965Sjdp 522633965Sjdp#if DEBUG & 4 522733965Sjdp { 522833965Sjdp fprintf (stderr, 522991047Sobrien "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n", 523033965Sjdp (long) asym_ptr, asym_ptr->name, idx, flags, 523133965Sjdp elf_symbol_flags (flags)); 523233965Sjdp fflush (stderr); 523333965Sjdp } 523433965Sjdp#endif 523533965Sjdp 523633965Sjdp return idx; 523733965Sjdp} 523833965Sjdp 5239218822Sdim/* Rewrite program header information. */ 524033965Sjdp 5241130563Sobrienstatic bfd_boolean 5242218822Sdimrewrite_elf_program_header (bfd *ibfd, bfd *obfd) 524333965Sjdp{ 5244130563Sobrien Elf_Internal_Ehdr *iehdr; 5245130563Sobrien struct elf_segment_map *map; 5246130563Sobrien struct elf_segment_map *map_first; 5247130563Sobrien struct elf_segment_map **pointer_to_map; 5248130563Sobrien Elf_Internal_Phdr *segment; 5249130563Sobrien asection *section; 5250130563Sobrien unsigned int i; 5251130563Sobrien unsigned int num_segments; 5252130563Sobrien bfd_boolean phdr_included = FALSE; 5253130563Sobrien bfd_vma maxpagesize; 5254130563Sobrien struct elf_segment_map *phdr_adjust_seg = NULL; 5255130563Sobrien unsigned int phdr_adjust_num = 0; 5256130563Sobrien const struct elf_backend_data *bed; 525733965Sjdp 5258104838Sobrien bed = get_elf_backend_data (ibfd); 525933965Sjdp iehdr = elf_elfheader (ibfd); 526033965Sjdp 526177301Sobrien map_first = NULL; 526277301Sobrien pointer_to_map = &map_first; 526333965Sjdp 526460508Sobrien num_segments = elf_elfheader (ibfd)->e_phnum; 526577301Sobrien maxpagesize = get_elf_backend_data (obfd)->maxpagesize; 526660508Sobrien 526777301Sobrien /* Returns the end address of the segment + 1. */ 5268104838Sobrien#define SEGMENT_END(segment, start) \ 5269104838Sobrien (start + (segment->p_memsz > segment->p_filesz \ 5270104838Sobrien ? segment->p_memsz : segment->p_filesz)) 527160508Sobrien 5272130563Sobrien#define SECTION_SIZE(section, segment) \ 5273130563Sobrien (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) \ 5274130563Sobrien != SEC_THREAD_LOCAL || segment->p_type == PT_TLS) \ 5275218822Sdim ? section->size : 0) 5276130563Sobrien 5277130563Sobrien /* Returns TRUE if the given section is contained within 527877301Sobrien the given segment. VMA addresses are compared. */ 5279104838Sobrien#define IS_CONTAINED_BY_VMA(section, segment) \ 5280104838Sobrien (section->vma >= segment->p_vaddr \ 5281130563Sobrien && (section->vma + SECTION_SIZE (section, segment) \ 5282104838Sobrien <= (SEGMENT_END (segment, segment->p_vaddr)))) 528360508Sobrien 5284130563Sobrien /* Returns TRUE if the given section is contained within 528577301Sobrien the given segment. LMA addresses are compared. */ 5286104838Sobrien#define IS_CONTAINED_BY_LMA(section, segment, base) \ 5287104838Sobrien (section->lma >= base \ 5288130563Sobrien && (section->lma + SECTION_SIZE (section, segment) \ 5289104838Sobrien <= SEGMENT_END (segment, base))) 529077301Sobrien 529177301Sobrien /* Special case: corefile "NOTE" section containing regs, prpsinfo etc. */ 5292104838Sobrien#define IS_COREFILE_NOTE(p, s) \ 5293104838Sobrien (p->p_type == PT_NOTE \ 5294104838Sobrien && bfd_get_format (ibfd) == bfd_core \ 5295104838Sobrien && s->vma == 0 && s->lma == 0 \ 5296104838Sobrien && (bfd_vma) s->filepos >= p->p_offset \ 5297218822Sdim && ((bfd_vma) s->filepos + s->size \ 5298104838Sobrien <= p->p_offset + p->p_filesz)) 529960508Sobrien 530060508Sobrien /* The complicated case when p_vaddr is 0 is to handle the Solaris 530160508Sobrien linker, which generates a PT_INTERP section with p_vaddr and 530260508Sobrien p_memsz set to 0. */ 5303104838Sobrien#define IS_SOLARIS_PT_INTERP(p, s) \ 5304104838Sobrien (p->p_vaddr == 0 \ 5305104838Sobrien && p->p_paddr == 0 \ 5306104838Sobrien && p->p_memsz == 0 \ 5307104838Sobrien && p->p_filesz > 0 \ 5308104838Sobrien && (s->flags & SEC_HAS_CONTENTS) != 0 \ 5309218822Sdim && s->size > 0 \ 5310104838Sobrien && (bfd_vma) s->filepos >= p->p_offset \ 5311218822Sdim && ((bfd_vma) s->filepos + s->size \ 5312104838Sobrien <= p->p_offset + p->p_filesz)) 531360508Sobrien 531477301Sobrien /* Decide if the given section should be included in the given segment. 531577301Sobrien A section will be included if: 531689860Sobrien 1. It is within the address space of the segment -- we use the LMA 5317218822Sdim if that is set for the segment and the VMA otherwise, 531877301Sobrien 2. It is an allocated segment, 531977301Sobrien 3. There is an output section associated with it, 5320130563Sobrien 4. The section has not already been allocated to a previous segment. 5321130563Sobrien 5. PT_GNU_STACK segments do not include any sections. 5322130563Sobrien 6. PT_TLS segment includes only SHF_TLS sections. 5323218822Sdim 7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments. 5324218822Sdim 8. PT_DYNAMIC should not contain empty sections at the beginning 5325218822Sdim (with the possible exception of .dynamic). */ 5326218822Sdim#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed) \ 5327104838Sobrien ((((segment->p_paddr \ 5328104838Sobrien ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \ 5329104838Sobrien : IS_CONTAINED_BY_VMA (section, segment)) \ 533089860Sobrien && (section->flags & SEC_ALLOC) != 0) \ 5331107496Sobrien || IS_COREFILE_NOTE (segment, section)) \ 5332130563Sobrien && segment->p_type != PT_GNU_STACK \ 5333130563Sobrien && (segment->p_type != PT_TLS \ 5334130563Sobrien || (section->flags & SEC_THREAD_LOCAL)) \ 5335130563Sobrien && (segment->p_type == PT_LOAD \ 5336130563Sobrien || segment->p_type == PT_TLS \ 5337130563Sobrien || (section->flags & SEC_THREAD_LOCAL) == 0) \ 5338218822Sdim && (segment->p_type != PT_DYNAMIC \ 5339218822Sdim || SECTION_SIZE (section, segment) > 0 \ 5340218822Sdim || (segment->p_paddr \ 5341218822Sdim ? segment->p_paddr != section->lma \ 5342218822Sdim : segment->p_vaddr != section->vma) \ 5343218822Sdim || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic") \ 5344218822Sdim == 0)) \ 5345104838Sobrien && ! section->segment_mark) 534677301Sobrien 5347218822Sdim/* If the output section of a section in the input segment is NULL, 5348218822Sdim it is removed from the corresponding output segment. */ 5349218822Sdim#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \ 5350218822Sdim (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed) \ 5351218822Sdim && section->output_section != NULL) 5352218822Sdim 5353130563Sobrien /* Returns TRUE iff seg1 starts after the end of seg2. */ 5354130563Sobrien#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field) \ 5355130563Sobrien (seg1->field >= SEGMENT_END (seg2, seg2->field)) 535677301Sobrien 5357130563Sobrien /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both 5358130563Sobrien their VMA address ranges and their LMA address ranges overlap. 5359130563Sobrien It is possible to have overlapping VMA ranges without overlapping LMA 5360130563Sobrien ranges. RedBoot images for example can have both .data and .bss mapped 5361130563Sobrien to the same VMA range, but with the .data section mapped to a different 5362130563Sobrien LMA. */ 5363104838Sobrien#define SEGMENT_OVERLAPS(seg1, seg2) \ 5364130563Sobrien ( !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr) \ 5365218822Sdim || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr)) \ 5366130563Sobrien && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr) \ 5367218822Sdim || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr))) 536877301Sobrien 536977301Sobrien /* Initialise the segment mark field. */ 537077301Sobrien for (section = ibfd->sections; section != NULL; section = section->next) 5371130563Sobrien section->segment_mark = FALSE; 537277301Sobrien 537360508Sobrien /* Scan through the segments specified in the program header 537477301Sobrien of the input BFD. For this first scan we look for overlaps 537589860Sobrien in the loadable segments. These can be created by weird 5376104838Sobrien parameters to objcopy. Also, fix some solaris weirdness. */ 537777301Sobrien for (i = 0, segment = elf_tdata (ibfd)->phdr; 537877301Sobrien i < num_segments; 537977301Sobrien i++, segment++) 538033965Sjdp { 538160508Sobrien unsigned int j; 538277301Sobrien Elf_Internal_Phdr *segment2; 538333965Sjdp 5384104838Sobrien if (segment->p_type == PT_INTERP) 5385104838Sobrien for (section = ibfd->sections; section; section = section->next) 5386104838Sobrien if (IS_SOLARIS_PT_INTERP (segment, section)) 5387104838Sobrien { 5388104838Sobrien /* Mininal change so that the normal section to segment 5389130563Sobrien assignment code will work. */ 5390104838Sobrien segment->p_vaddr = section->vma; 5391104838Sobrien break; 5392104838Sobrien } 5393104838Sobrien 539477301Sobrien if (segment->p_type != PT_LOAD) 539577301Sobrien continue; 539633965Sjdp 539777301Sobrien /* Determine if this segment overlaps any previous segments. */ 539877301Sobrien for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2 ++) 539977301Sobrien { 540077301Sobrien bfd_signed_vma extra_length; 540177301Sobrien 540277301Sobrien if (segment2->p_type != PT_LOAD 540377301Sobrien || ! SEGMENT_OVERLAPS (segment, segment2)) 540477301Sobrien continue; 540577301Sobrien 540677301Sobrien /* Merge the two segments together. */ 540777301Sobrien if (segment2->p_vaddr < segment->p_vaddr) 540877301Sobrien { 540977301Sobrien /* Extend SEGMENT2 to include SEGMENT and then delete 5410218822Sdim SEGMENT. */ 541177301Sobrien extra_length = 541277301Sobrien SEGMENT_END (segment, segment->p_vaddr) 541377301Sobrien - SEGMENT_END (segment2, segment2->p_vaddr); 541477301Sobrien 541577301Sobrien if (extra_length > 0) 541677301Sobrien { 541777301Sobrien segment2->p_memsz += extra_length; 541877301Sobrien segment2->p_filesz += extra_length; 541977301Sobrien } 542077301Sobrien 542177301Sobrien segment->p_type = PT_NULL; 542277301Sobrien 542377301Sobrien /* Since we have deleted P we must restart the outer loop. */ 542477301Sobrien i = 0; 542577301Sobrien segment = elf_tdata (ibfd)->phdr; 542677301Sobrien break; 542777301Sobrien } 542877301Sobrien else 542977301Sobrien { 543077301Sobrien /* Extend SEGMENT to include SEGMENT2 and then delete 5431218822Sdim SEGMENT2. */ 543277301Sobrien extra_length = 543377301Sobrien SEGMENT_END (segment2, segment2->p_vaddr) 543477301Sobrien - SEGMENT_END (segment, segment->p_vaddr); 543577301Sobrien 543677301Sobrien if (extra_length > 0) 543777301Sobrien { 543877301Sobrien segment->p_memsz += extra_length; 543977301Sobrien segment->p_filesz += extra_length; 544077301Sobrien } 544177301Sobrien 544277301Sobrien segment2->p_type = PT_NULL; 544377301Sobrien } 544477301Sobrien } 544577301Sobrien } 544677301Sobrien 544777301Sobrien /* The second scan attempts to assign sections to segments. */ 544877301Sobrien for (i = 0, segment = elf_tdata (ibfd)->phdr; 544977301Sobrien i < num_segments; 545077301Sobrien i ++, segment ++) 545177301Sobrien { 545277301Sobrien unsigned int section_count; 545377301Sobrien asection ** sections; 545477301Sobrien asection * output_section; 545577301Sobrien unsigned int isec; 545677301Sobrien bfd_vma matching_lma; 545777301Sobrien bfd_vma suggested_lma; 545877301Sobrien unsigned int j; 545989860Sobrien bfd_size_type amt; 5460218822Sdim asection * first_section; 546177301Sobrien 546277301Sobrien if (segment->p_type == PT_NULL) 546377301Sobrien continue; 546477301Sobrien 5465218822Sdim first_section = NULL; 546677301Sobrien /* Compute how many sections might be placed into this segment. */ 5467130563Sobrien for (section = ibfd->sections, section_count = 0; 5468130563Sobrien section != NULL; 5469130563Sobrien section = section->next) 5470218822Sdim { 5471218822Sdim /* Find the first section in the input segment, which may be 5472218822Sdim removed from the corresponding output segment. */ 5473218822Sdim if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed)) 5474218822Sdim { 5475218822Sdim if (first_section == NULL) 5476218822Sdim first_section = section; 5477218822Sdim if (section->output_section != NULL) 5478218822Sdim ++section_count; 5479218822Sdim } 5480218822Sdim } 548177301Sobrien 5482130563Sobrien /* Allocate a segment map big enough to contain 5483130563Sobrien all of the sections we have selected. */ 548489860Sobrien amt = sizeof (struct elf_segment_map); 548589860Sobrien amt += ((bfd_size_type) section_count - 1) * sizeof (asection *); 5486218822Sdim map = bfd_zalloc (obfd, amt); 548777301Sobrien if (map == NULL) 5488130563Sobrien return FALSE; 548933965Sjdp 549060508Sobrien /* Initialise the fields of the segment map. Default to 549160508Sobrien using the physical address of the segment in the input BFD. */ 549277301Sobrien map->next = NULL; 549377301Sobrien map->p_type = segment->p_type; 549477301Sobrien map->p_flags = segment->p_flags; 549577301Sobrien map->p_flags_valid = 1; 549633965Sjdp 5497218822Sdim /* If the first section in the input segment is removed, there is 5498218822Sdim no need to preserve segment physical address in the corresponding 5499218822Sdim output segment. */ 5500218822Sdim if (!first_section || first_section->output_section != NULL) 5501218822Sdim { 5502218822Sdim map->p_paddr = segment->p_paddr; 5503218822Sdim map->p_paddr_valid = 1; 5504218822Sdim } 5505218822Sdim 550660508Sobrien /* Determine if this segment contains the ELF file header 550760508Sobrien and if it contains the program headers themselves. */ 550877301Sobrien map->includes_filehdr = (segment->p_offset == 0 550977301Sobrien && segment->p_filesz >= iehdr->e_ehsize); 551033965Sjdp 551177301Sobrien map->includes_phdrs = 0; 551233965Sjdp 551377301Sobrien if (! phdr_included || segment->p_type != PT_LOAD) 551460508Sobrien { 551577301Sobrien map->includes_phdrs = 551677301Sobrien (segment->p_offset <= (bfd_vma) iehdr->e_phoff 551777301Sobrien && (segment->p_offset + segment->p_filesz 551860508Sobrien >= ((bfd_vma) iehdr->e_phoff 551960508Sobrien + iehdr->e_phnum * iehdr->e_phentsize))); 552077301Sobrien 552177301Sobrien if (segment->p_type == PT_LOAD && map->includes_phdrs) 5522130563Sobrien phdr_included = TRUE; 552360508Sobrien } 552460508Sobrien 552577301Sobrien if (section_count == 0) 552660508Sobrien { 552760508Sobrien /* Special segments, such as the PT_PHDR segment, may contain 552860508Sobrien no sections, but ordinary, loadable segments should contain 5529104838Sobrien something. They are allowed by the ELF spec however, so only 5530104838Sobrien a warning is produced. */ 553177301Sobrien if (segment->p_type == PT_LOAD) 5532104838Sobrien (*_bfd_error_handler) 5533218822Sdim (_("%B: warning: Empty loadable segment detected, is this intentional ?\n"), 5534218822Sdim ibfd); 553560508Sobrien 553677301Sobrien map->count = 0; 553777301Sobrien *pointer_to_map = map; 553877301Sobrien pointer_to_map = &map->next; 553960508Sobrien 554060508Sobrien continue; 554160508Sobrien } 554260508Sobrien 554360508Sobrien /* Now scan the sections in the input BFD again and attempt 554460508Sobrien to add their corresponding output sections to the segment map. 554560508Sobrien The problem here is how to handle an output section which has 554660508Sobrien been moved (ie had its LMA changed). There are four possibilities: 554760508Sobrien 554860508Sobrien 1. None of the sections have been moved. 554960508Sobrien In this case we can continue to use the segment LMA from the 555060508Sobrien input BFD. 555160508Sobrien 555260508Sobrien 2. All of the sections have been moved by the same amount. 555360508Sobrien In this case we can change the segment's LMA to match the LMA 555460508Sobrien of the first section. 555560508Sobrien 555660508Sobrien 3. Some of the sections have been moved, others have not. 555760508Sobrien In this case those sections which have not been moved can be 555860508Sobrien placed in the current segment which will have to have its size, 555960508Sobrien and possibly its LMA changed, and a new segment or segments will 556060508Sobrien have to be created to contain the other sections. 556160508Sobrien 5562130563Sobrien 4. The sections have been moved, but not by the same amount. 556360508Sobrien In this case we can change the segment's LMA to match the LMA 556460508Sobrien of the first section and we will have to create a new segment 556560508Sobrien or segments to contain the other sections. 556660508Sobrien 556760508Sobrien In order to save time, we allocate an array to hold the section 556860508Sobrien pointers that we are interested in. As these sections get assigned 556960508Sobrien to a segment, they are removed from this array. */ 557060508Sobrien 5571104838Sobrien /* Gcc 2.96 miscompiles this code on mips. Don't do casting here 5572104838Sobrien to work around this long long bug. */ 5573218822Sdim sections = bfd_malloc2 (section_count, sizeof (asection *)); 557460508Sobrien if (sections == NULL) 5575130563Sobrien return FALSE; 557660508Sobrien 557760508Sobrien /* Step One: Scan for segment vs section LMA conflicts. 557860508Sobrien Also add the sections to the section array allocated above. 557960508Sobrien Also add the sections to the current segment. In the common 558060508Sobrien case, where the sections have not been moved, this means that 558160508Sobrien we have completely filled the segment, and there is nothing 558260508Sobrien more to do. */ 558333965Sjdp isec = 0; 558460508Sobrien matching_lma = 0; 558560508Sobrien suggested_lma = 0; 558660508Sobrien 558777301Sobrien for (j = 0, section = ibfd->sections; 558877301Sobrien section != NULL; 558977301Sobrien section = section->next) 559033965Sjdp { 5591104838Sobrien if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed)) 559233965Sjdp { 559377301Sobrien output_section = section->output_section; 559460508Sobrien 559577301Sobrien sections[j ++] = section; 559677301Sobrien 559760508Sobrien /* The Solaris native linker always sets p_paddr to 0. 559860508Sobrien We try to catch that case here, and set it to the 5599104838Sobrien correct value. Note - some backends require that 5600104838Sobrien p_paddr be left as zero. */ 560177301Sobrien if (segment->p_paddr == 0 560277301Sobrien && segment->p_vaddr != 0 5603104838Sobrien && (! bed->want_p_paddr_set_to_zero) 560460508Sobrien && isec == 0 560577301Sobrien && output_section->lma != 0 560677301Sobrien && (output_section->vma == (segment->p_vaddr 560777301Sobrien + (map->includes_filehdr 560877301Sobrien ? iehdr->e_ehsize 560977301Sobrien : 0) 561077301Sobrien + (map->includes_phdrs 561189860Sobrien ? (iehdr->e_phnum 561289860Sobrien * iehdr->e_phentsize) 561377301Sobrien : 0)))) 561477301Sobrien map->p_paddr = segment->p_vaddr; 561560508Sobrien 561660508Sobrien /* Match up the physical address of the segment with the 561760508Sobrien LMA address of the output section. */ 561877301Sobrien if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr) 5619104838Sobrien || IS_COREFILE_NOTE (segment, section) 5620104838Sobrien || (bed->want_p_paddr_set_to_zero && 5621218822Sdim IS_CONTAINED_BY_VMA (output_section, segment))) 562260508Sobrien { 562360508Sobrien if (matching_lma == 0) 562477301Sobrien matching_lma = output_section->lma; 562560508Sobrien 562660508Sobrien /* We assume that if the section fits within the segment 562777301Sobrien then it does not overlap any other section within that 562860508Sobrien segment. */ 562977301Sobrien map->sections[isec ++] = output_section; 563060508Sobrien } 563160508Sobrien else if (suggested_lma == 0) 563277301Sobrien suggested_lma = output_section->lma; 563333965Sjdp } 563433965Sjdp } 563533965Sjdp 563677301Sobrien BFD_ASSERT (j == section_count); 563760508Sobrien 563860508Sobrien /* Step Two: Adjust the physical address of the current segment, 563960508Sobrien if necessary. */ 564077301Sobrien if (isec == section_count) 564160508Sobrien { 564260508Sobrien /* All of the sections fitted within the segment as currently 564360508Sobrien specified. This is the default case. Add the segment to 564460508Sobrien the list of built segments and carry on to process the next 564560508Sobrien program header in the input BFD. */ 564677301Sobrien map->count = section_count; 564777301Sobrien *pointer_to_map = map; 564877301Sobrien pointer_to_map = &map->next; 564960508Sobrien 5650218822Sdim if (matching_lma != map->p_paddr 5651218822Sdim && !map->includes_filehdr && !map->includes_phdrs) 5652218822Sdim /* There is some padding before the first section in the 5653218822Sdim segment. So, we must account for that in the output 5654218822Sdim segment's vma. */ 5655218822Sdim map->p_vaddr_offset = matching_lma - map->p_paddr; 5656218822Sdim 565760508Sobrien free (sections); 565860508Sobrien continue; 565960508Sobrien } 566060508Sobrien else 566160508Sobrien { 566260508Sobrien if (matching_lma != 0) 566360508Sobrien { 566460508Sobrien /* At least one section fits inside the current segment. 566560508Sobrien Keep it, but modify its physical address to match the 566660508Sobrien LMA of the first section that fitted. */ 566777301Sobrien map->p_paddr = matching_lma; 566860508Sobrien } 566960508Sobrien else 567060508Sobrien { 567160508Sobrien /* None of the sections fitted inside the current segment. 567260508Sobrien Change the current segment's physical address to match 567360508Sobrien the LMA of the first section. */ 567477301Sobrien map->p_paddr = suggested_lma; 567560508Sobrien } 567660508Sobrien 567777301Sobrien /* Offset the segment physical address from the lma 567877301Sobrien to allow for space taken up by elf headers. */ 567977301Sobrien if (map->includes_filehdr) 568077301Sobrien map->p_paddr -= iehdr->e_ehsize; 568160508Sobrien 568277301Sobrien if (map->includes_phdrs) 568377301Sobrien { 568477301Sobrien map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize; 568577301Sobrien 568677301Sobrien /* iehdr->e_phnum is just an estimate of the number 568777301Sobrien of program headers that we will need. Make a note 568877301Sobrien here of the number we used and the segment we chose 568977301Sobrien to hold these headers, so that we can adjust the 569077301Sobrien offset when we know the correct value. */ 569177301Sobrien phdr_adjust_num = iehdr->e_phnum; 569277301Sobrien phdr_adjust_seg = map; 569377301Sobrien } 569460508Sobrien } 569560508Sobrien 569660508Sobrien /* Step Three: Loop over the sections again, this time assigning 5697104838Sobrien those that fit to the current segment and removing them from the 569860508Sobrien sections array; but making sure not to leave large gaps. Once all 569960508Sobrien possible sections have been assigned to the current segment it is 570060508Sobrien added to the list of built segments and if sections still remain 570160508Sobrien to be assigned, a new segment is constructed before repeating 570260508Sobrien the loop. */ 570360508Sobrien isec = 0; 570460508Sobrien do 570560508Sobrien { 570677301Sobrien map->count = 0; 570760508Sobrien suggested_lma = 0; 570860508Sobrien 570960508Sobrien /* Fill the current segment with sections that fit. */ 571077301Sobrien for (j = 0; j < section_count; j++) 571160508Sobrien { 571277301Sobrien section = sections[j]; 571360508Sobrien 571477301Sobrien if (section == NULL) 571560508Sobrien continue; 571660508Sobrien 571777301Sobrien output_section = section->output_section; 571860508Sobrien 571977301Sobrien BFD_ASSERT (output_section != NULL); 572077301Sobrien 572177301Sobrien if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr) 572277301Sobrien || IS_COREFILE_NOTE (segment, section)) 572360508Sobrien { 572477301Sobrien if (map->count == 0) 572560508Sobrien { 572660508Sobrien /* If the first section in a segment does not start at 572777301Sobrien the beginning of the segment, then something is 572877301Sobrien wrong. */ 572977301Sobrien if (output_section->lma != 573077301Sobrien (map->p_paddr 573177301Sobrien + (map->includes_filehdr ? iehdr->e_ehsize : 0) 573277301Sobrien + (map->includes_phdrs 573377301Sobrien ? iehdr->e_phnum * iehdr->e_phentsize 573477301Sobrien : 0))) 573560508Sobrien abort (); 573660508Sobrien } 573760508Sobrien else 573860508Sobrien { 573960508Sobrien asection * prev_sec; 574060508Sobrien 574177301Sobrien prev_sec = map->sections[map->count - 1]; 574260508Sobrien 574360508Sobrien /* If the gap between the end of the previous section 574477301Sobrien and the start of this section is more than 574577301Sobrien maxpagesize then we need to start a new segment. */ 5746218822Sdim if ((BFD_ALIGN (prev_sec->lma + prev_sec->size, 574789860Sobrien maxpagesize) 5748104838Sobrien < BFD_ALIGN (output_section->lma, maxpagesize)) 5749218822Sdim || ((prev_sec->lma + prev_sec->size) 575089860Sobrien > output_section->lma)) 575160508Sobrien { 575260508Sobrien if (suggested_lma == 0) 575377301Sobrien suggested_lma = output_section->lma; 575460508Sobrien 575560508Sobrien continue; 575660508Sobrien } 575760508Sobrien } 575860508Sobrien 575977301Sobrien map->sections[map->count++] = output_section; 576060508Sobrien ++isec; 576160508Sobrien sections[j] = NULL; 5762130563Sobrien section->segment_mark = TRUE; 576360508Sobrien } 576460508Sobrien else if (suggested_lma == 0) 576577301Sobrien suggested_lma = output_section->lma; 576660508Sobrien } 576760508Sobrien 576877301Sobrien BFD_ASSERT (map->count > 0); 576960508Sobrien 577060508Sobrien /* Add the current segment to the list of built segments. */ 577177301Sobrien *pointer_to_map = map; 577277301Sobrien pointer_to_map = &map->next; 577360508Sobrien 577477301Sobrien if (isec < section_count) 577560508Sobrien { 577660508Sobrien /* We still have not allocated all of the sections to 577760508Sobrien segments. Create a new segment here, initialise it 577860508Sobrien and carry on looping. */ 577989860Sobrien amt = sizeof (struct elf_segment_map); 578089860Sobrien amt += ((bfd_size_type) section_count - 1) * sizeof (asection *); 5781130563Sobrien map = bfd_alloc (obfd, amt); 578277301Sobrien if (map == NULL) 5783130563Sobrien { 5784130563Sobrien free (sections); 5785130563Sobrien return FALSE; 5786130563Sobrien } 578760508Sobrien 578860508Sobrien /* Initialise the fields of the segment map. Set the physical 578960508Sobrien physical address to the LMA of the first section that has 579060508Sobrien not yet been assigned. */ 579177301Sobrien map->next = NULL; 579277301Sobrien map->p_type = segment->p_type; 579377301Sobrien map->p_flags = segment->p_flags; 579477301Sobrien map->p_flags_valid = 1; 579577301Sobrien map->p_paddr = suggested_lma; 579677301Sobrien map->p_paddr_valid = 1; 579777301Sobrien map->includes_filehdr = 0; 579877301Sobrien map->includes_phdrs = 0; 579960508Sobrien } 580060508Sobrien } 580177301Sobrien while (isec < section_count); 580260508Sobrien 580360508Sobrien free (sections); 580433965Sjdp } 580533965Sjdp 580638891Sjdp /* The Solaris linker creates program headers in which all the 580738891Sjdp p_paddr fields are zero. When we try to objcopy or strip such a 580838891Sjdp file, we get confused. Check for this case, and if we find it 580938891Sjdp reset the p_paddr_valid fields. */ 581077301Sobrien for (map = map_first; map != NULL; map = map->next) 581177301Sobrien if (map->p_paddr != 0) 581238891Sjdp break; 581377301Sobrien if (map == NULL) 5814130563Sobrien for (map = map_first; map != NULL; map = map->next) 5815130563Sobrien map->p_paddr_valid = 0; 581638891Sjdp 581777301Sobrien elf_tdata (obfd)->segment_map = map_first; 581833965Sjdp 581977301Sobrien /* If we had to estimate the number of program headers that were 582089860Sobrien going to be needed, then check our estimate now and adjust 582177301Sobrien the offset if necessary. */ 582277301Sobrien if (phdr_adjust_seg != NULL) 582377301Sobrien { 582477301Sobrien unsigned int count; 582577301Sobrien 582677301Sobrien for (count = 0, map = map_first; map != NULL; map = map->next) 582777301Sobrien count++; 582877301Sobrien 582977301Sobrien if (count > phdr_adjust_num) 583077301Sobrien phdr_adjust_seg->p_paddr 583177301Sobrien -= (count - phdr_adjust_num) * iehdr->e_phentsize; 583277301Sobrien } 583377301Sobrien 583477301Sobrien#undef SEGMENT_END 5835130563Sobrien#undef SECTION_SIZE 583677301Sobrien#undef IS_CONTAINED_BY_VMA 583777301Sobrien#undef IS_CONTAINED_BY_LMA 583877301Sobrien#undef IS_COREFILE_NOTE 583960508Sobrien#undef IS_SOLARIS_PT_INTERP 5840218822Sdim#undef IS_SECTION_IN_INPUT_SEGMENT 584177301Sobrien#undef INCLUDE_SECTION_IN_SEGMENT 584277301Sobrien#undef SEGMENT_AFTER_SEGMENT 584377301Sobrien#undef SEGMENT_OVERLAPS 5844130563Sobrien return TRUE; 584533965Sjdp} 584633965Sjdp 5847218822Sdim/* Copy ELF program header information. */ 5848218822Sdim 5849218822Sdimstatic bfd_boolean 5850218822Sdimcopy_elf_program_header (bfd *ibfd, bfd *obfd) 5851218822Sdim{ 5852218822Sdim Elf_Internal_Ehdr *iehdr; 5853218822Sdim struct elf_segment_map *map; 5854218822Sdim struct elf_segment_map *map_first; 5855218822Sdim struct elf_segment_map **pointer_to_map; 5856218822Sdim Elf_Internal_Phdr *segment; 5857218822Sdim unsigned int i; 5858218822Sdim unsigned int num_segments; 5859218822Sdim bfd_boolean phdr_included = FALSE; 5860218822Sdim 5861218822Sdim iehdr = elf_elfheader (ibfd); 5862218822Sdim 5863218822Sdim map_first = NULL; 5864218822Sdim pointer_to_map = &map_first; 5865218822Sdim 5866218822Sdim num_segments = elf_elfheader (ibfd)->e_phnum; 5867218822Sdim for (i = 0, segment = elf_tdata (ibfd)->phdr; 5868218822Sdim i < num_segments; 5869218822Sdim i++, segment++) 5870218822Sdim { 5871218822Sdim asection *section; 5872218822Sdim unsigned int section_count; 5873218822Sdim bfd_size_type amt; 5874218822Sdim Elf_Internal_Shdr *this_hdr; 5875218822Sdim asection *first_section = NULL; 5876218822Sdim 5877218822Sdim /* FIXME: Do we need to copy PT_NULL segment? */ 5878218822Sdim if (segment->p_type == PT_NULL) 5879218822Sdim continue; 5880218822Sdim 5881218822Sdim /* Compute how many sections are in this segment. */ 5882218822Sdim for (section = ibfd->sections, section_count = 0; 5883218822Sdim section != NULL; 5884218822Sdim section = section->next) 5885218822Sdim { 5886218822Sdim this_hdr = &(elf_section_data(section)->this_hdr); 5887218822Sdim if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment)) 5888218822Sdim { 5889218822Sdim if (!first_section) 5890218822Sdim first_section = section; 5891218822Sdim section_count++; 5892218822Sdim } 5893218822Sdim } 5894218822Sdim 5895218822Sdim /* Allocate a segment map big enough to contain 5896218822Sdim all of the sections we have selected. */ 5897218822Sdim amt = sizeof (struct elf_segment_map); 5898218822Sdim if (section_count != 0) 5899218822Sdim amt += ((bfd_size_type) section_count - 1) * sizeof (asection *); 5900218822Sdim map = bfd_zalloc (obfd, amt); 5901218822Sdim if (map == NULL) 5902218822Sdim return FALSE; 5903218822Sdim 5904218822Sdim /* Initialize the fields of the output segment map with the 5905218822Sdim input segment. */ 5906218822Sdim map->next = NULL; 5907218822Sdim map->p_type = segment->p_type; 5908218822Sdim map->p_flags = segment->p_flags; 5909218822Sdim map->p_flags_valid = 1; 5910218822Sdim map->p_paddr = segment->p_paddr; 5911218822Sdim map->p_paddr_valid = 1; 5912218822Sdim map->p_align = segment->p_align; 5913218822Sdim map->p_align_valid = 1; 5914218822Sdim map->p_vaddr_offset = 0; 5915218822Sdim 5916218822Sdim /* Determine if this segment contains the ELF file header 5917218822Sdim and if it contains the program headers themselves. */ 5918218822Sdim map->includes_filehdr = (segment->p_offset == 0 5919218822Sdim && segment->p_filesz >= iehdr->e_ehsize); 5920218822Sdim 5921218822Sdim map->includes_phdrs = 0; 5922218822Sdim if (! phdr_included || segment->p_type != PT_LOAD) 5923218822Sdim { 5924218822Sdim map->includes_phdrs = 5925218822Sdim (segment->p_offset <= (bfd_vma) iehdr->e_phoff 5926218822Sdim && (segment->p_offset + segment->p_filesz 5927218822Sdim >= ((bfd_vma) iehdr->e_phoff 5928218822Sdim + iehdr->e_phnum * iehdr->e_phentsize))); 5929218822Sdim 5930218822Sdim if (segment->p_type == PT_LOAD && map->includes_phdrs) 5931218822Sdim phdr_included = TRUE; 5932218822Sdim } 5933218822Sdim 5934218822Sdim if (!map->includes_phdrs && !map->includes_filehdr) 5935218822Sdim /* There is some other padding before the first section. */ 5936218822Sdim map->p_vaddr_offset = ((first_section ? first_section->lma : 0) 5937218822Sdim - segment->p_paddr); 5938218822Sdim 5939218822Sdim if (section_count != 0) 5940218822Sdim { 5941218822Sdim unsigned int isec = 0; 5942218822Sdim 5943218822Sdim for (section = first_section; 5944218822Sdim section != NULL; 5945218822Sdim section = section->next) 5946218822Sdim { 5947218822Sdim this_hdr = &(elf_section_data(section)->this_hdr); 5948218822Sdim if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment)) 5949218822Sdim { 5950218822Sdim map->sections[isec++] = section->output_section; 5951218822Sdim if (isec == section_count) 5952218822Sdim break; 5953218822Sdim } 5954218822Sdim } 5955218822Sdim } 5956218822Sdim 5957218822Sdim map->count = section_count; 5958218822Sdim *pointer_to_map = map; 5959218822Sdim pointer_to_map = &map->next; 5960218822Sdim } 5961218822Sdim 5962218822Sdim elf_tdata (obfd)->segment_map = map_first; 5963218822Sdim return TRUE; 5964218822Sdim} 5965218822Sdim 5966218822Sdim/* Copy private BFD data. This copies or rewrites ELF program header 5967218822Sdim information. */ 5968218822Sdim 5969218822Sdimstatic bfd_boolean 5970218822Sdimcopy_private_bfd_data (bfd *ibfd, bfd *obfd) 5971218822Sdim{ 5972218822Sdim if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 5973218822Sdim || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 5974218822Sdim return TRUE; 5975218822Sdim 5976218822Sdim if (elf_tdata (ibfd)->phdr == NULL) 5977218822Sdim return TRUE; 5978218822Sdim 5979218822Sdim if (ibfd->xvec == obfd->xvec) 5980218822Sdim { 5981218822Sdim /* Check to see if any sections in the input BFD 5982218822Sdim covered by ELF program header have changed. */ 5983218822Sdim Elf_Internal_Phdr *segment; 5984218822Sdim asection *section, *osec; 5985218822Sdim unsigned int i, num_segments; 5986218822Sdim Elf_Internal_Shdr *this_hdr; 5987218822Sdim 5988218822Sdim /* Initialize the segment mark field. */ 5989218822Sdim for (section = obfd->sections; section != NULL; 5990218822Sdim section = section->next) 5991218822Sdim section->segment_mark = FALSE; 5992218822Sdim 5993218822Sdim num_segments = elf_elfheader (ibfd)->e_phnum; 5994218822Sdim for (i = 0, segment = elf_tdata (ibfd)->phdr; 5995218822Sdim i < num_segments; 5996218822Sdim i++, segment++) 5997218822Sdim { 5998218822Sdim /* PR binutils/3535. The Solaris linker always sets the p_paddr 5999218822Sdim and p_memsz fields of special segments (DYNAMIC, INTERP) to 0 6000218822Sdim which severly confuses things, so always regenerate the segment 6001218822Sdim map in this case. */ 6002218822Sdim if (segment->p_paddr == 0 6003218822Sdim && segment->p_memsz == 0 6004218822Sdim && (segment->p_type == PT_INTERP || segment->p_type == PT_DYNAMIC)) 6005218822Sdim goto rewrite; 6006218822Sdim 6007218822Sdim for (section = ibfd->sections; 6008218822Sdim section != NULL; section = section->next) 6009218822Sdim { 6010218822Sdim /* We mark the output section so that we know it comes 6011218822Sdim from the input BFD. */ 6012218822Sdim osec = section->output_section; 6013218822Sdim if (osec) 6014218822Sdim osec->segment_mark = TRUE; 6015218822Sdim 6016218822Sdim /* Check if this section is covered by the segment. */ 6017218822Sdim this_hdr = &(elf_section_data(section)->this_hdr); 6018218822Sdim if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment)) 6019218822Sdim { 6020218822Sdim /* FIXME: Check if its output section is changed or 6021218822Sdim removed. What else do we need to check? */ 6022218822Sdim if (osec == NULL 6023218822Sdim || section->flags != osec->flags 6024218822Sdim || section->lma != osec->lma 6025218822Sdim || section->vma != osec->vma 6026218822Sdim || section->size != osec->size 6027218822Sdim || section->rawsize != osec->rawsize 6028218822Sdim || section->alignment_power != osec->alignment_power) 6029218822Sdim goto rewrite; 6030218822Sdim } 6031218822Sdim } 6032218822Sdim } 6033218822Sdim 6034218822Sdim /* Check to see if any output section do not come from the 6035218822Sdim input BFD. */ 6036218822Sdim for (section = obfd->sections; section != NULL; 6037218822Sdim section = section->next) 6038218822Sdim { 6039218822Sdim if (section->segment_mark == FALSE) 6040218822Sdim goto rewrite; 6041218822Sdim else 6042218822Sdim section->segment_mark = FALSE; 6043218822Sdim } 6044218822Sdim 6045218822Sdim return copy_elf_program_header (ibfd, obfd); 6046218822Sdim } 6047218822Sdim 6048218822Sdimrewrite: 6049218822Sdim return rewrite_elf_program_header (ibfd, obfd); 6050218822Sdim} 6051218822Sdim 6052218822Sdim/* Initialize private output section information from input section. */ 6053218822Sdim 6054218822Sdimbfd_boolean 6055218822Sdim_bfd_elf_init_private_section_data (bfd *ibfd, 6056218822Sdim asection *isec, 6057218822Sdim bfd *obfd, 6058218822Sdim asection *osec, 6059218822Sdim struct bfd_link_info *link_info) 6060218822Sdim 6061218822Sdim{ 6062218822Sdim Elf_Internal_Shdr *ihdr, *ohdr; 6063218822Sdim bfd_boolean need_group = link_info == NULL || link_info->relocatable; 6064218822Sdim 6065218822Sdim if (ibfd->xvec->flavour != bfd_target_elf_flavour 6066218822Sdim || obfd->xvec->flavour != bfd_target_elf_flavour) 6067218822Sdim return TRUE; 6068218822Sdim 6069218822Sdim /* Don't copy the output ELF section type from input if the 6070218822Sdim output BFD section flags have been set to something different. 6071218822Sdim elf_fake_sections will set ELF section type based on BFD 6072218822Sdim section flags. */ 6073218822Sdim if (elf_section_type (osec) == SHT_NULL 6074218822Sdim && (osec->flags == isec->flags || !osec->flags)) 6075218822Sdim elf_section_type (osec) = elf_section_type (isec); 6076218822Sdim 6077218822Sdim /* FIXME: Is this correct for all OS/PROC specific flags? */ 6078218822Sdim elf_section_flags (osec) |= (elf_section_flags (isec) 6079218822Sdim & (SHF_MASKOS | SHF_MASKPROC)); 6080218822Sdim 6081218822Sdim /* Set things up for objcopy and relocatable link. The output 6082218822Sdim SHT_GROUP section will have its elf_next_in_group pointing back 6083218822Sdim to the input group members. Ignore linker created group section. 6084218822Sdim See elfNN_ia64_object_p in elfxx-ia64.c. */ 6085218822Sdim if (need_group) 6086218822Sdim { 6087218822Sdim if (elf_sec_group (isec) == NULL 6088218822Sdim || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0) 6089218822Sdim { 6090218822Sdim if (elf_section_flags (isec) & SHF_GROUP) 6091218822Sdim elf_section_flags (osec) |= SHF_GROUP; 6092218822Sdim elf_next_in_group (osec) = elf_next_in_group (isec); 6093218822Sdim elf_group_name (osec) = elf_group_name (isec); 6094218822Sdim } 6095218822Sdim } 6096218822Sdim 6097218822Sdim ihdr = &elf_section_data (isec)->this_hdr; 6098218822Sdim 6099218822Sdim /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We 6100218822Sdim don't use the output section of the linked-to section since it 6101218822Sdim may be NULL at this point. */ 6102218822Sdim if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0) 6103218822Sdim { 6104218822Sdim ohdr = &elf_section_data (osec)->this_hdr; 6105218822Sdim ohdr->sh_flags |= SHF_LINK_ORDER; 6106218822Sdim elf_linked_to_section (osec) = elf_linked_to_section (isec); 6107218822Sdim } 6108218822Sdim 6109218822Sdim osec->use_rela_p = isec->use_rela_p; 6110218822Sdim 6111218822Sdim return TRUE; 6112218822Sdim} 6113218822Sdim 611433965Sjdp/* Copy private section information. This copies over the entsize 611533965Sjdp field, and sometimes the info field. */ 611633965Sjdp 6117130563Sobrienbfd_boolean 6118130563Sobrien_bfd_elf_copy_private_section_data (bfd *ibfd, 6119130563Sobrien asection *isec, 6120130563Sobrien bfd *obfd, 6121130563Sobrien asection *osec) 612233965Sjdp{ 612333965Sjdp Elf_Internal_Shdr *ihdr, *ohdr; 612433965Sjdp 612533965Sjdp if (ibfd->xvec->flavour != bfd_target_elf_flavour 612633965Sjdp || obfd->xvec->flavour != bfd_target_elf_flavour) 6127130563Sobrien return TRUE; 612833965Sjdp 612933965Sjdp ihdr = &elf_section_data (isec)->this_hdr; 613033965Sjdp ohdr = &elf_section_data (osec)->this_hdr; 613133965Sjdp 613233965Sjdp ohdr->sh_entsize = ihdr->sh_entsize; 613333965Sjdp 613433965Sjdp if (ihdr->sh_type == SHT_SYMTAB 613533965Sjdp || ihdr->sh_type == SHT_DYNSYM 613633965Sjdp || ihdr->sh_type == SHT_GNU_verneed 613733965Sjdp || ihdr->sh_type == SHT_GNU_verdef) 613833965Sjdp ohdr->sh_info = ihdr->sh_info; 613933965Sjdp 6140218822Sdim return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec, 6141218822Sdim NULL); 6142218822Sdim} 6143104838Sobrien 6144218822Sdim/* Copy private header information. */ 614560508Sobrien 6146218822Sdimbfd_boolean 6147218822Sdim_bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd) 6148218822Sdim{ 6149218822Sdim asection *isec; 6150218822Sdim 6151218822Sdim if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 6152218822Sdim || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 6153218822Sdim return TRUE; 6154218822Sdim 6155218822Sdim /* Copy over private BFD data if it has not already been copied. 6156218822Sdim This must be done here, rather than in the copy_private_bfd_data 6157218822Sdim entry point, because the latter is called after the section 6158218822Sdim contents have been set, which means that the program headers have 6159218822Sdim already been worked out. */ 6160218822Sdim if (elf_tdata (obfd)->segment_map == NULL && elf_tdata (ibfd)->phdr != NULL) 6161218822Sdim { 6162218822Sdim if (! copy_private_bfd_data (ibfd, obfd)) 6163218822Sdim return FALSE; 6164218822Sdim } 6165218822Sdim 6166218822Sdim /* _bfd_elf_copy_private_section_data copied over the SHF_GROUP flag 6167218822Sdim but this might be wrong if we deleted the group section. */ 6168218822Sdim for (isec = ibfd->sections; isec != NULL; isec = isec->next) 6169218822Sdim if (elf_section_type (isec) == SHT_GROUP 6170218822Sdim && isec->output_section == NULL) 6171218822Sdim { 6172218822Sdim asection *first = elf_next_in_group (isec); 6173218822Sdim asection *s = first; 6174218822Sdim while (s != NULL) 6175218822Sdim { 6176218822Sdim if (s->output_section != NULL) 6177218822Sdim { 6178218822Sdim elf_section_flags (s->output_section) &= ~SHF_GROUP; 6179218822Sdim elf_group_name (s->output_section) = NULL; 6180218822Sdim } 6181218822Sdim s = elf_next_in_group (s); 6182218822Sdim if (s == first) 6183218822Sdim break; 6184218822Sdim } 6185218822Sdim } 6186218822Sdim 6187130563Sobrien return TRUE; 618833965Sjdp} 618933965Sjdp 619033965Sjdp/* Copy private symbol information. If this symbol is in a section 619133965Sjdp which we did not map into a BFD section, try to map the section 619233965Sjdp index correctly. We use special macro definitions for the mapped 619333965Sjdp section indices; these definitions are interpreted by the 619433965Sjdp swap_out_syms function. */ 619533965Sjdp 619689860Sobrien#define MAP_ONESYMTAB (SHN_HIOS + 1) 619789860Sobrien#define MAP_DYNSYMTAB (SHN_HIOS + 2) 619889860Sobrien#define MAP_STRTAB (SHN_HIOS + 3) 619989860Sobrien#define MAP_SHSTRTAB (SHN_HIOS + 4) 620089860Sobrien#define MAP_SYM_SHNDX (SHN_HIOS + 5) 620133965Sjdp 6202130563Sobrienbfd_boolean 6203130563Sobrien_bfd_elf_copy_private_symbol_data (bfd *ibfd, 6204130563Sobrien asymbol *isymarg, 6205130563Sobrien bfd *obfd, 6206130563Sobrien asymbol *osymarg) 620733965Sjdp{ 620833965Sjdp elf_symbol_type *isym, *osym; 620933965Sjdp 621033965Sjdp if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 621133965Sjdp || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 6212130563Sobrien return TRUE; 621333965Sjdp 621433965Sjdp isym = elf_symbol_from (ibfd, isymarg); 621533965Sjdp osym = elf_symbol_from (obfd, osymarg); 621633965Sjdp 621733965Sjdp if (isym != NULL 621833965Sjdp && osym != NULL 621933965Sjdp && bfd_is_abs_section (isym->symbol.section)) 622033965Sjdp { 622133965Sjdp unsigned int shndx; 622233965Sjdp 622333965Sjdp shndx = isym->internal_elf_sym.st_shndx; 622433965Sjdp if (shndx == elf_onesymtab (ibfd)) 622533965Sjdp shndx = MAP_ONESYMTAB; 622633965Sjdp else if (shndx == elf_dynsymtab (ibfd)) 622733965Sjdp shndx = MAP_DYNSYMTAB; 622833965Sjdp else if (shndx == elf_tdata (ibfd)->strtab_section) 622933965Sjdp shndx = MAP_STRTAB; 623033965Sjdp else if (shndx == elf_tdata (ibfd)->shstrtab_section) 623133965Sjdp shndx = MAP_SHSTRTAB; 623289860Sobrien else if (shndx == elf_tdata (ibfd)->symtab_shndx_section) 623389860Sobrien shndx = MAP_SYM_SHNDX; 623433965Sjdp osym->internal_elf_sym.st_shndx = shndx; 623533965Sjdp } 623633965Sjdp 6237130563Sobrien return TRUE; 623833965Sjdp} 623933965Sjdp 624033965Sjdp/* Swap out the symbols. */ 624133965Sjdp 6242130563Sobrienstatic bfd_boolean 6243130563Sobrienswap_out_syms (bfd *abfd, 6244130563Sobrien struct bfd_strtab_hash **sttp, 6245130563Sobrien int relocatable_p) 624633965Sjdp{ 6247130563Sobrien const struct elf_backend_data *bed; 624889860Sobrien int symcount; 624989860Sobrien asymbol **syms; 625089860Sobrien struct bfd_strtab_hash *stt; 625189860Sobrien Elf_Internal_Shdr *symtab_hdr; 625289860Sobrien Elf_Internal_Shdr *symtab_shndx_hdr; 625389860Sobrien Elf_Internal_Shdr *symstrtab_hdr; 6254218822Sdim bfd_byte *outbound_syms; 6255218822Sdim bfd_byte *outbound_shndx; 625689860Sobrien int idx; 625789860Sobrien bfd_size_type amt; 6258130563Sobrien bfd_boolean name_local_sections; 625933965Sjdp 626033965Sjdp if (!elf_map_symbols (abfd)) 6261130563Sobrien return FALSE; 626233965Sjdp 626377301Sobrien /* Dump out the symtabs. */ 626489860Sobrien stt = _bfd_elf_stringtab_init (); 626589860Sobrien if (stt == NULL) 6266130563Sobrien return FALSE; 626733965Sjdp 626889860Sobrien bed = get_elf_backend_data (abfd); 626989860Sobrien symcount = bfd_get_symcount (abfd); 627089860Sobrien symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 627189860Sobrien symtab_hdr->sh_type = SHT_SYMTAB; 627289860Sobrien symtab_hdr->sh_entsize = bed->s->sizeof_sym; 627389860Sobrien symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1); 627489860Sobrien symtab_hdr->sh_info = elf_num_locals (abfd) + 1; 6275130563Sobrien symtab_hdr->sh_addralign = 1 << bed->s->log_file_align; 627633965Sjdp 627789860Sobrien symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; 627889860Sobrien symstrtab_hdr->sh_type = SHT_STRTAB; 627933965Sjdp 6280218822Sdim outbound_syms = bfd_alloc2 (abfd, 1 + symcount, bed->s->sizeof_sym); 628189860Sobrien if (outbound_syms == NULL) 6282130563Sobrien { 6283130563Sobrien _bfd_stringtab_free (stt); 6284130563Sobrien return FALSE; 6285130563Sobrien } 6286130563Sobrien symtab_hdr->contents = outbound_syms; 628733965Sjdp 628889860Sobrien outbound_shndx = NULL; 628989860Sobrien symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; 629089860Sobrien if (symtab_shndx_hdr->sh_name != 0) 629189860Sobrien { 629289860Sobrien amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx); 6293218822Sdim outbound_shndx = bfd_zalloc2 (abfd, 1 + symcount, 6294218822Sdim sizeof (Elf_External_Sym_Shndx)); 629589860Sobrien if (outbound_shndx == NULL) 6296130563Sobrien { 6297130563Sobrien _bfd_stringtab_free (stt); 6298130563Sobrien return FALSE; 6299130563Sobrien } 6300130563Sobrien 630189860Sobrien symtab_shndx_hdr->contents = outbound_shndx; 630289860Sobrien symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; 630389860Sobrien symtab_shndx_hdr->sh_size = amt; 630489860Sobrien symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); 630589860Sobrien symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); 630689860Sobrien } 630733965Sjdp 6308130563Sobrien /* Now generate the data (for "contents"). */ 630989860Sobrien { 631089860Sobrien /* Fill in zeroth symbol and swap it out. */ 631189860Sobrien Elf_Internal_Sym sym; 631289860Sobrien sym.st_name = 0; 631389860Sobrien sym.st_value = 0; 631489860Sobrien sym.st_size = 0; 631589860Sobrien sym.st_info = 0; 631689860Sobrien sym.st_other = 0; 631789860Sobrien sym.st_shndx = SHN_UNDEF; 631889860Sobrien bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx); 631989860Sobrien outbound_syms += bed->s->sizeof_sym; 632089860Sobrien if (outbound_shndx != NULL) 632189860Sobrien outbound_shndx += sizeof (Elf_External_Sym_Shndx); 632289860Sobrien } 632389860Sobrien 6324130563Sobrien name_local_sections 6325130563Sobrien = (bed->elf_backend_name_local_section_symbols 6326130563Sobrien && bed->elf_backend_name_local_section_symbols (abfd)); 6327130563Sobrien 632889860Sobrien syms = bfd_get_outsymbols (abfd); 632989860Sobrien for (idx = 0; idx < symcount; idx++) 633033965Sjdp { 633133965Sjdp Elf_Internal_Sym sym; 633289860Sobrien bfd_vma value = syms[idx]->value; 633389860Sobrien elf_symbol_type *type_ptr; 633489860Sobrien flagword flags = syms[idx]->flags; 633589860Sobrien int type; 633633965Sjdp 6337130563Sobrien if (!name_local_sections 6338130563Sobrien && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM) 633989860Sobrien { 634089860Sobrien /* Local section symbols have no name. */ 634189860Sobrien sym.st_name = 0; 634289860Sobrien } 634389860Sobrien else 634489860Sobrien { 634589860Sobrien sym.st_name = (unsigned long) _bfd_stringtab_add (stt, 634689860Sobrien syms[idx]->name, 6347130563Sobrien TRUE, FALSE); 634889860Sobrien if (sym.st_name == (unsigned long) -1) 6349130563Sobrien { 6350130563Sobrien _bfd_stringtab_free (stt); 6351130563Sobrien return FALSE; 6352130563Sobrien } 635389860Sobrien } 635433965Sjdp 635589860Sobrien type_ptr = elf_symbol_from (abfd, syms[idx]); 635633965Sjdp 635789860Sobrien if ((flags & BSF_SECTION_SYM) == 0 635889860Sobrien && bfd_is_com_section (syms[idx]->section)) 635989860Sobrien { 636089860Sobrien /* ELF common symbols put the alignment into the `value' field, 636189860Sobrien and the size into the `size' field. This is backwards from 636289860Sobrien how BFD handles it, so reverse it here. */ 636389860Sobrien sym.st_size = value; 636489860Sobrien if (type_ptr == NULL 636589860Sobrien || type_ptr->internal_elf_sym.st_value == 0) 636689860Sobrien sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value)); 636789860Sobrien else 636889860Sobrien sym.st_value = type_ptr->internal_elf_sym.st_value; 636989860Sobrien sym.st_shndx = _bfd_elf_section_from_bfd_section 637089860Sobrien (abfd, syms[idx]->section); 637189860Sobrien } 637289860Sobrien else 637389860Sobrien { 637489860Sobrien asection *sec = syms[idx]->section; 637589860Sobrien int shndx; 637633965Sjdp 637789860Sobrien if (sec->output_section) 637889860Sobrien { 637989860Sobrien value += sec->output_offset; 638089860Sobrien sec = sec->output_section; 638189860Sobrien } 6382130563Sobrien 638389860Sobrien /* Don't add in the section vma for relocatable output. */ 638489860Sobrien if (! relocatable_p) 638589860Sobrien value += sec->vma; 638689860Sobrien sym.st_value = value; 638789860Sobrien sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0; 638833965Sjdp 638989860Sobrien if (bfd_is_abs_section (sec) 639089860Sobrien && type_ptr != NULL 639189860Sobrien && type_ptr->internal_elf_sym.st_shndx != 0) 639289860Sobrien { 639389860Sobrien /* This symbol is in a real ELF section which we did 639489860Sobrien not create as a BFD section. Undo the mapping done 639589860Sobrien by copy_private_symbol_data. */ 639689860Sobrien shndx = type_ptr->internal_elf_sym.st_shndx; 639789860Sobrien switch (shndx) 639889860Sobrien { 639989860Sobrien case MAP_ONESYMTAB: 640089860Sobrien shndx = elf_onesymtab (abfd); 640189860Sobrien break; 640289860Sobrien case MAP_DYNSYMTAB: 640389860Sobrien shndx = elf_dynsymtab (abfd); 640489860Sobrien break; 640589860Sobrien case MAP_STRTAB: 640689860Sobrien shndx = elf_tdata (abfd)->strtab_section; 640789860Sobrien break; 640889860Sobrien case MAP_SHSTRTAB: 640989860Sobrien shndx = elf_tdata (abfd)->shstrtab_section; 641089860Sobrien break; 641189860Sobrien case MAP_SYM_SHNDX: 641289860Sobrien shndx = elf_tdata (abfd)->symtab_shndx_section; 641389860Sobrien break; 641489860Sobrien default: 641589860Sobrien break; 641689860Sobrien } 641789860Sobrien } 641889860Sobrien else 641989860Sobrien { 642089860Sobrien shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 642133965Sjdp 642289860Sobrien if (shndx == -1) 642389860Sobrien { 642489860Sobrien asection *sec2; 642533965Sjdp 642689860Sobrien /* Writing this would be a hell of a lot easier if 642789860Sobrien we had some decent documentation on bfd, and 642889860Sobrien knew what to expect of the library, and what to 642989860Sobrien demand of applications. For example, it 643089860Sobrien appears that `objcopy' might not set the 643189860Sobrien section of a symbol to be a section that is 643289860Sobrien actually in the output file. */ 643389860Sobrien sec2 = bfd_get_section_by_name (abfd, sec->name); 6434130563Sobrien if (sec2 == NULL) 6435130563Sobrien { 6436130563Sobrien _bfd_error_handler (_("\ 6437130563SobrienUnable to find equivalent output section for symbol '%s' from section '%s'"), 6438130563Sobrien syms[idx]->name ? syms[idx]->name : "<Local sym>", 6439130563Sobrien sec->name); 6440130563Sobrien bfd_set_error (bfd_error_invalid_operation); 6441130563Sobrien _bfd_stringtab_free (stt); 6442130563Sobrien return FALSE; 6443130563Sobrien } 6444130563Sobrien 644589860Sobrien shndx = _bfd_elf_section_from_bfd_section (abfd, sec2); 644689860Sobrien BFD_ASSERT (shndx != -1); 644789860Sobrien } 644889860Sobrien } 644933965Sjdp 645089860Sobrien sym.st_shndx = shndx; 645189860Sobrien } 645233965Sjdp 6453104838Sobrien if ((flags & BSF_THREAD_LOCAL) != 0) 6454104838Sobrien type = STT_TLS; 6455104838Sobrien else if ((flags & BSF_FUNCTION) != 0) 645689860Sobrien type = STT_FUNC; 645789860Sobrien else if ((flags & BSF_OBJECT) != 0) 645889860Sobrien type = STT_OBJECT; 6459218822Sdim else if ((flags & BSF_RELC) != 0) 6460218822Sdim type = STT_RELC; 6461218822Sdim else if ((flags & BSF_SRELC) != 0) 6462218822Sdim type = STT_SRELC; 646389860Sobrien else 646489860Sobrien type = STT_NOTYPE; 646533965Sjdp 6466104838Sobrien if (syms[idx]->section->flags & SEC_THREAD_LOCAL) 6467104838Sobrien type = STT_TLS; 6468104838Sobrien 6469130563Sobrien /* Processor-specific types. */ 647089860Sobrien if (type_ptr != NULL 647189860Sobrien && bed->elf_backend_get_symbol_type) 647289860Sobrien type = ((*bed->elf_backend_get_symbol_type) 647389860Sobrien (&type_ptr->internal_elf_sym, type)); 647460508Sobrien 647589860Sobrien if (flags & BSF_SECTION_SYM) 647689860Sobrien { 647789860Sobrien if (flags & BSF_GLOBAL) 647889860Sobrien sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); 647989860Sobrien else 648089860Sobrien sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); 648189860Sobrien } 648289860Sobrien else if (bfd_is_com_section (syms[idx]->section)) 648389860Sobrien sym.st_info = ELF_ST_INFO (STB_GLOBAL, type); 648489860Sobrien else if (bfd_is_und_section (syms[idx]->section)) 648589860Sobrien sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK) 648689860Sobrien ? STB_WEAK 648789860Sobrien : STB_GLOBAL), 648889860Sobrien type); 648989860Sobrien else if (flags & BSF_FILE) 649089860Sobrien sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); 649189860Sobrien else 649289860Sobrien { 649389860Sobrien int bind = STB_LOCAL; 649433965Sjdp 649589860Sobrien if (flags & BSF_LOCAL) 649689860Sobrien bind = STB_LOCAL; 649789860Sobrien else if (flags & BSF_WEAK) 649889860Sobrien bind = STB_WEAK; 649989860Sobrien else if (flags & BSF_GLOBAL) 650089860Sobrien bind = STB_GLOBAL; 650133965Sjdp 650289860Sobrien sym.st_info = ELF_ST_INFO (bind, type); 650389860Sobrien } 650433965Sjdp 650589860Sobrien if (type_ptr != NULL) 650689860Sobrien sym.st_other = type_ptr->internal_elf_sym.st_other; 650789860Sobrien else 650889860Sobrien sym.st_other = 0; 650933965Sjdp 651089860Sobrien bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx); 651189860Sobrien outbound_syms += bed->s->sizeof_sym; 651289860Sobrien if (outbound_shndx != NULL) 651389860Sobrien outbound_shndx += sizeof (Elf_External_Sym_Shndx); 651489860Sobrien } 651533965Sjdp 651689860Sobrien *sttp = stt; 651789860Sobrien symstrtab_hdr->sh_size = _bfd_stringtab_size (stt); 651889860Sobrien symstrtab_hdr->sh_type = SHT_STRTAB; 651933965Sjdp 652089860Sobrien symstrtab_hdr->sh_flags = 0; 652189860Sobrien symstrtab_hdr->sh_addr = 0; 652289860Sobrien symstrtab_hdr->sh_entsize = 0; 652389860Sobrien symstrtab_hdr->sh_link = 0; 652489860Sobrien symstrtab_hdr->sh_info = 0; 652589860Sobrien symstrtab_hdr->sh_addralign = 1; 652633965Sjdp 6527130563Sobrien return TRUE; 652833965Sjdp} 652933965Sjdp 653033965Sjdp/* Return the number of bytes required to hold the symtab vector. 653133965Sjdp 653233965Sjdp Note that we base it on the count plus 1, since we will null terminate 653333965Sjdp the vector allocated based on this size. However, the ELF symbol table 653433965Sjdp always has a dummy entry as symbol #0, so it ends up even. */ 653533965Sjdp 653633965Sjdplong 6537130563Sobrien_bfd_elf_get_symtab_upper_bound (bfd *abfd) 653833965Sjdp{ 653933965Sjdp long symcount; 654033965Sjdp long symtab_size; 654133965Sjdp Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; 654233965Sjdp 654333965Sjdp symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; 654494542Sobrien symtab_size = (symcount + 1) * (sizeof (asymbol *)); 654594542Sobrien if (symcount > 0) 654694542Sobrien symtab_size -= sizeof (asymbol *); 654733965Sjdp 654833965Sjdp return symtab_size; 654933965Sjdp} 655033965Sjdp 655133965Sjdplong 6552130563Sobrien_bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) 655333965Sjdp{ 655433965Sjdp long symcount; 655533965Sjdp long symtab_size; 655633965Sjdp Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr; 655733965Sjdp 655833965Sjdp if (elf_dynsymtab (abfd) == 0) 655933965Sjdp { 656033965Sjdp bfd_set_error (bfd_error_invalid_operation); 656133965Sjdp return -1; 656233965Sjdp } 656333965Sjdp 656433965Sjdp symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; 656594542Sobrien symtab_size = (symcount + 1) * (sizeof (asymbol *)); 656694542Sobrien if (symcount > 0) 656794542Sobrien symtab_size -= sizeof (asymbol *); 656833965Sjdp 656933965Sjdp return symtab_size; 657033965Sjdp} 657133965Sjdp 657233965Sjdplong 6573130563Sobrien_bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, 6574130563Sobrien sec_ptr asect) 657533965Sjdp{ 657633965Sjdp return (asect->reloc_count + 1) * sizeof (arelent *); 657733965Sjdp} 657833965Sjdp 657933965Sjdp/* Canonicalize the relocs. */ 658033965Sjdp 658133965Sjdplong 6582130563Sobrien_bfd_elf_canonicalize_reloc (bfd *abfd, 6583130563Sobrien sec_ptr section, 6584130563Sobrien arelent **relptr, 6585130563Sobrien asymbol **symbols) 658633965Sjdp{ 658733965Sjdp arelent *tblptr; 658833965Sjdp unsigned int i; 6589130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 659033965Sjdp 6591130563Sobrien if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE)) 659233965Sjdp return -1; 659333965Sjdp 659433965Sjdp tblptr = section->relocation; 659533965Sjdp for (i = 0; i < section->reloc_count; i++) 659633965Sjdp *relptr++ = tblptr++; 659733965Sjdp 659833965Sjdp *relptr = NULL; 659933965Sjdp 660033965Sjdp return section->reloc_count; 660133965Sjdp} 660233965Sjdp 660333965Sjdplong 6604130563Sobrien_bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation) 660533965Sjdp{ 6606130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 6607130563Sobrien long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE); 660833965Sjdp 660933965Sjdp if (symcount >= 0) 661033965Sjdp bfd_get_symcount (abfd) = symcount; 661133965Sjdp return symcount; 661233965Sjdp} 661333965Sjdp 661433965Sjdplong 6615130563Sobrien_bfd_elf_canonicalize_dynamic_symtab (bfd *abfd, 6616130563Sobrien asymbol **allocation) 661733965Sjdp{ 6618130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 6619130563Sobrien long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE); 6620104838Sobrien 6621104838Sobrien if (symcount >= 0) 6622104838Sobrien bfd_get_dynamic_symcount (abfd) = symcount; 6623104838Sobrien return symcount; 662433965Sjdp} 662533965Sjdp 6626218822Sdim/* Return the size required for the dynamic reloc entries. Any loadable 6627218822Sdim section that was actually installed in the BFD, and has type SHT_REL 6628218822Sdim or SHT_RELA, and uses the dynamic symbol table, is considered to be a 6629218822Sdim dynamic reloc section. */ 663033965Sjdp 663133965Sjdplong 6632130563Sobrien_bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) 663333965Sjdp{ 663433965Sjdp long ret; 663533965Sjdp asection *s; 663633965Sjdp 663733965Sjdp if (elf_dynsymtab (abfd) == 0) 663833965Sjdp { 663933965Sjdp bfd_set_error (bfd_error_invalid_operation); 664033965Sjdp return -1; 664133965Sjdp } 664233965Sjdp 664333965Sjdp ret = sizeof (arelent *); 664433965Sjdp for (s = abfd->sections; s != NULL; s = s->next) 6645218822Sdim if ((s->flags & SEC_LOAD) != 0 6646218822Sdim && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) 664733965Sjdp && (elf_section_data (s)->this_hdr.sh_type == SHT_REL 664833965Sjdp || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)) 6649218822Sdim ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize) 665033965Sjdp * sizeof (arelent *)); 665133965Sjdp 665233965Sjdp return ret; 665333965Sjdp} 665433965Sjdp 6655218822Sdim/* Canonicalize the dynamic relocation entries. Note that we return the 6656218822Sdim dynamic relocations as a single block, although they are actually 6657218822Sdim associated with particular sections; the interface, which was 6658218822Sdim designed for SunOS style shared libraries, expects that there is only 6659218822Sdim one set of dynamic relocs. Any loadable section that was actually 6660218822Sdim installed in the BFD, and has type SHT_REL or SHT_RELA, and uses the 6661218822Sdim dynamic symbol table, is considered to be a dynamic reloc section. */ 666233965Sjdp 666333965Sjdplong 6664130563Sobrien_bfd_elf_canonicalize_dynamic_reloc (bfd *abfd, 6665130563Sobrien arelent **storage, 6666130563Sobrien asymbol **syms) 666733965Sjdp{ 6668130563Sobrien bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean); 666933965Sjdp asection *s; 667033965Sjdp long ret; 667133965Sjdp 667233965Sjdp if (elf_dynsymtab (abfd) == 0) 667333965Sjdp { 667433965Sjdp bfd_set_error (bfd_error_invalid_operation); 667533965Sjdp return -1; 667633965Sjdp } 667733965Sjdp 667833965Sjdp slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; 667933965Sjdp ret = 0; 668033965Sjdp for (s = abfd->sections; s != NULL; s = s->next) 668133965Sjdp { 6682218822Sdim if ((s->flags & SEC_LOAD) != 0 6683218822Sdim && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) 668433965Sjdp && (elf_section_data (s)->this_hdr.sh_type == SHT_REL 668533965Sjdp || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)) 668633965Sjdp { 668733965Sjdp arelent *p; 668833965Sjdp long count, i; 668933965Sjdp 6690130563Sobrien if (! (*slurp_relocs) (abfd, s, syms, TRUE)) 669133965Sjdp return -1; 6692218822Sdim count = s->size / elf_section_data (s)->this_hdr.sh_entsize; 669333965Sjdp p = s->relocation; 669433965Sjdp for (i = 0; i < count; i++) 669533965Sjdp *storage++ = p++; 669633965Sjdp ret += count; 669733965Sjdp } 669833965Sjdp } 669933965Sjdp 670033965Sjdp *storage = NULL; 670133965Sjdp 670233965Sjdp return ret; 670333965Sjdp} 670433965Sjdp 670533965Sjdp/* Read in the version information. */ 670633965Sjdp 6707130563Sobrienbfd_boolean 6708218822Sdim_bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) 670933965Sjdp{ 671033965Sjdp bfd_byte *contents = NULL; 6711218822Sdim unsigned int freeidx = 0; 671233965Sjdp 6713218822Sdim if (elf_dynverref (abfd) != 0) 6714218822Sdim { 6715218822Sdim Elf_Internal_Shdr *hdr; 6716218822Sdim Elf_External_Verneed *everneed; 6717218822Sdim Elf_Internal_Verneed *iverneed; 6718218822Sdim unsigned int i; 6719218822Sdim bfd_byte *contents_end; 6720218822Sdim 6721218822Sdim hdr = &elf_tdata (abfd)->dynverref_hdr; 6722218822Sdim 6723218822Sdim elf_tdata (abfd)->verref = bfd_zalloc2 (abfd, hdr->sh_info, 6724218822Sdim sizeof (Elf_Internal_Verneed)); 6725218822Sdim if (elf_tdata (abfd)->verref == NULL) 6726218822Sdim goto error_return; 6727218822Sdim 6728218822Sdim elf_tdata (abfd)->cverrefs = hdr->sh_info; 6729218822Sdim 6730218822Sdim contents = bfd_malloc (hdr->sh_size); 6731218822Sdim if (contents == NULL) 6732218822Sdim { 6733218822Sdimerror_return_verref: 6734218822Sdim elf_tdata (abfd)->verref = NULL; 6735218822Sdim elf_tdata (abfd)->cverrefs = 0; 6736218822Sdim goto error_return; 6737218822Sdim } 6738218822Sdim if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 6739218822Sdim || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) 6740218822Sdim goto error_return_verref; 6741218822Sdim 6742218822Sdim if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed)) 6743218822Sdim goto error_return_verref; 6744218822Sdim 6745218822Sdim BFD_ASSERT (sizeof (Elf_External_Verneed) 6746218822Sdim == sizeof (Elf_External_Vernaux)); 6747218822Sdim contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed); 6748218822Sdim everneed = (Elf_External_Verneed *) contents; 6749218822Sdim iverneed = elf_tdata (abfd)->verref; 6750218822Sdim for (i = 0; i < hdr->sh_info; i++, iverneed++) 6751218822Sdim { 6752218822Sdim Elf_External_Vernaux *evernaux; 6753218822Sdim Elf_Internal_Vernaux *ivernaux; 6754218822Sdim unsigned int j; 6755218822Sdim 6756218822Sdim _bfd_elf_swap_verneed_in (abfd, everneed, iverneed); 6757218822Sdim 6758218822Sdim iverneed->vn_bfd = abfd; 6759218822Sdim 6760218822Sdim iverneed->vn_filename = 6761218822Sdim bfd_elf_string_from_elf_section (abfd, hdr->sh_link, 6762218822Sdim iverneed->vn_file); 6763218822Sdim if (iverneed->vn_filename == NULL) 6764218822Sdim goto error_return_verref; 6765218822Sdim 6766218822Sdim if (iverneed->vn_cnt == 0) 6767218822Sdim iverneed->vn_auxptr = NULL; 6768218822Sdim else 6769218822Sdim { 6770218822Sdim iverneed->vn_auxptr = bfd_alloc2 (abfd, iverneed->vn_cnt, 6771218822Sdim sizeof (Elf_Internal_Vernaux)); 6772218822Sdim if (iverneed->vn_auxptr == NULL) 6773218822Sdim goto error_return_verref; 6774218822Sdim } 6775218822Sdim 6776218822Sdim if (iverneed->vn_aux 6777218822Sdim > (size_t) (contents_end - (bfd_byte *) everneed)) 6778218822Sdim goto error_return_verref; 6779218822Sdim 6780218822Sdim evernaux = ((Elf_External_Vernaux *) 6781218822Sdim ((bfd_byte *) everneed + iverneed->vn_aux)); 6782218822Sdim ivernaux = iverneed->vn_auxptr; 6783218822Sdim for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++) 6784218822Sdim { 6785218822Sdim _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux); 6786218822Sdim 6787218822Sdim ivernaux->vna_nodename = 6788218822Sdim bfd_elf_string_from_elf_section (abfd, hdr->sh_link, 6789218822Sdim ivernaux->vna_name); 6790218822Sdim if (ivernaux->vna_nodename == NULL) 6791218822Sdim goto error_return_verref; 6792218822Sdim 6793218822Sdim if (j + 1 < iverneed->vn_cnt) 6794218822Sdim ivernaux->vna_nextptr = ivernaux + 1; 6795218822Sdim else 6796218822Sdim ivernaux->vna_nextptr = NULL; 6797218822Sdim 6798218822Sdim if (ivernaux->vna_next 6799218822Sdim > (size_t) (contents_end - (bfd_byte *) evernaux)) 6800218822Sdim goto error_return_verref; 6801218822Sdim 6802218822Sdim evernaux = ((Elf_External_Vernaux *) 6803218822Sdim ((bfd_byte *) evernaux + ivernaux->vna_next)); 6804218822Sdim 6805218822Sdim if (ivernaux->vna_other > freeidx) 6806218822Sdim freeidx = ivernaux->vna_other; 6807218822Sdim } 6808218822Sdim 6809218822Sdim if (i + 1 < hdr->sh_info) 6810218822Sdim iverneed->vn_nextref = iverneed + 1; 6811218822Sdim else 6812218822Sdim iverneed->vn_nextref = NULL; 6813218822Sdim 6814218822Sdim if (iverneed->vn_next 6815218822Sdim > (size_t) (contents_end - (bfd_byte *) everneed)) 6816218822Sdim goto error_return_verref; 6817218822Sdim 6818218822Sdim everneed = ((Elf_External_Verneed *) 6819218822Sdim ((bfd_byte *) everneed + iverneed->vn_next)); 6820218822Sdim } 6821218822Sdim 6822218822Sdim free (contents); 6823218822Sdim contents = NULL; 6824218822Sdim } 6825218822Sdim 682633965Sjdp if (elf_dynverdef (abfd) != 0) 682733965Sjdp { 682833965Sjdp Elf_Internal_Shdr *hdr; 682933965Sjdp Elf_External_Verdef *everdef; 683033965Sjdp Elf_Internal_Verdef *iverdef; 683168767Sobrien Elf_Internal_Verdef *iverdefarr; 683268767Sobrien Elf_Internal_Verdef iverdefmem; 683333965Sjdp unsigned int i; 683468767Sobrien unsigned int maxidx; 6835218822Sdim bfd_byte *contents_end_def, *contents_end_aux; 683633965Sjdp 683733965Sjdp hdr = &elf_tdata (abfd)->dynverdef_hdr; 683833965Sjdp 6839130563Sobrien contents = bfd_malloc (hdr->sh_size); 684033965Sjdp if (contents == NULL) 684133965Sjdp goto error_return; 684233965Sjdp if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 6843130563Sobrien || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) 684433965Sjdp goto error_return; 684533965Sjdp 6846218822Sdim if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef)) 6847218822Sdim goto error_return; 6848218822Sdim 6849218822Sdim BFD_ASSERT (sizeof (Elf_External_Verdef) 6850218822Sdim >= sizeof (Elf_External_Verdaux)); 6851218822Sdim contents_end_def = contents + hdr->sh_size 6852218822Sdim - sizeof (Elf_External_Verdef); 6853218822Sdim contents_end_aux = contents + hdr->sh_size 6854218822Sdim - sizeof (Elf_External_Verdaux); 6855218822Sdim 685668767Sobrien /* We know the number of entries in the section but not the maximum 685768767Sobrien index. Therefore we have to run through all entries and find 685868767Sobrien the maximum. */ 685933965Sjdp everdef = (Elf_External_Verdef *) contents; 686068767Sobrien maxidx = 0; 686168767Sobrien for (i = 0; i < hdr->sh_info; ++i) 686233965Sjdp { 686368767Sobrien _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem); 686468767Sobrien 686578831Sobrien if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx) 686678831Sobrien maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION); 686768767Sobrien 6868218822Sdim if (iverdefmem.vd_next 6869218822Sdim > (size_t) (contents_end_def - (bfd_byte *) everdef)) 6870218822Sdim goto error_return; 6871218822Sdim 687268767Sobrien everdef = ((Elf_External_Verdef *) 687368767Sobrien ((bfd_byte *) everdef + iverdefmem.vd_next)); 687468767Sobrien } 687568767Sobrien 6876218822Sdim if (default_imported_symver) 6877218822Sdim { 6878218822Sdim if (freeidx > maxidx) 6879218822Sdim maxidx = ++freeidx; 6880218822Sdim else 6881218822Sdim freeidx = ++maxidx; 6882218822Sdim } 6883218822Sdim elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, maxidx, 6884218822Sdim sizeof (Elf_Internal_Verdef)); 688568767Sobrien if (elf_tdata (abfd)->verdef == NULL) 688668767Sobrien goto error_return; 688768767Sobrien 688868767Sobrien elf_tdata (abfd)->cverdefs = maxidx; 688968767Sobrien 689068767Sobrien everdef = (Elf_External_Verdef *) contents; 689168767Sobrien iverdefarr = elf_tdata (abfd)->verdef; 689268767Sobrien for (i = 0; i < hdr->sh_info; i++) 689368767Sobrien { 689433965Sjdp Elf_External_Verdaux *everdaux; 689533965Sjdp Elf_Internal_Verdaux *iverdaux; 689633965Sjdp unsigned int j; 689733965Sjdp 689868767Sobrien _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem); 689933965Sjdp 6900218822Sdim if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0) 6901218822Sdim { 6902218822Sdimerror_return_verdef: 6903218822Sdim elf_tdata (abfd)->verdef = NULL; 6904218822Sdim elf_tdata (abfd)->cverdefs = 0; 6905218822Sdim goto error_return; 6906218822Sdim } 6907218822Sdim 690868767Sobrien iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1]; 690968767Sobrien memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef)); 691068767Sobrien 691133965Sjdp iverdef->vd_bfd = abfd; 691233965Sjdp 6913218822Sdim if (iverdef->vd_cnt == 0) 6914218822Sdim iverdef->vd_auxptr = NULL; 6915218822Sdim else 6916218822Sdim { 6917218822Sdim iverdef->vd_auxptr = bfd_alloc2 (abfd, iverdef->vd_cnt, 6918218822Sdim sizeof (Elf_Internal_Verdaux)); 6919218822Sdim if (iverdef->vd_auxptr == NULL) 6920218822Sdim goto error_return_verdef; 6921218822Sdim } 692233965Sjdp 6923218822Sdim if (iverdef->vd_aux 6924218822Sdim > (size_t) (contents_end_aux - (bfd_byte *) everdef)) 6925218822Sdim goto error_return_verdef; 6926218822Sdim 692733965Sjdp everdaux = ((Elf_External_Verdaux *) 692833965Sjdp ((bfd_byte *) everdef + iverdef->vd_aux)); 692933965Sjdp iverdaux = iverdef->vd_auxptr; 693033965Sjdp for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++) 693133965Sjdp { 693233965Sjdp _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux); 693333965Sjdp 693433965Sjdp iverdaux->vda_nodename = 693533965Sjdp bfd_elf_string_from_elf_section (abfd, hdr->sh_link, 693633965Sjdp iverdaux->vda_name); 693733965Sjdp if (iverdaux->vda_nodename == NULL) 6938218822Sdim goto error_return_verdef; 693933965Sjdp 694033965Sjdp if (j + 1 < iverdef->vd_cnt) 694133965Sjdp iverdaux->vda_nextptr = iverdaux + 1; 694233965Sjdp else 694333965Sjdp iverdaux->vda_nextptr = NULL; 694433965Sjdp 6945218822Sdim if (iverdaux->vda_next 6946218822Sdim > (size_t) (contents_end_aux - (bfd_byte *) everdaux)) 6947218822Sdim goto error_return_verdef; 6948218822Sdim 694933965Sjdp everdaux = ((Elf_External_Verdaux *) 695033965Sjdp ((bfd_byte *) everdaux + iverdaux->vda_next)); 695133965Sjdp } 695233965Sjdp 6953218822Sdim if (iverdef->vd_cnt) 6954218822Sdim iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename; 695533965Sjdp 6956218822Sdim if ((size_t) (iverdef - iverdefarr) + 1 < maxidx) 695733965Sjdp iverdef->vd_nextdef = iverdef + 1; 695833965Sjdp else 695933965Sjdp iverdef->vd_nextdef = NULL; 696033965Sjdp 696133965Sjdp everdef = ((Elf_External_Verdef *) 696233965Sjdp ((bfd_byte *) everdef + iverdef->vd_next)); 696333965Sjdp } 696433965Sjdp 696533965Sjdp free (contents); 696633965Sjdp contents = NULL; 696733965Sjdp } 6968218822Sdim else if (default_imported_symver) 696933965Sjdp { 6970218822Sdim if (freeidx < 3) 6971218822Sdim freeidx = 3; 6972218822Sdim else 6973218822Sdim freeidx++; 697433965Sjdp 6975218822Sdim elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, freeidx, 6976218822Sdim sizeof (Elf_Internal_Verdef)); 6977218822Sdim if (elf_tdata (abfd)->verdef == NULL) 697833965Sjdp goto error_return; 697933965Sjdp 6980218822Sdim elf_tdata (abfd)->cverdefs = freeidx; 6981218822Sdim } 698233965Sjdp 6983218822Sdim /* Create a default version based on the soname. */ 6984218822Sdim if (default_imported_symver) 6985218822Sdim { 6986218822Sdim Elf_Internal_Verdef *iverdef; 6987218822Sdim Elf_Internal_Verdaux *iverdaux; 698833965Sjdp 6989218822Sdim iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];; 699033965Sjdp 6991218822Sdim iverdef->vd_version = VER_DEF_CURRENT; 6992218822Sdim iverdef->vd_flags = 0; 6993218822Sdim iverdef->vd_ndx = freeidx; 6994218822Sdim iverdef->vd_cnt = 1; 699533965Sjdp 6996218822Sdim iverdef->vd_bfd = abfd; 699733965Sjdp 6998218822Sdim iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd); 6999218822Sdim if (iverdef->vd_nodename == NULL) 7000218822Sdim goto error_return_verdef; 7001218822Sdim iverdef->vd_nextdef = NULL; 7002218822Sdim iverdef->vd_auxptr = bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux)); 7003218822Sdim if (iverdef->vd_auxptr == NULL) 7004218822Sdim goto error_return_verdef; 700533965Sjdp 7006218822Sdim iverdaux = iverdef->vd_auxptr; 7007218822Sdim iverdaux->vda_nodename = iverdef->vd_nodename; 7008218822Sdim iverdaux->vda_nextptr = NULL; 700933965Sjdp } 701033965Sjdp 7011130563Sobrien return TRUE; 701233965Sjdp 701333965Sjdp error_return: 7014130563Sobrien if (contents != NULL) 701533965Sjdp free (contents); 7016130563Sobrien return FALSE; 701733965Sjdp} 701833965Sjdp 701933965Sjdpasymbol * 7020130563Sobrien_bfd_elf_make_empty_symbol (bfd *abfd) 702133965Sjdp{ 702233965Sjdp elf_symbol_type *newsym; 702389860Sobrien bfd_size_type amt = sizeof (elf_symbol_type); 702433965Sjdp 7025130563Sobrien newsym = bfd_zalloc (abfd, amt); 702633965Sjdp if (!newsym) 702733965Sjdp return NULL; 702833965Sjdp else 702933965Sjdp { 703033965Sjdp newsym->symbol.the_bfd = abfd; 703133965Sjdp return &newsym->symbol; 703233965Sjdp } 703333965Sjdp} 703433965Sjdp 703533965Sjdpvoid 7036130563Sobrien_bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, 7037130563Sobrien asymbol *symbol, 7038130563Sobrien symbol_info *ret) 703933965Sjdp{ 704033965Sjdp bfd_symbol_info (symbol, ret); 704133965Sjdp} 704233965Sjdp 704333965Sjdp/* Return whether a symbol name implies a local symbol. Most targets 704433965Sjdp use this function for the is_local_label_name entry point, but some 704533965Sjdp override it. */ 704633965Sjdp 7047130563Sobrienbfd_boolean 7048130563Sobrien_bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, 7049130563Sobrien const char *name) 705033965Sjdp{ 705133965Sjdp /* Normal local symbols start with ``.L''. */ 705233965Sjdp if (name[0] == '.' && name[1] == 'L') 7053130563Sobrien return TRUE; 705433965Sjdp 705533965Sjdp /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate 705633965Sjdp DWARF debugging symbols starting with ``..''. */ 705733965Sjdp if (name[0] == '.' && name[1] == '.') 7058130563Sobrien return TRUE; 705933965Sjdp 706033965Sjdp /* gcc will sometimes generate symbols beginning with ``_.L_'' when 706133965Sjdp emitting DWARF debugging output. I suspect this is actually a 706233965Sjdp small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call 706333965Sjdp ASM_GENERATE_INTERNAL_LABEL, and this causes the leading 706433965Sjdp underscore to be emitted on some ELF targets). For ease of use, 706533965Sjdp we treat such symbols as local. */ 706633965Sjdp if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_') 7067130563Sobrien return TRUE; 706833965Sjdp 7069130563Sobrien return FALSE; 707033965Sjdp} 707133965Sjdp 707233965Sjdpalent * 7073130563Sobrien_bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED, 7074130563Sobrien asymbol *symbol ATTRIBUTE_UNUSED) 707533965Sjdp{ 707633965Sjdp abort (); 707733965Sjdp return NULL; 707833965Sjdp} 707933965Sjdp 7080130563Sobrienbfd_boolean 7081130563Sobrien_bfd_elf_set_arch_mach (bfd *abfd, 7082130563Sobrien enum bfd_architecture arch, 7083130563Sobrien unsigned long machine) 708433965Sjdp{ 708533965Sjdp /* If this isn't the right architecture for this backend, and this 708633965Sjdp isn't the generic backend, fail. */ 708733965Sjdp if (arch != get_elf_backend_data (abfd)->arch 708833965Sjdp && arch != bfd_arch_unknown 708933965Sjdp && get_elf_backend_data (abfd)->arch != bfd_arch_unknown) 7090130563Sobrien return FALSE; 709133965Sjdp 709233965Sjdp return bfd_default_set_arch_mach (abfd, arch, machine); 709333965Sjdp} 709433965Sjdp 709578831Sobrien/* Find the function to a particular section and offset, 709678831Sobrien for error reporting. */ 709733965Sjdp 7098130563Sobrienstatic bfd_boolean 7099130563Sobrienelf_find_function (bfd *abfd ATTRIBUTE_UNUSED, 7100130563Sobrien asection *section, 7101130563Sobrien asymbol **symbols, 7102130563Sobrien bfd_vma offset, 7103130563Sobrien const char **filename_ptr, 7104130563Sobrien const char **functionname_ptr) 710533965Sjdp{ 710633965Sjdp const char *filename; 7107218822Sdim asymbol *func, *file; 710833965Sjdp bfd_vma low_func; 710933965Sjdp asymbol **p; 7110218822Sdim /* ??? Given multiple file symbols, it is impossible to reliably 7111218822Sdim choose the right file name for global symbols. File symbols are 7112218822Sdim local symbols, and thus all file symbols must sort before any 7113218822Sdim global symbols. The ELF spec may be interpreted to say that a 7114218822Sdim file symbol must sort before other local symbols, but currently 7115218822Sdim ld -r doesn't do this. So, for ld -r output, it is possible to 7116218822Sdim make a better choice of file name for local symbols by ignoring 7117218822Sdim file symbols appearing after a given local symbol. */ 7118218822Sdim enum { nothing_seen, symbol_seen, file_after_symbol_seen } state; 711933965Sjdp 712033965Sjdp filename = NULL; 712133965Sjdp func = NULL; 7122218822Sdim file = NULL; 712333965Sjdp low_func = 0; 7124218822Sdim state = nothing_seen; 712533965Sjdp 712633965Sjdp for (p = symbols; *p != NULL; p++) 712733965Sjdp { 712833965Sjdp elf_symbol_type *q; 712933965Sjdp 713033965Sjdp q = (elf_symbol_type *) *p; 713133965Sjdp 713233965Sjdp switch (ELF_ST_TYPE (q->internal_elf_sym.st_info)) 713333965Sjdp { 713433965Sjdp default: 713533965Sjdp break; 713633965Sjdp case STT_FILE: 7137218822Sdim file = &q->symbol; 7138218822Sdim if (state == symbol_seen) 7139218822Sdim state = file_after_symbol_seen; 7140218822Sdim continue; 714160508Sobrien case STT_NOTYPE: 714233965Sjdp case STT_FUNC: 7143218822Sdim if (bfd_get_section (&q->symbol) == section 714433965Sjdp && q->symbol.value >= low_func 714533965Sjdp && q->symbol.value <= offset) 714633965Sjdp { 714733965Sjdp func = (asymbol *) q; 714833965Sjdp low_func = q->symbol.value; 7149218822Sdim filename = NULL; 7150218822Sdim if (file != NULL 7151218822Sdim && (ELF_ST_BIND (q->internal_elf_sym.st_info) == STB_LOCAL 7152218822Sdim || state != file_after_symbol_seen)) 7153218822Sdim filename = bfd_asymbol_name (file); 715433965Sjdp } 715533965Sjdp break; 715633965Sjdp } 7157218822Sdim if (state == nothing_seen) 7158218822Sdim state = symbol_seen; 715933965Sjdp } 716033965Sjdp 716133965Sjdp if (func == NULL) 7162130563Sobrien return FALSE; 716333965Sjdp 716478831Sobrien if (filename_ptr) 716578831Sobrien *filename_ptr = filename; 716678831Sobrien if (functionname_ptr) 716778831Sobrien *functionname_ptr = bfd_asymbol_name (func); 716878831Sobrien 7169130563Sobrien return TRUE; 717078831Sobrien} 717178831Sobrien 717278831Sobrien/* Find the nearest line to a particular section and offset, 717378831Sobrien for error reporting. */ 717478831Sobrien 7175130563Sobrienbfd_boolean 7176130563Sobrien_bfd_elf_find_nearest_line (bfd *abfd, 7177130563Sobrien asection *section, 7178130563Sobrien asymbol **symbols, 7179130563Sobrien bfd_vma offset, 7180130563Sobrien const char **filename_ptr, 7181130563Sobrien const char **functionname_ptr, 7182130563Sobrien unsigned int *line_ptr) 718378831Sobrien{ 7184130563Sobrien bfd_boolean found; 718578831Sobrien 718678831Sobrien if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, 718778831Sobrien filename_ptr, functionname_ptr, 718878831Sobrien line_ptr)) 718978831Sobrien { 719078831Sobrien if (!*functionname_ptr) 719178831Sobrien elf_find_function (abfd, section, symbols, offset, 719278831Sobrien *filename_ptr ? NULL : filename_ptr, 719378831Sobrien functionname_ptr); 719478831Sobrien 7195130563Sobrien return TRUE; 719678831Sobrien } 719778831Sobrien 719878831Sobrien if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, 719978831Sobrien filename_ptr, functionname_ptr, 720078831Sobrien line_ptr, 0, 720178831Sobrien &elf_tdata (abfd)->dwarf2_find_line_info)) 720278831Sobrien { 720378831Sobrien if (!*functionname_ptr) 720478831Sobrien elf_find_function (abfd, section, symbols, offset, 720578831Sobrien *filename_ptr ? NULL : filename_ptr, 720678831Sobrien functionname_ptr); 720778831Sobrien 7208130563Sobrien return TRUE; 720978831Sobrien } 721078831Sobrien 721178831Sobrien if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, 721278831Sobrien &found, filename_ptr, 721378831Sobrien functionname_ptr, line_ptr, 721478831Sobrien &elf_tdata (abfd)->line_info)) 7215130563Sobrien return FALSE; 7216104838Sobrien if (found && (*functionname_ptr || *line_ptr)) 7217130563Sobrien return TRUE; 721878831Sobrien 721978831Sobrien if (symbols == NULL) 7220130563Sobrien return FALSE; 722178831Sobrien 722278831Sobrien if (! elf_find_function (abfd, section, symbols, offset, 722378831Sobrien filename_ptr, functionname_ptr)) 7224130563Sobrien return FALSE; 722578831Sobrien 722633965Sjdp *line_ptr = 0; 7227130563Sobrien return TRUE; 722833965Sjdp} 722933965Sjdp 7230218822Sdim/* Find the line for a symbol. */ 7231218822Sdim 7232218822Sdimbfd_boolean 7233218822Sdim_bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol, 7234218822Sdim const char **filename_ptr, unsigned int *line_ptr) 7235218822Sdim{ 7236218822Sdim return _bfd_dwarf2_find_line (abfd, symbols, symbol, 7237218822Sdim filename_ptr, line_ptr, 0, 7238218822Sdim &elf_tdata (abfd)->dwarf2_find_line_info); 7239218822Sdim} 7240218822Sdim 7241218822Sdim/* After a call to bfd_find_nearest_line, successive calls to 7242218822Sdim bfd_find_inliner_info can be used to get source information about 7243218822Sdim each level of function inlining that terminated at the address 7244218822Sdim passed to bfd_find_nearest_line. Currently this is only supported 7245218822Sdim for DWARF2 with appropriate DWARF3 extensions. */ 7246218822Sdim 7247218822Sdimbfd_boolean 7248218822Sdim_bfd_elf_find_inliner_info (bfd *abfd, 7249218822Sdim const char **filename_ptr, 7250218822Sdim const char **functionname_ptr, 7251218822Sdim unsigned int *line_ptr) 7252218822Sdim{ 7253218822Sdim bfd_boolean found; 7254218822Sdim found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr, 7255218822Sdim functionname_ptr, line_ptr, 7256218822Sdim & elf_tdata (abfd)->dwarf2_find_line_info); 7257218822Sdim return found; 7258218822Sdim} 7259218822Sdim 726033965Sjdpint 7261218822Sdim_bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info) 726233965Sjdp{ 7263218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 7264218822Sdim int ret = bed->s->sizeof_ehdr; 726533965Sjdp 7266218822Sdim if (!info->relocatable) 7267218822Sdim { 7268218822Sdim bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size; 7269218822Sdim 7270218822Sdim if (phdr_size == (bfd_size_type) -1) 7271218822Sdim { 7272218822Sdim struct elf_segment_map *m; 7273218822Sdim 7274218822Sdim phdr_size = 0; 7275218822Sdim for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) 7276218822Sdim phdr_size += bed->s->sizeof_phdr; 7277218822Sdim 7278218822Sdim if (phdr_size == 0) 7279218822Sdim phdr_size = get_program_header_size (abfd, info); 7280218822Sdim } 7281218822Sdim 7282218822Sdim elf_tdata (abfd)->program_header_size = phdr_size; 7283218822Sdim ret += phdr_size; 7284218822Sdim } 7285218822Sdim 728633965Sjdp return ret; 728733965Sjdp} 728833965Sjdp 7289130563Sobrienbfd_boolean 7290130563Sobrien_bfd_elf_set_section_contents (bfd *abfd, 7291130563Sobrien sec_ptr section, 7292130563Sobrien const void *location, 7293130563Sobrien file_ptr offset, 7294130563Sobrien bfd_size_type count) 729533965Sjdp{ 729633965Sjdp Elf_Internal_Shdr *hdr; 729789860Sobrien bfd_signed_vma pos; 729833965Sjdp 729933965Sjdp if (! abfd->output_has_begun 7300130563Sobrien && ! _bfd_elf_compute_section_file_positions (abfd, NULL)) 7301130563Sobrien return FALSE; 730233965Sjdp 730333965Sjdp hdr = &elf_section_data (section)->this_hdr; 730489860Sobrien pos = hdr->sh_offset + offset; 730589860Sobrien if (bfd_seek (abfd, pos, SEEK_SET) != 0 730689860Sobrien || bfd_bwrite (location, count, abfd) != count) 7307130563Sobrien return FALSE; 730833965Sjdp 7309130563Sobrien return TRUE; 731033965Sjdp} 731133965Sjdp 731233965Sjdpvoid 7313130563Sobrien_bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, 7314130563Sobrien arelent *cache_ptr ATTRIBUTE_UNUSED, 7315130563Sobrien Elf_Internal_Rela *dst ATTRIBUTE_UNUSED) 731633965Sjdp{ 731733965Sjdp abort (); 731833965Sjdp} 731933965Sjdp 732033965Sjdp/* Try to convert a non-ELF reloc into an ELF one. */ 732133965Sjdp 7322130563Sobrienbfd_boolean 7323130563Sobrien_bfd_elf_validate_reloc (bfd *abfd, arelent *areloc) 732433965Sjdp{ 732577301Sobrien /* Check whether we really have an ELF howto. */ 732633965Sjdp 732760508Sobrien if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec) 732833965Sjdp { 732933965Sjdp bfd_reloc_code_real_type code; 733033965Sjdp reloc_howto_type *howto; 733160508Sobrien 733233965Sjdp /* Alien reloc: Try to determine its type to replace it with an 733377301Sobrien equivalent ELF reloc. */ 733433965Sjdp 733533965Sjdp if (areloc->howto->pc_relative) 733633965Sjdp { 733733965Sjdp switch (areloc->howto->bitsize) 733833965Sjdp { 733933965Sjdp case 8: 734060508Sobrien code = BFD_RELOC_8_PCREL; 734133965Sjdp break; 734233965Sjdp case 12: 734360508Sobrien code = BFD_RELOC_12_PCREL; 734433965Sjdp break; 734533965Sjdp case 16: 734660508Sobrien code = BFD_RELOC_16_PCREL; 734733965Sjdp break; 734833965Sjdp case 24: 734960508Sobrien code = BFD_RELOC_24_PCREL; 735033965Sjdp break; 735133965Sjdp case 32: 735260508Sobrien code = BFD_RELOC_32_PCREL; 735333965Sjdp break; 735433965Sjdp case 64: 735560508Sobrien code = BFD_RELOC_64_PCREL; 735633965Sjdp break; 735733965Sjdp default: 735833965Sjdp goto fail; 735933965Sjdp } 736033965Sjdp 736133965Sjdp howto = bfd_reloc_type_lookup (abfd, code); 736233965Sjdp 736333965Sjdp if (areloc->howto->pcrel_offset != howto->pcrel_offset) 736433965Sjdp { 736533965Sjdp if (howto->pcrel_offset) 736633965Sjdp areloc->addend += areloc->address; 736733965Sjdp else 736833965Sjdp areloc->addend -= areloc->address; /* addend is unsigned!! */ 736933965Sjdp } 737033965Sjdp } 737133965Sjdp else 737233965Sjdp { 737333965Sjdp switch (areloc->howto->bitsize) 737433965Sjdp { 737533965Sjdp case 8: 737660508Sobrien code = BFD_RELOC_8; 737733965Sjdp break; 737833965Sjdp case 14: 737960508Sobrien code = BFD_RELOC_14; 738033965Sjdp break; 738133965Sjdp case 16: 738260508Sobrien code = BFD_RELOC_16; 738333965Sjdp break; 738433965Sjdp case 26: 738560508Sobrien code = BFD_RELOC_26; 738633965Sjdp break; 738733965Sjdp case 32: 738860508Sobrien code = BFD_RELOC_32; 738933965Sjdp break; 739033965Sjdp case 64: 739160508Sobrien code = BFD_RELOC_64; 739233965Sjdp break; 739333965Sjdp default: 739433965Sjdp goto fail; 739533965Sjdp } 739633965Sjdp 739733965Sjdp howto = bfd_reloc_type_lookup (abfd, code); 739833965Sjdp } 739933965Sjdp 740033965Sjdp if (howto) 740133965Sjdp areloc->howto = howto; 740233965Sjdp else 740333965Sjdp goto fail; 740433965Sjdp } 740533965Sjdp 7406130563Sobrien return TRUE; 740733965Sjdp 740833965Sjdp fail: 740933965Sjdp (*_bfd_error_handler) 7410218822Sdim (_("%B: unsupported relocation type %s"), 7411218822Sdim abfd, areloc->howto->name); 741233965Sjdp bfd_set_error (bfd_error_bad_value); 7413130563Sobrien return FALSE; 741433965Sjdp} 741538891Sjdp 7416130563Sobrienbfd_boolean 7417130563Sobrien_bfd_elf_close_and_cleanup (bfd *abfd) 741838891Sjdp{ 741938891Sjdp if (bfd_get_format (abfd) == bfd_object) 742038891Sjdp { 7421218822Sdim if (elf_tdata (abfd) != NULL && elf_shstrtab (abfd) != NULL) 742289860Sobrien _bfd_elf_strtab_free (elf_shstrtab (abfd)); 7423218822Sdim _bfd_dwarf2_cleanup_debug_info (abfd); 742438891Sjdp } 742538891Sjdp 742638891Sjdp return _bfd_generic_close_and_cleanup (abfd); 742738891Sjdp} 742860508Sobrien 742960508Sobrien/* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY 743060508Sobrien in the relocation's offset. Thus we cannot allow any sort of sanity 743160508Sobrien range-checking to interfere. There is nothing else to do in processing 743260508Sobrien this reloc. */ 743360508Sobrien 743460508Sobrienbfd_reloc_status_type 7435130563Sobrien_bfd_elf_rel_vtable_reloc_fn 7436130563Sobrien (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED, 7437130563Sobrien struct bfd_symbol *symbol ATTRIBUTE_UNUSED, 7438130563Sobrien void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED, 7439130563Sobrien bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED) 744060508Sobrien{ 744160508Sobrien return bfd_reloc_ok; 744260508Sobrien} 744360508Sobrien 744460508Sobrien/* Elf core file support. Much of this only works on native 744560508Sobrien toolchains, since we rely on knowing the 744660508Sobrien machine-dependent procfs structure in order to pick 744777301Sobrien out details about the corefile. */ 744860508Sobrien 744960508Sobrien#ifdef HAVE_SYS_PROCFS_H 745060508Sobrien# include <sys/procfs.h> 7451215679Sattilio 7452215679Sattilio/* Define HAVE_THRMISC_T for consistency with other similar GNU-type stubs. */ 7453215679Sattilio#undef HAVE_THRMISC_T 7454215679Sattilio#if defined (THRMISC_VERSION) 7455215679Sattilio#define HAVE_THRMISC_T 1 745660508Sobrien#endif 7457215679Sattilio#endif 745860508Sobrien 745977301Sobrien/* FIXME: this is kinda wrong, but it's what gdb wants. */ 746060508Sobrien 746160508Sobrienstatic int 7462130563Sobrienelfcore_make_pid (bfd *abfd) 746360508Sobrien{ 746460508Sobrien return ((elf_tdata (abfd)->core_lwpid << 16) 746560508Sobrien + (elf_tdata (abfd)->core_pid)); 746660508Sobrien} 746760508Sobrien 746860508Sobrien/* If there isn't a section called NAME, make one, using 746960508Sobrien data from SECT. Note, this function will generate a 747060508Sobrien reference to NAME, so you shouldn't deallocate or 747177301Sobrien overwrite it. */ 747260508Sobrien 7473130563Sobrienstatic bfd_boolean 7474130563Sobrienelfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect) 747560508Sobrien{ 747677301Sobrien asection *sect2; 747760508Sobrien 747860508Sobrien if (bfd_get_section_by_name (abfd, name) != NULL) 7479130563Sobrien return TRUE; 748060508Sobrien 7481218822Sdim sect2 = bfd_make_section_with_flags (abfd, name, sect->flags); 748260508Sobrien if (sect2 == NULL) 7483130563Sobrien return FALSE; 748460508Sobrien 7485218822Sdim sect2->size = sect->size; 748660508Sobrien sect2->filepos = sect->filepos; 748760508Sobrien sect2->alignment_power = sect->alignment_power; 7488130563Sobrien return TRUE; 748960508Sobrien} 749060508Sobrien 749189860Sobrien/* Create a pseudosection containing SIZE bytes at FILEPOS. This 749289860Sobrien actually creates up to two pseudosections: 749389860Sobrien - For the single-threaded case, a section named NAME, unless 749489860Sobrien such a section already exists. 749589860Sobrien - For the multi-threaded case, a section named "NAME/PID", where 749689860Sobrien PID is elfcore_make_pid (abfd). 749789860Sobrien Both pseudosections have identical contents. */ 7498130563Sobrienbfd_boolean 7499130563Sobrien_bfd_elfcore_make_pseudosection (bfd *abfd, 7500130563Sobrien char *name, 7501130563Sobrien size_t size, 7502130563Sobrien ufile_ptr filepos) 750389860Sobrien{ 750489860Sobrien char buf[100]; 750589860Sobrien char *threaded_name; 7506104838Sobrien size_t len; 750789860Sobrien asection *sect; 750889860Sobrien 750989860Sobrien /* Build the section name. */ 751089860Sobrien 751189860Sobrien sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd)); 7512104838Sobrien len = strlen (buf) + 1; 7513130563Sobrien threaded_name = bfd_alloc (abfd, len); 751489860Sobrien if (threaded_name == NULL) 7515130563Sobrien return FALSE; 7516104838Sobrien memcpy (threaded_name, buf, len); 751789860Sobrien 7518218822Sdim sect = bfd_make_section_anyway_with_flags (abfd, threaded_name, 7519218822Sdim SEC_HAS_CONTENTS); 752089860Sobrien if (sect == NULL) 7521130563Sobrien return FALSE; 7522218822Sdim sect->size = size; 752389860Sobrien sect->filepos = filepos; 752489860Sobrien sect->alignment_power = 2; 752589860Sobrien 752689860Sobrien return elfcore_maybe_make_sect (abfd, name, sect); 752789860Sobrien} 752889860Sobrien 752960508Sobrien/* prstatus_t exists on: 753077301Sobrien solaris 2.5+ 753160508Sobrien linux 2.[01] + glibc 753260508Sobrien unixware 4.2 753360508Sobrien*/ 753460508Sobrien 753560508Sobrien#if defined (HAVE_PRSTATUS_T) 753689860Sobrien 7537130563Sobrienstatic bfd_boolean 7538130563Sobrienelfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) 753960508Sobrien{ 7540218822Sdim size_t size; 754177301Sobrien int offset; 754260508Sobrien 754377301Sobrien if (note->descsz == sizeof (prstatus_t)) 754477301Sobrien { 754577301Sobrien prstatus_t prstat; 754660508Sobrien 7547218822Sdim size = sizeof (prstat.pr_reg); 754877301Sobrien offset = offsetof (prstatus_t, pr_reg); 754977301Sobrien memcpy (&prstat, note->descdata, sizeof (prstat)); 755060508Sobrien 755189860Sobrien /* Do not overwrite the core signal if it 755289860Sobrien has already been set by another thread. */ 755389860Sobrien if (elf_tdata (abfd)->core_signal == 0) 755489860Sobrien elf_tdata (abfd)->core_signal = prstat.pr_cursig; 755577301Sobrien elf_tdata (abfd)->core_pid = prstat.pr_pid; 755660508Sobrien 755777301Sobrien /* pr_who exists on: 755877301Sobrien solaris 2.5+ 755977301Sobrien unixware 4.2 756077301Sobrien pr_who doesn't exist on: 756177301Sobrien linux 2.[01] 756277301Sobrien */ 756360508Sobrien#if defined (HAVE_PRSTATUS_T_PR_WHO) 756477301Sobrien elf_tdata (abfd)->core_lwpid = prstat.pr_who; 756560508Sobrien#endif 756677301Sobrien } 756777301Sobrien#if defined (HAVE_PRSTATUS32_T) 756877301Sobrien else if (note->descsz == sizeof (prstatus32_t)) 756977301Sobrien { 757077301Sobrien /* 64-bit host, 32-bit corefile */ 757177301Sobrien prstatus32_t prstat; 757260508Sobrien 7573218822Sdim size = sizeof (prstat.pr_reg); 757477301Sobrien offset = offsetof (prstatus32_t, pr_reg); 757577301Sobrien memcpy (&prstat, note->descdata, sizeof (prstat)); 757660508Sobrien 757789860Sobrien /* Do not overwrite the core signal if it 757889860Sobrien has already been set by another thread. */ 757989860Sobrien if (elf_tdata (abfd)->core_signal == 0) 758089860Sobrien elf_tdata (abfd)->core_signal = prstat.pr_cursig; 758177301Sobrien elf_tdata (abfd)->core_pid = prstat.pr_pid; 758277301Sobrien 758377301Sobrien /* pr_who exists on: 758477301Sobrien solaris 2.5+ 758577301Sobrien unixware 4.2 758677301Sobrien pr_who doesn't exist on: 758777301Sobrien linux 2.[01] 758877301Sobrien */ 758977301Sobrien#if defined (HAVE_PRSTATUS32_T_PR_WHO) 759077301Sobrien elf_tdata (abfd)->core_lwpid = prstat.pr_who; 759177301Sobrien#endif 759277301Sobrien } 759377301Sobrien#endif /* HAVE_PRSTATUS32_T */ 759477301Sobrien else 759577301Sobrien { 759677301Sobrien /* Fail - we don't know how to handle any other 759777301Sobrien note size (ie. data object type). */ 7598130563Sobrien return TRUE; 759977301Sobrien } 760077301Sobrien 760189860Sobrien /* Make a ".reg/999" section and a ".reg" section. */ 760289860Sobrien return _bfd_elfcore_make_pseudosection (abfd, ".reg", 7603218822Sdim size, note->descpos + offset); 760460508Sobrien} 760560508Sobrien#endif /* defined (HAVE_PRSTATUS_T) */ 760660508Sobrien 760789860Sobrien/* Create a pseudosection containing the exact contents of NOTE. */ 7608130563Sobrienstatic bfd_boolean 7609130563Sobrienelfcore_make_note_pseudosection (bfd *abfd, 7610130563Sobrien char *name, 7611130563Sobrien Elf_Internal_Note *note) 761260508Sobrien{ 761389860Sobrien return _bfd_elfcore_make_pseudosection (abfd, name, 761489860Sobrien note->descsz, note->descpos); 761560508Sobrien} 761660508Sobrien 761760508Sobrien/* There isn't a consistent prfpregset_t across platforms, 761860508Sobrien but it doesn't matter, because we don't have to pick this 761977301Sobrien data structure apart. */ 762077301Sobrien 7621130563Sobrienstatic bfd_boolean 7622130563Sobrienelfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note) 762360508Sobrien{ 762460508Sobrien return elfcore_make_note_pseudosection (abfd, ".reg2", note); 762560508Sobrien} 762660508Sobrien 762760508Sobrien/* Linux dumps the Intel SSE regs in a note named "LINUX" with a note 762860508Sobrien type of 5 (NT_PRXFPREG). Just include the whole note's contents 762960508Sobrien literally. */ 763077301Sobrien 7631130563Sobrienstatic bfd_boolean 7632130563Sobrienelfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note) 763360508Sobrien{ 763460508Sobrien return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note); 763560508Sobrien} 763660508Sobrien 7637215679Sattilio#if defined (HAVE_THRMISC_T) 7638215679Sattilio 7639215679Sattiliostatic bfd_boolean 7640215679Sattilioelfcore_grok_thrmisc (bfd *abfd, Elf_Internal_Note *note) 7641215679Sattilio{ 7642215679Sattilio return elfcore_make_note_pseudosection (abfd, ".tname", note); 7643215679Sattilio} 7644215679Sattilio 7645215679Sattilio#endif /* defined (HAVE_THRMISC_T) */ 7646215679Sattilio 764760508Sobrien#if defined (HAVE_PRPSINFO_T) 764877301Sobrientypedef prpsinfo_t elfcore_psinfo_t; 764977301Sobrien#if defined (HAVE_PRPSINFO32_T) /* Sparc64 cross Sparc32 */ 765077301Sobrientypedef prpsinfo32_t elfcore_psinfo32_t; 765160508Sobrien#endif 765277301Sobrien#endif 765360508Sobrien 765460508Sobrien#if defined (HAVE_PSINFO_T) 765577301Sobrientypedef psinfo_t elfcore_psinfo_t; 765677301Sobrien#if defined (HAVE_PSINFO32_T) /* Sparc64 cross Sparc32 */ 765777301Sobrientypedef psinfo32_t elfcore_psinfo32_t; 765860508Sobrien#endif 765977301Sobrien#endif 766060508Sobrien 766160508Sobrien/* return a malloc'ed copy of a string at START which is at 766260508Sobrien most MAX bytes long, possibly without a terminating '\0'. 766377301Sobrien the copy will always have a terminating '\0'. */ 766460508Sobrien 766589860Sobrienchar * 7666130563Sobrien_bfd_elfcore_strndup (bfd *abfd, char *start, size_t max) 766760508Sobrien{ 766889860Sobrien char *dups; 766977301Sobrien char *end = memchr (start, '\0', max); 767089860Sobrien size_t len; 767160508Sobrien 767260508Sobrien if (end == NULL) 767360508Sobrien len = max; 767460508Sobrien else 767560508Sobrien len = end - start; 767660508Sobrien 7677130563Sobrien dups = bfd_alloc (abfd, len + 1); 767889860Sobrien if (dups == NULL) 767960508Sobrien return NULL; 768060508Sobrien 768189860Sobrien memcpy (dups, start, len); 768289860Sobrien dups[len] = '\0'; 768360508Sobrien 768489860Sobrien return dups; 768560508Sobrien} 768660508Sobrien 768789860Sobrien#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) 7688130563Sobrienstatic bfd_boolean 7689130563Sobrienelfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 769060508Sobrien{ 769177301Sobrien if (note->descsz == sizeof (elfcore_psinfo_t)) 769277301Sobrien { 769377301Sobrien elfcore_psinfo_t psinfo; 769460508Sobrien 769577301Sobrien memcpy (&psinfo, note->descdata, sizeof (psinfo)); 769660508Sobrien 769777301Sobrien elf_tdata (abfd)->core_program 769889860Sobrien = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, 769989860Sobrien sizeof (psinfo.pr_fname)); 770060508Sobrien 770177301Sobrien elf_tdata (abfd)->core_command 770289860Sobrien = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, 770389860Sobrien sizeof (psinfo.pr_psargs)); 770477301Sobrien } 770577301Sobrien#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T) 770677301Sobrien else if (note->descsz == sizeof (elfcore_psinfo32_t)) 770777301Sobrien { 770877301Sobrien /* 64-bit host, 32-bit corefile */ 770977301Sobrien elfcore_psinfo32_t psinfo; 771060508Sobrien 771177301Sobrien memcpy (&psinfo, note->descdata, sizeof (psinfo)); 771260508Sobrien 771377301Sobrien elf_tdata (abfd)->core_program 771489860Sobrien = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, 771589860Sobrien sizeof (psinfo.pr_fname)); 771677301Sobrien 771777301Sobrien elf_tdata (abfd)->core_command 771889860Sobrien = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, 771989860Sobrien sizeof (psinfo.pr_psargs)); 772077301Sobrien } 772177301Sobrien#endif 772277301Sobrien 772377301Sobrien else 772477301Sobrien { 772577301Sobrien /* Fail - we don't know how to handle any other 772677301Sobrien note size (ie. data object type). */ 7727130563Sobrien return TRUE; 772877301Sobrien } 772977301Sobrien 773060508Sobrien /* Note that for some reason, a spurious space is tacked 773160508Sobrien onto the end of the args in some (at least one anyway) 773277301Sobrien implementations, so strip it off if it exists. */ 773360508Sobrien 773460508Sobrien { 773577301Sobrien char *command = elf_tdata (abfd)->core_command; 773660508Sobrien int n = strlen (command); 773760508Sobrien 773860508Sobrien if (0 < n && command[n - 1] == ' ') 773960508Sobrien command[n - 1] = '\0'; 774060508Sobrien } 774160508Sobrien 7742130563Sobrien return TRUE; 774360508Sobrien} 774460508Sobrien#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */ 774560508Sobrien 774660508Sobrien#if defined (HAVE_PSTATUS_T) 7747130563Sobrienstatic bfd_boolean 7748130563Sobrienelfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note) 774960508Sobrien{ 775077301Sobrien if (note->descsz == sizeof (pstatus_t) 775177301Sobrien#if defined (HAVE_PXSTATUS_T) 775277301Sobrien || note->descsz == sizeof (pxstatus_t) 775377301Sobrien#endif 775477301Sobrien ) 775577301Sobrien { 775677301Sobrien pstatus_t pstat; 775760508Sobrien 775877301Sobrien memcpy (&pstat, note->descdata, sizeof (pstat)); 775960508Sobrien 776077301Sobrien elf_tdata (abfd)->core_pid = pstat.pr_pid; 776177301Sobrien } 776277301Sobrien#if defined (HAVE_PSTATUS32_T) 776377301Sobrien else if (note->descsz == sizeof (pstatus32_t)) 776477301Sobrien { 776577301Sobrien /* 64-bit host, 32-bit corefile */ 776677301Sobrien pstatus32_t pstat; 776760508Sobrien 776877301Sobrien memcpy (&pstat, note->descdata, sizeof (pstat)); 776960508Sobrien 777077301Sobrien elf_tdata (abfd)->core_pid = pstat.pr_pid; 777177301Sobrien } 777277301Sobrien#endif 777360508Sobrien /* Could grab some more details from the "representative" 777460508Sobrien lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an 777577301Sobrien NT_LWPSTATUS note, presumably. */ 777660508Sobrien 7777130563Sobrien return TRUE; 777860508Sobrien} 777960508Sobrien#endif /* defined (HAVE_PSTATUS_T) */ 778060508Sobrien 778160508Sobrien#if defined (HAVE_LWPSTATUS_T) 7782130563Sobrienstatic bfd_boolean 7783130563Sobrienelfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note) 778460508Sobrien{ 778560508Sobrien lwpstatus_t lwpstat; 778660508Sobrien char buf[100]; 778777301Sobrien char *name; 7788104838Sobrien size_t len; 778977301Sobrien asection *sect; 779060508Sobrien 779177301Sobrien if (note->descsz != sizeof (lwpstat) 779277301Sobrien#if defined (HAVE_LWPXSTATUS_T) 779377301Sobrien && note->descsz != sizeof (lwpxstatus_t) 779477301Sobrien#endif 779577301Sobrien ) 7796130563Sobrien return TRUE; 779760508Sobrien 779860508Sobrien memcpy (&lwpstat, note->descdata, sizeof (lwpstat)); 779960508Sobrien 780060508Sobrien elf_tdata (abfd)->core_lwpid = lwpstat.pr_lwpid; 780160508Sobrien elf_tdata (abfd)->core_signal = lwpstat.pr_cursig; 780260508Sobrien 780377301Sobrien /* Make a ".reg/999" section. */ 780460508Sobrien 780560508Sobrien sprintf (buf, ".reg/%d", elfcore_make_pid (abfd)); 7806104838Sobrien len = strlen (buf) + 1; 7807130563Sobrien name = bfd_alloc (abfd, len); 780860508Sobrien if (name == NULL) 7809130563Sobrien return FALSE; 7810104838Sobrien memcpy (name, buf, len); 781160508Sobrien 7812218822Sdim sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); 781360508Sobrien if (sect == NULL) 7814130563Sobrien return FALSE; 781560508Sobrien 781660508Sobrien#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT) 7817218822Sdim sect->size = sizeof (lwpstat.pr_context.uc_mcontext.gregs); 781860508Sobrien sect->filepos = note->descpos 781960508Sobrien + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs); 782060508Sobrien#endif 782160508Sobrien 782260508Sobrien#if defined (HAVE_LWPSTATUS_T_PR_REG) 7823218822Sdim sect->size = sizeof (lwpstat.pr_reg); 782460508Sobrien sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg); 782560508Sobrien#endif 782660508Sobrien 782760508Sobrien sect->alignment_power = 2; 782860508Sobrien 782960508Sobrien if (!elfcore_maybe_make_sect (abfd, ".reg", sect)) 7830130563Sobrien return FALSE; 783160508Sobrien 783260508Sobrien /* Make a ".reg2/999" section */ 783360508Sobrien 783460508Sobrien sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd)); 7835104838Sobrien len = strlen (buf) + 1; 7836130563Sobrien name = bfd_alloc (abfd, len); 783760508Sobrien if (name == NULL) 7838130563Sobrien return FALSE; 7839104838Sobrien memcpy (name, buf, len); 784060508Sobrien 7841218822Sdim sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); 784260508Sobrien if (sect == NULL) 7843130563Sobrien return FALSE; 784460508Sobrien 784560508Sobrien#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT) 7846218822Sdim sect->size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs); 784760508Sobrien sect->filepos = note->descpos 784860508Sobrien + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs); 784960508Sobrien#endif 785060508Sobrien 785160508Sobrien#if defined (HAVE_LWPSTATUS_T_PR_FPREG) 7852218822Sdim sect->size = sizeof (lwpstat.pr_fpreg); 785360508Sobrien sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg); 785460508Sobrien#endif 785560508Sobrien 785660508Sobrien sect->alignment_power = 2; 785760508Sobrien 785889860Sobrien return elfcore_maybe_make_sect (abfd, ".reg2", sect); 785960508Sobrien} 786060508Sobrien#endif /* defined (HAVE_LWPSTATUS_T) */ 786160508Sobrien 786260508Sobrien#if defined (HAVE_WIN32_PSTATUS_T) 7863130563Sobrienstatic bfd_boolean 7864130563Sobrienelfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note) 786560508Sobrien{ 786660508Sobrien char buf[30]; 786777301Sobrien char *name; 7868104838Sobrien size_t len; 786977301Sobrien asection *sect; 787060508Sobrien win32_pstatus_t pstatus; 787160508Sobrien 787260508Sobrien if (note->descsz < sizeof (pstatus)) 7873130563Sobrien return TRUE; 787460508Sobrien 787589860Sobrien memcpy (&pstatus, note->descdata, sizeof (pstatus)); 787677301Sobrien 787777301Sobrien switch (pstatus.data_type) 787860508Sobrien { 787960508Sobrien case NOTE_INFO_PROCESS: 788060508Sobrien /* FIXME: need to add ->core_command. */ 788160508Sobrien elf_tdata (abfd)->core_signal = pstatus.data.process_info.signal; 788260508Sobrien elf_tdata (abfd)->core_pid = pstatus.data.process_info.pid; 788377301Sobrien break; 788460508Sobrien 788560508Sobrien case NOTE_INFO_THREAD: 788660508Sobrien /* Make a ".reg/999" section. */ 7887218822Sdim sprintf (buf, ".reg/%ld", (long) pstatus.data.thread_info.tid); 788877301Sobrien 7889104838Sobrien len = strlen (buf) + 1; 7890130563Sobrien name = bfd_alloc (abfd, len); 789160508Sobrien if (name == NULL) 7892130563Sobrien return FALSE; 789377301Sobrien 7894104838Sobrien memcpy (name, buf, len); 789560508Sobrien 7896218822Sdim sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); 789760508Sobrien if (sect == NULL) 7898130563Sobrien return FALSE; 789977301Sobrien 7900218822Sdim sect->size = sizeof (pstatus.data.thread_info.thread_context); 790189860Sobrien sect->filepos = (note->descpos 790289860Sobrien + offsetof (struct win32_pstatus, 790389860Sobrien data.thread_info.thread_context)); 790460508Sobrien sect->alignment_power = 2; 790560508Sobrien 790660508Sobrien if (pstatus.data.thread_info.is_active_thread) 790760508Sobrien if (! elfcore_maybe_make_sect (abfd, ".reg", sect)) 7908130563Sobrien return FALSE; 790960508Sobrien break; 791060508Sobrien 791160508Sobrien case NOTE_INFO_MODULE: 791260508Sobrien /* Make a ".module/xxxxxxxx" section. */ 7913218822Sdim sprintf (buf, ".module/%08lx", 7914218822Sdim (long) pstatus.data.module_info.base_address); 791577301Sobrien 7916104838Sobrien len = strlen (buf) + 1; 7917130563Sobrien name = bfd_alloc (abfd, len); 791860508Sobrien if (name == NULL) 7919130563Sobrien return FALSE; 792077301Sobrien 7921104838Sobrien memcpy (name, buf, len); 792260508Sobrien 7923218822Sdim sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); 792477301Sobrien 792560508Sobrien if (sect == NULL) 7926130563Sobrien return FALSE; 792777301Sobrien 7928218822Sdim sect->size = note->descsz; 792960508Sobrien sect->filepos = note->descpos; 793060508Sobrien sect->alignment_power = 2; 793160508Sobrien break; 793260508Sobrien 793360508Sobrien default: 7934130563Sobrien return TRUE; 793560508Sobrien } 793660508Sobrien 7937130563Sobrien return TRUE; 793860508Sobrien} 793960508Sobrien#endif /* HAVE_WIN32_PSTATUS_T */ 794060508Sobrien 7941130563Sobrienstatic bfd_boolean 7942130563Sobrienelfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) 794360508Sobrien{ 7944130563Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 794589860Sobrien 794660508Sobrien switch (note->type) 794760508Sobrien { 794860508Sobrien default: 7949130563Sobrien return TRUE; 795060508Sobrien 795189860Sobrien case NT_PRSTATUS: 795289860Sobrien if (bed->elf_backend_grok_prstatus) 795389860Sobrien if ((*bed->elf_backend_grok_prstatus) (abfd, note)) 7954130563Sobrien return TRUE; 795560508Sobrien#if defined (HAVE_PRSTATUS_T) 795660508Sobrien return elfcore_grok_prstatus (abfd, note); 795789860Sobrien#else 7958130563Sobrien return TRUE; 795960508Sobrien#endif 796060508Sobrien 796160508Sobrien#if defined (HAVE_PSTATUS_T) 796260508Sobrien case NT_PSTATUS: 796360508Sobrien return elfcore_grok_pstatus (abfd, note); 796460508Sobrien#endif 796560508Sobrien 796660508Sobrien#if defined (HAVE_LWPSTATUS_T) 796760508Sobrien case NT_LWPSTATUS: 796860508Sobrien return elfcore_grok_lwpstatus (abfd, note); 796960508Sobrien#endif 797060508Sobrien 797160508Sobrien case NT_FPREGSET: /* FIXME: rename to NT_PRFPREG */ 797260508Sobrien return elfcore_grok_prfpreg (abfd, note); 797360508Sobrien 797460508Sobrien#if defined (HAVE_WIN32_PSTATUS_T) 797577301Sobrien case NT_WIN32PSTATUS: 797660508Sobrien return elfcore_grok_win32pstatus (abfd, note); 797760508Sobrien#endif 797860508Sobrien 797977301Sobrien case NT_PRXFPREG: /* Linux SSE extension */ 7980130563Sobrien if (note->namesz == 6 7981130563Sobrien && strcmp (note->namedata, "LINUX") == 0) 798260508Sobrien return elfcore_grok_prxfpreg (abfd, note); 798360508Sobrien else 7984130563Sobrien return TRUE; 798560508Sobrien 798660508Sobrien case NT_PRPSINFO: 798760508Sobrien case NT_PSINFO: 798889860Sobrien if (bed->elf_backend_grok_psinfo) 798989860Sobrien if ((*bed->elf_backend_grok_psinfo) (abfd, note)) 7990130563Sobrien return TRUE; 799189860Sobrien#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) 799260508Sobrien return elfcore_grok_psinfo (abfd, note); 799389860Sobrien#else 7994130563Sobrien return TRUE; 799560508Sobrien#endif 7996130563Sobrien 7997130563Sobrien case NT_AUXV: 7998130563Sobrien { 7999218822Sdim asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv", 8000218822Sdim SEC_HAS_CONTENTS); 8001130563Sobrien 8002130563Sobrien if (sect == NULL) 8003130563Sobrien return FALSE; 8004218822Sdim sect->size = note->descsz; 8005130563Sobrien sect->filepos = note->descpos; 8006130563Sobrien sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32; 8007130563Sobrien 8008130563Sobrien return TRUE; 8009130563Sobrien } 8010215679Sattilio 8011215679Sattilio#if defined (HAVE_THRMISC_T) 8012215679Sattilio case NT_THRMISC: 8013215679Sattilio return elfcore_grok_thrmisc (abfd, note); 8014215679Sattilio#endif 8015215679Sattilio 801660508Sobrien } 801760508Sobrien} 801860508Sobrien 8019130563Sobrienstatic bfd_boolean 8020130563Sobrienelfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp) 802189860Sobrien{ 802289860Sobrien char *cp; 802389860Sobrien 802489860Sobrien cp = strchr (note->namedata, '@'); 802589860Sobrien if (cp != NULL) 802689860Sobrien { 802794542Sobrien *lwpidp = atoi(cp + 1); 8028130563Sobrien return TRUE; 802989860Sobrien } 8030130563Sobrien return FALSE; 803189860Sobrien} 803289860Sobrien 8033130563Sobrienstatic bfd_boolean 8034130563Sobrienelfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note) 803589860Sobrien{ 803689860Sobrien /* Signal number at offset 0x08. */ 803789860Sobrien elf_tdata (abfd)->core_signal 803889860Sobrien = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08); 803989860Sobrien 804089860Sobrien /* Process ID at offset 0x50. */ 804189860Sobrien elf_tdata (abfd)->core_pid 804289860Sobrien = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50); 804389860Sobrien 804489860Sobrien /* Command name at 0x7c (max 32 bytes, including nul). */ 804589860Sobrien elf_tdata (abfd)->core_command 804689860Sobrien = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31); 804789860Sobrien 8048130563Sobrien return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo", 8049130563Sobrien note); 805089860Sobrien} 805189860Sobrien 8052130563Sobrienstatic bfd_boolean 8053130563Sobrienelfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note) 805489860Sobrien{ 805589860Sobrien int lwp; 805689860Sobrien 805789860Sobrien if (elfcore_netbsd_get_lwpid (note, &lwp)) 805889860Sobrien elf_tdata (abfd)->core_lwpid = lwp; 805989860Sobrien 806089860Sobrien if (note->type == NT_NETBSDCORE_PROCINFO) 806189860Sobrien { 806289860Sobrien /* NetBSD-specific core "procinfo". Note that we expect to 8063218822Sdim find this note before any of the others, which is fine, 8064218822Sdim since the kernel writes this note out first when it 8065218822Sdim creates a core file. */ 8066104838Sobrien 806789860Sobrien return elfcore_grok_netbsd_procinfo (abfd, note); 806889860Sobrien } 806989860Sobrien 807089860Sobrien /* As of Jan 2002 there are no other machine-independent notes 807189860Sobrien defined for NetBSD core files. If the note type is less 807289860Sobrien than the start of the machine-dependent note types, we don't 807389860Sobrien understand it. */ 8074104838Sobrien 807589860Sobrien if (note->type < NT_NETBSDCORE_FIRSTMACH) 8076130563Sobrien return TRUE; 807789860Sobrien 807889860Sobrien 807989860Sobrien switch (bfd_get_arch (abfd)) 808089860Sobrien { 8081218822Sdim /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and 8082218822Sdim PT_GETFPREGS == mach+2. */ 808389860Sobrien 808489860Sobrien case bfd_arch_alpha: 808589860Sobrien case bfd_arch_sparc: 808689860Sobrien switch (note->type) 8087218822Sdim { 8088218822Sdim case NT_NETBSDCORE_FIRSTMACH+0: 8089218822Sdim return elfcore_make_note_pseudosection (abfd, ".reg", note); 809089860Sobrien 8091218822Sdim case NT_NETBSDCORE_FIRSTMACH+2: 8092218822Sdim return elfcore_make_note_pseudosection (abfd, ".reg2", note); 809389860Sobrien 8094218822Sdim default: 8095218822Sdim return TRUE; 8096218822Sdim } 809789860Sobrien 8098218822Sdim /* On all other arch's, PT_GETREGS == mach+1 and 8099218822Sdim PT_GETFPREGS == mach+3. */ 810089860Sobrien 810189860Sobrien default: 810289860Sobrien switch (note->type) 8103218822Sdim { 8104218822Sdim case NT_NETBSDCORE_FIRSTMACH+1: 8105218822Sdim return elfcore_make_note_pseudosection (abfd, ".reg", note); 810689860Sobrien 8107218822Sdim case NT_NETBSDCORE_FIRSTMACH+3: 8108218822Sdim return elfcore_make_note_pseudosection (abfd, ".reg2", note); 810989860Sobrien 8110218822Sdim default: 8111218822Sdim return TRUE; 8112218822Sdim } 811389860Sobrien } 811489860Sobrien /* NOTREACHED */ 811589860Sobrien} 811689860Sobrien 8117130563Sobrienstatic bfd_boolean 8118218822Sdimelfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid) 8119130563Sobrien{ 8120130563Sobrien void *ddata = note->descdata; 8121130563Sobrien char buf[100]; 8122130563Sobrien char *name; 8123130563Sobrien asection *sect; 8124130563Sobrien short sig; 8125130563Sobrien unsigned flags; 8126130563Sobrien 8127130563Sobrien /* nto_procfs_status 'pid' field is at offset 0. */ 8128130563Sobrien elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata); 8129130563Sobrien 8130130563Sobrien /* nto_procfs_status 'tid' field is at offset 4. Pass it back. */ 8131130563Sobrien *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4); 8132130563Sobrien 8133130563Sobrien /* nto_procfs_status 'flags' field is at offset 8. */ 8134130563Sobrien flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8); 8135130563Sobrien 8136130563Sobrien /* nto_procfs_status 'what' field is at offset 14. */ 8137130563Sobrien if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0) 8138130563Sobrien { 8139130563Sobrien elf_tdata (abfd)->core_signal = sig; 8140130563Sobrien elf_tdata (abfd)->core_lwpid = *tid; 8141130563Sobrien } 8142130563Sobrien 8143130563Sobrien /* _DEBUG_FLAG_CURTID (current thread) is 0x80. Some cores 8144130563Sobrien do not come from signals so we make sure we set the current 8145130563Sobrien thread just in case. */ 8146130563Sobrien if (flags & 0x00000080) 8147130563Sobrien elf_tdata (abfd)->core_lwpid = *tid; 8148130563Sobrien 8149130563Sobrien /* Make a ".qnx_core_status/%d" section. */ 8150218822Sdim sprintf (buf, ".qnx_core_status/%ld", *tid); 8151130563Sobrien 8152130563Sobrien name = bfd_alloc (abfd, strlen (buf) + 1); 8153130563Sobrien if (name == NULL) 8154130563Sobrien return FALSE; 8155130563Sobrien strcpy (name, buf); 8156130563Sobrien 8157218822Sdim sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); 8158130563Sobrien if (sect == NULL) 8159130563Sobrien return FALSE; 8160130563Sobrien 8161218822Sdim sect->size = note->descsz; 8162130563Sobrien sect->filepos = note->descpos; 8163130563Sobrien sect->alignment_power = 2; 8164130563Sobrien 8165130563Sobrien return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect)); 8166130563Sobrien} 8167130563Sobrien 8168130563Sobrienstatic bfd_boolean 8169218822Sdimelfcore_grok_nto_regs (bfd *abfd, 8170218822Sdim Elf_Internal_Note *note, 8171218822Sdim long tid, 8172218822Sdim char *base) 8173130563Sobrien{ 8174130563Sobrien char buf[100]; 8175130563Sobrien char *name; 8176130563Sobrien asection *sect; 8177130563Sobrien 8178218822Sdim /* Make a "(base)/%d" section. */ 8179218822Sdim sprintf (buf, "%s/%ld", base, tid); 8180130563Sobrien 8181130563Sobrien name = bfd_alloc (abfd, strlen (buf) + 1); 8182130563Sobrien if (name == NULL) 8183130563Sobrien return FALSE; 8184130563Sobrien strcpy (name, buf); 8185130563Sobrien 8186218822Sdim sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); 8187130563Sobrien if (sect == NULL) 8188130563Sobrien return FALSE; 8189130563Sobrien 8190218822Sdim sect->size = note->descsz; 8191130563Sobrien sect->filepos = note->descpos; 8192130563Sobrien sect->alignment_power = 2; 8193130563Sobrien 8194130563Sobrien /* This is the current thread. */ 8195130563Sobrien if (elf_tdata (abfd)->core_lwpid == tid) 8196218822Sdim return elfcore_maybe_make_sect (abfd, base, sect); 8197130563Sobrien 8198130563Sobrien return TRUE; 8199130563Sobrien} 8200130563Sobrien 8201130563Sobrien#define BFD_QNT_CORE_INFO 7 8202130563Sobrien#define BFD_QNT_CORE_STATUS 8 8203130563Sobrien#define BFD_QNT_CORE_GREG 9 8204130563Sobrien#define BFD_QNT_CORE_FPREG 10 8205130563Sobrien 8206130563Sobrienstatic bfd_boolean 8207130563Sobrienelfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note) 8208130563Sobrien{ 8209130563Sobrien /* Every GREG section has a STATUS section before it. Store the 8210130563Sobrien tid from the previous call to pass down to the next gregs 8211130563Sobrien function. */ 8212218822Sdim static long tid = 1; 8213130563Sobrien 8214130563Sobrien switch (note->type) 8215130563Sobrien { 8216218822Sdim case BFD_QNT_CORE_INFO: 8217218822Sdim return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note); 8218218822Sdim case BFD_QNT_CORE_STATUS: 8219218822Sdim return elfcore_grok_nto_status (abfd, note, &tid); 8220218822Sdim case BFD_QNT_CORE_GREG: 8221218822Sdim return elfcore_grok_nto_regs (abfd, note, tid, ".reg"); 8222218822Sdim case BFD_QNT_CORE_FPREG: 8223218822Sdim return elfcore_grok_nto_regs (abfd, note, tid, ".reg2"); 8224218822Sdim default: 8225218822Sdim return TRUE; 8226130563Sobrien } 8227130563Sobrien} 8228130563Sobrien 822989860Sobrien/* Function: elfcore_write_note 823089860Sobrien 8231104838Sobrien Inputs: 8232218822Sdim buffer to hold note, and current size of buffer 823389860Sobrien name of note 823489860Sobrien type of note 823589860Sobrien data for note 823689860Sobrien size of data for note 823789860Sobrien 8238218822Sdim Writes note to end of buffer. ELF64 notes are written exactly as 8239218822Sdim for ELF32, despite the current (as of 2006) ELF gabi specifying 8240218822Sdim that they ought to have 8-byte namesz and descsz field, and have 8241218822Sdim 8-byte alignment. Other writers, eg. Linux kernel, do the same. 8242218822Sdim 824389860Sobrien Return: 8244218822Sdim Pointer to realloc'd buffer, *BUFSIZ updated. */ 824589860Sobrien 824689860Sobrienchar * 8247218822Sdimelfcore_write_note (bfd *abfd, 8248130563Sobrien char *buf, 8249218822Sdim int *bufsiz, 8250130563Sobrien const char *name, 8251218822Sdim int type, 8252130563Sobrien const void *input, 8253218822Sdim int size) 825489860Sobrien{ 825589860Sobrien Elf_External_Note *xnp; 8256104838Sobrien size_t namesz; 8257104838Sobrien size_t newspace; 8258218822Sdim char *dest; 825989860Sobrien 8260104838Sobrien namesz = 0; 8261104838Sobrien if (name != NULL) 8262218822Sdim namesz = strlen (name) + 1; 8263104838Sobrien 8264218822Sdim newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4); 8265104838Sobrien 8266218822Sdim buf = realloc (buf, *bufsiz + newspace); 8267218822Sdim dest = buf + *bufsiz; 826889860Sobrien *bufsiz += newspace; 826989860Sobrien xnp = (Elf_External_Note *) dest; 827089860Sobrien H_PUT_32 (abfd, namesz, xnp->namesz); 827189860Sobrien H_PUT_32 (abfd, size, xnp->descsz); 827289860Sobrien H_PUT_32 (abfd, type, xnp->type); 8273104838Sobrien dest = xnp->name; 8274104838Sobrien if (name != NULL) 8275104838Sobrien { 8276104838Sobrien memcpy (dest, name, namesz); 8277104838Sobrien dest += namesz; 8278218822Sdim while (namesz & 3) 8279104838Sobrien { 8280104838Sobrien *dest++ = '\0'; 8281218822Sdim ++namesz; 8282104838Sobrien } 8283104838Sobrien } 8284104838Sobrien memcpy (dest, input, size); 8285218822Sdim dest += size; 8286218822Sdim while (size & 3) 8287218822Sdim { 8288218822Sdim *dest++ = '\0'; 8289218822Sdim ++size; 8290218822Sdim } 8291218822Sdim return buf; 829289860Sobrien} 829389860Sobrien 829489860Sobrien#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) 829589860Sobrienchar * 8296130563Sobrienelfcore_write_prpsinfo (bfd *abfd, 8297130563Sobrien char *buf, 8298130563Sobrien int *bufsiz, 8299130563Sobrien const char *fname, 8300130563Sobrien const char *psargs) 830189860Sobrien{ 8302218822Sdim const char *note_name = "CORE"; 8303218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 830489860Sobrien 8305218822Sdim if (bed->elf_backend_write_core_note != NULL) 8306218822Sdim { 8307218822Sdim char *ret; 8308218822Sdim ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz, 8309218822Sdim NT_PRPSINFO, fname, psargs); 8310218822Sdim if (ret != NULL) 8311218822Sdim return ret; 8312218822Sdim } 8313218822Sdim 8314218822Sdim#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T) 8315218822Sdim if (bed->s->elfclass == ELFCLASS32) 8316218822Sdim { 8317218822Sdim#if defined (HAVE_PSINFO32_T) 8318218822Sdim psinfo32_t data; 8319218822Sdim int note_type = NT_PSINFO; 8320218822Sdim#else 8321218822Sdim prpsinfo32_t data; 8322218822Sdim int note_type = NT_PRPSINFO; 8323218822Sdim#endif 8324218822Sdim 8325218822Sdim memset (&data, 0, sizeof (data)); 8326218822Sdim strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); 8327218822Sdim strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); 8328218822Sdim return elfcore_write_note (abfd, buf, bufsiz, 8329218822Sdim note_name, note_type, &data, sizeof (data)); 8330218822Sdim } 8331218822Sdim else 8332218822Sdim#endif 8333218822Sdim { 833489860Sobrien#if defined (HAVE_PSINFO_T) 8335218822Sdim psinfo_t data; 8336218822Sdim int note_type = NT_PSINFO; 833789860Sobrien#else 8338218822Sdim prpsinfo_t data; 8339218822Sdim int note_type = NT_PRPSINFO; 834089860Sobrien#endif 834189860Sobrien 8342218822Sdim memset (&data, 0, sizeof (data)); 8343218822Sdim strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); 8344218822Sdim strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); 8345218822Sdim return elfcore_write_note (abfd, buf, bufsiz, 8346218822Sdim note_name, note_type, &data, sizeof (data)); 8347218822Sdim } 834889860Sobrien} 834989860Sobrien#endif /* PSINFO_T or PRPSINFO_T */ 835089860Sobrien 835189860Sobrien#if defined (HAVE_PRSTATUS_T) 835289860Sobrienchar * 8353130563Sobrienelfcore_write_prstatus (bfd *abfd, 8354130563Sobrien char *buf, 8355130563Sobrien int *bufsiz, 8356130563Sobrien long pid, 8357130563Sobrien int cursig, 8358130563Sobrien const void *gregs) 835989860Sobrien{ 8360218822Sdim const char *note_name = "CORE"; 8361218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 836289860Sobrien 8363218822Sdim if (bed->elf_backend_write_core_note != NULL) 8364218822Sdim { 8365218822Sdim char *ret; 8366218822Sdim ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz, 8367218822Sdim NT_PRSTATUS, 8368218822Sdim pid, cursig, gregs); 8369218822Sdim if (ret != NULL) 8370218822Sdim return ret; 8371218822Sdim } 8372218822Sdim 8373218822Sdim#if defined (HAVE_PRSTATUS32_T) 8374218822Sdim if (bed->s->elfclass == ELFCLASS32) 8375218822Sdim { 8376218822Sdim prstatus32_t prstat; 8377218822Sdim 8378218822Sdim memset (&prstat, 0, sizeof (prstat)); 8379218822Sdim prstat.pr_pid = pid; 8380218822Sdim prstat.pr_cursig = cursig; 8381218822Sdim memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); 8382218822Sdim return elfcore_write_note (abfd, buf, bufsiz, note_name, 8383218822Sdim NT_PRSTATUS, &prstat, sizeof (prstat)); 8384218822Sdim } 8385218822Sdim else 8386218822Sdim#endif 8387218822Sdim { 8388218822Sdim prstatus_t prstat; 8389218822Sdim 8390218822Sdim memset (&prstat, 0, sizeof (prstat)); 8391218822Sdim prstat.pr_pid = pid; 8392218822Sdim prstat.pr_cursig = cursig; 8393218822Sdim memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); 8394218822Sdim return elfcore_write_note (abfd, buf, bufsiz, note_name, 8395218822Sdim NT_PRSTATUS, &prstat, sizeof (prstat)); 8396218822Sdim } 839789860Sobrien} 839889860Sobrien#endif /* HAVE_PRSTATUS_T */ 839989860Sobrien 840094542Sobrien#if defined (HAVE_LWPSTATUS_T) 840194542Sobrienchar * 8402130563Sobrienelfcore_write_lwpstatus (bfd *abfd, 8403130563Sobrien char *buf, 8404130563Sobrien int *bufsiz, 8405130563Sobrien long pid, 8406130563Sobrien int cursig, 8407130563Sobrien const void *gregs) 840894542Sobrien{ 840994542Sobrien lwpstatus_t lwpstat; 8410218822Sdim const char *note_name = "CORE"; 841194542Sobrien 841294542Sobrien memset (&lwpstat, 0, sizeof (lwpstat)); 841394542Sobrien lwpstat.pr_lwpid = pid >> 16; 841494542Sobrien lwpstat.pr_cursig = cursig; 841594542Sobrien#if defined (HAVE_LWPSTATUS_T_PR_REG) 841694542Sobrien memcpy (lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg)); 841794542Sobrien#elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT) 841894542Sobrien#if !defined(gregs) 841994542Sobrien memcpy (lwpstat.pr_context.uc_mcontext.gregs, 842094542Sobrien gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs)); 842194542Sobrien#else 842294542Sobrien memcpy (lwpstat.pr_context.uc_mcontext.__gregs, 842394542Sobrien gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs)); 842494542Sobrien#endif 842594542Sobrien#endif 8426104838Sobrien return elfcore_write_note (abfd, buf, bufsiz, note_name, 842794542Sobrien NT_LWPSTATUS, &lwpstat, sizeof (lwpstat)); 842894542Sobrien} 842994542Sobrien#endif /* HAVE_LWPSTATUS_T */ 843094542Sobrien 843189860Sobrien#if defined (HAVE_PSTATUS_T) 843289860Sobrienchar * 8433130563Sobrienelfcore_write_pstatus (bfd *abfd, 8434130563Sobrien char *buf, 8435130563Sobrien int *bufsiz, 8436130563Sobrien long pid, 8437218822Sdim int cursig ATTRIBUTE_UNUSED, 8438218822Sdim const void *gregs ATTRIBUTE_UNUSED) 843989860Sobrien{ 8440218822Sdim const char *note_name = "CORE"; 8441218822Sdim#if defined (HAVE_PSTATUS32_T) 8442218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 844389860Sobrien 8444218822Sdim if (bed->s->elfclass == ELFCLASS32) 8445218822Sdim { 8446218822Sdim pstatus32_t pstat; 8447218822Sdim 8448218822Sdim memset (&pstat, 0, sizeof (pstat)); 8449218822Sdim pstat.pr_pid = pid & 0xffff; 8450218822Sdim buf = elfcore_write_note (abfd, buf, bufsiz, note_name, 8451218822Sdim NT_PSTATUS, &pstat, sizeof (pstat)); 8452218822Sdim return buf; 8453218822Sdim } 8454218822Sdim else 8455218822Sdim#endif 8456218822Sdim { 8457218822Sdim pstatus_t pstat; 8458218822Sdim 8459218822Sdim memset (&pstat, 0, sizeof (pstat)); 8460218822Sdim pstat.pr_pid = pid & 0xffff; 8461218822Sdim buf = elfcore_write_note (abfd, buf, bufsiz, note_name, 8462218822Sdim NT_PSTATUS, &pstat, sizeof (pstat)); 8463218822Sdim return buf; 8464218822Sdim } 846589860Sobrien} 846689860Sobrien#endif /* HAVE_PSTATUS_T */ 846789860Sobrien 846889860Sobrienchar * 8469130563Sobrienelfcore_write_prfpreg (bfd *abfd, 8470130563Sobrien char *buf, 8471130563Sobrien int *bufsiz, 8472130563Sobrien const void *fpregs, 8473130563Sobrien int size) 847489860Sobrien{ 8475218822Sdim const char *note_name = "CORE"; 8476104838Sobrien return elfcore_write_note (abfd, buf, bufsiz, 847789860Sobrien note_name, NT_FPREGSET, fpregs, size); 847889860Sobrien} 847989860Sobrien 848089860Sobrienchar * 8481215679Sattilioelfcore_write_thrmisc (bfd *abfd, 8482215679Sattilio char *buf, 8483215679Sattilio int *bufsiz, 8484215679Sattilio const char *tname, 8485215679Sattilio int size) 8486215679Sattilio{ 8487215679Sattilio#if defined (HAVE_THRMISC_T) 8488215679Sattilio char *note_name = "CORE"; 8489215679Sattilio return elfcore_write_note (abfd, buf, bufsiz, 8490215679Sattilio note_name, NT_THRMISC, tname, size); 8491215679Sattilio#else 8492215679Sattilio return buf; 8493215679Sattilio#endif 8494215679Sattilio} 8495215679Sattilio 8496215679Sattiliochar * 8497130563Sobrienelfcore_write_prxfpreg (bfd *abfd, 8498130563Sobrien char *buf, 8499130563Sobrien int *bufsiz, 8500130563Sobrien const void *xfpregs, 8501130563Sobrien int size) 850289860Sobrien{ 850389860Sobrien char *note_name = "LINUX"; 8504104838Sobrien return elfcore_write_note (abfd, buf, bufsiz, 850589860Sobrien note_name, NT_PRXFPREG, xfpregs, size); 850689860Sobrien} 850789860Sobrien 8508130563Sobrienstatic bfd_boolean 8509130563Sobrienelfcore_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size) 851060508Sobrien{ 851177301Sobrien char *buf; 851277301Sobrien char *p; 851360508Sobrien 851460508Sobrien if (size <= 0) 8515130563Sobrien return TRUE; 851660508Sobrien 851789860Sobrien if (bfd_seek (abfd, offset, SEEK_SET) != 0) 8518130563Sobrien return FALSE; 851960508Sobrien 852089860Sobrien buf = bfd_malloc (size); 852160508Sobrien if (buf == NULL) 8522130563Sobrien return FALSE; 852360508Sobrien 852489860Sobrien if (bfd_bread (buf, size, abfd) != size) 852560508Sobrien { 852660508Sobrien error: 852760508Sobrien free (buf); 8528130563Sobrien return FALSE; 852960508Sobrien } 853060508Sobrien 853160508Sobrien p = buf; 853260508Sobrien while (p < buf + size) 853360508Sobrien { 853477301Sobrien /* FIXME: bad alignment assumption. */ 853577301Sobrien Elf_External_Note *xnp = (Elf_External_Note *) p; 853660508Sobrien Elf_Internal_Note in; 853760508Sobrien 853889860Sobrien in.type = H_GET_32 (abfd, xnp->type); 853960508Sobrien 854089860Sobrien in.namesz = H_GET_32 (abfd, xnp->namesz); 854160508Sobrien in.namedata = xnp->name; 854260508Sobrien 854389860Sobrien in.descsz = H_GET_32 (abfd, xnp->descsz); 854460508Sobrien in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4); 854560508Sobrien in.descpos = offset + (in.descdata - buf); 854660508Sobrien 8547218822Sdim if (CONST_STRNEQ (in.namedata, "NetBSD-CORE")) 8548130563Sobrien { 8549218822Sdim if (! elfcore_grok_netbsd_note (abfd, &in)) 8550218822Sdim goto error; 8551218822Sdim } 8552218822Sdim else if (CONST_STRNEQ (in.namedata, "QNX")) 8553218822Sdim { 8554130563Sobrien if (! elfcore_grok_nto_note (abfd, &in)) 8555130563Sobrien goto error; 8556130563Sobrien } 855789860Sobrien else 8558218822Sdim { 8559218822Sdim if (! elfcore_grok_note (abfd, &in)) 8560218822Sdim goto error; 8561218822Sdim } 856260508Sobrien 856360508Sobrien p = in.descdata + BFD_ALIGN (in.descsz, 4); 856460508Sobrien } 856560508Sobrien 856660508Sobrien free (buf); 8567130563Sobrien return TRUE; 856860508Sobrien} 856960508Sobrien 857060508Sobrien/* Providing external access to the ELF program header table. */ 857160508Sobrien 857260508Sobrien/* Return an upper bound on the number of bytes required to store a 857360508Sobrien copy of ABFD's program header table entries. Return -1 if an error 857460508Sobrien occurs; bfd_get_error will return an appropriate code. */ 857577301Sobrien 857660508Sobrienlong 8577130563Sobrienbfd_get_elf_phdr_upper_bound (bfd *abfd) 857860508Sobrien{ 857960508Sobrien if (abfd->xvec->flavour != bfd_target_elf_flavour) 858060508Sobrien { 858160508Sobrien bfd_set_error (bfd_error_wrong_format); 858260508Sobrien return -1; 858360508Sobrien } 858460508Sobrien 858589860Sobrien return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr); 858660508Sobrien} 858760508Sobrien 858860508Sobrien/* Copy ABFD's program header table entries to *PHDRS. The entries 858960508Sobrien will be stored as an array of Elf_Internal_Phdr structures, as 859060508Sobrien defined in include/elf/internal.h. To find out how large the 859160508Sobrien buffer needs to be, call bfd_get_elf_phdr_upper_bound. 859260508Sobrien 859360508Sobrien Return the number of program header table entries read, or -1 if an 859460508Sobrien error occurs; bfd_get_error will return an appropriate code. */ 859577301Sobrien 859660508Sobrienint 8597130563Sobrienbfd_get_elf_phdrs (bfd *abfd, void *phdrs) 859860508Sobrien{ 859960508Sobrien int num_phdrs; 860060508Sobrien 860160508Sobrien if (abfd->xvec->flavour != bfd_target_elf_flavour) 860260508Sobrien { 860360508Sobrien bfd_set_error (bfd_error_wrong_format); 860460508Sobrien return -1; 860560508Sobrien } 860660508Sobrien 860760508Sobrien num_phdrs = elf_elfheader (abfd)->e_phnum; 860877301Sobrien memcpy (phdrs, elf_tdata (abfd)->phdr, 860960508Sobrien num_phdrs * sizeof (Elf_Internal_Phdr)); 861060508Sobrien 861160508Sobrien return num_phdrs; 861260508Sobrien} 861389860Sobrien 861489860Sobrienvoid 8615130563Sobrien_bfd_elf_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value) 861689860Sobrien{ 861789860Sobrien#ifdef BFD64 861889860Sobrien Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ 861989860Sobrien 862089860Sobrien i_ehdrp = elf_elfheader (abfd); 862189860Sobrien if (i_ehdrp == NULL) 862289860Sobrien sprintf_vma (buf, value); 862389860Sobrien else 862489860Sobrien { 862589860Sobrien if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64) 862689860Sobrien { 862789860Sobrien#if BFD_HOST_64BIT_LONG 862889860Sobrien sprintf (buf, "%016lx", value); 862989860Sobrien#else 863089860Sobrien sprintf (buf, "%08lx%08lx", _bfd_int64_high (value), 863189860Sobrien _bfd_int64_low (value)); 863289860Sobrien#endif 863389860Sobrien } 863489860Sobrien else 863589860Sobrien sprintf (buf, "%08lx", (unsigned long) (value & 0xffffffff)); 863689860Sobrien } 863789860Sobrien#else 863889860Sobrien sprintf_vma (buf, value); 863989860Sobrien#endif 864089860Sobrien} 864189860Sobrien 864289860Sobrienvoid 8643130563Sobrien_bfd_elf_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value) 864489860Sobrien{ 864589860Sobrien#ifdef BFD64 864689860Sobrien Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ 864789860Sobrien 864889860Sobrien i_ehdrp = elf_elfheader (abfd); 864989860Sobrien if (i_ehdrp == NULL) 865089860Sobrien fprintf_vma ((FILE *) stream, value); 865189860Sobrien else 865289860Sobrien { 865389860Sobrien if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64) 865489860Sobrien { 865589860Sobrien#if BFD_HOST_64BIT_LONG 865689860Sobrien fprintf ((FILE *) stream, "%016lx", value); 865789860Sobrien#else 865889860Sobrien fprintf ((FILE *) stream, "%08lx%08lx", 865989860Sobrien _bfd_int64_high (value), _bfd_int64_low (value)); 866089860Sobrien#endif 866189860Sobrien } 866289860Sobrien else 866389860Sobrien fprintf ((FILE *) stream, "%08lx", 866489860Sobrien (unsigned long) (value & 0xffffffff)); 866589860Sobrien } 866689860Sobrien#else 866789860Sobrien fprintf_vma ((FILE *) stream, value); 866889860Sobrien#endif 866989860Sobrien} 867089860Sobrien 867189860Sobrienenum elf_reloc_type_class 8672130563Sobrien_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED) 867389860Sobrien{ 867489860Sobrien return reloc_class_normal; 867589860Sobrien} 867689860Sobrien 8677104838Sobrien/* For RELA architectures, return the relocation value for a 867889860Sobrien relocation against a local symbol. */ 867989860Sobrien 868089860Sobrienbfd_vma 8681130563Sobrien_bfd_elf_rela_local_sym (bfd *abfd, 8682130563Sobrien Elf_Internal_Sym *sym, 8683130563Sobrien asection **psec, 8684130563Sobrien Elf_Internal_Rela *rel) 868589860Sobrien{ 8686130563Sobrien asection *sec = *psec; 868789860Sobrien bfd_vma relocation; 868889860Sobrien 868989860Sobrien relocation = (sec->output_section->vma 869089860Sobrien + sec->output_offset 869189860Sobrien + sym->st_value); 869289860Sobrien if ((sec->flags & SEC_MERGE) 869389860Sobrien && ELF_ST_TYPE (sym->st_info) == STT_SECTION 8694130563Sobrien && sec->sec_info_type == ELF_INFO_TYPE_MERGE) 869589860Sobrien { 869689860Sobrien rel->r_addend = 8697130563Sobrien _bfd_merged_section_offset (abfd, psec, 869889860Sobrien elf_section_data (sec)->sec_info, 8699218822Sdim sym->st_value + rel->r_addend); 8700218822Sdim if (sec != *psec) 8701218822Sdim { 8702218822Sdim /* If we have changed the section, and our original section is 8703218822Sdim marked with SEC_EXCLUDE, it means that the original 8704218822Sdim SEC_MERGE section has been completely subsumed in some 8705218822Sdim other SEC_MERGE section. In this case, we need to leave 8706218822Sdim some info around for --emit-relocs. */ 8707218822Sdim if ((sec->flags & SEC_EXCLUDE) != 0) 8708218822Sdim sec->kept_section = *psec; 8709218822Sdim sec = *psec; 8710218822Sdim } 8711130563Sobrien rel->r_addend -= relocation; 8712130563Sobrien rel->r_addend += sec->output_section->vma + sec->output_offset; 871389860Sobrien } 871489860Sobrien return relocation; 871589860Sobrien} 871689860Sobrien 871789860Sobrienbfd_vma 8718130563Sobrien_bfd_elf_rel_local_sym (bfd *abfd, 8719130563Sobrien Elf_Internal_Sym *sym, 8720130563Sobrien asection **psec, 8721130563Sobrien bfd_vma addend) 8722104838Sobrien{ 872389860Sobrien asection *sec = *psec; 872489860Sobrien 8725130563Sobrien if (sec->sec_info_type != ELF_INFO_TYPE_MERGE) 872689860Sobrien return sym->st_value + addend; 872789860Sobrien 872889860Sobrien return _bfd_merged_section_offset (abfd, psec, 872989860Sobrien elf_section_data (sec)->sec_info, 8730218822Sdim sym->st_value + addend); 873189860Sobrien} 873289860Sobrien 873389860Sobrienbfd_vma 8734130563Sobrien_bfd_elf_section_offset (bfd *abfd, 8735130563Sobrien struct bfd_link_info *info, 8736130563Sobrien asection *sec, 8737130563Sobrien bfd_vma offset) 873889860Sobrien{ 8739130563Sobrien switch (sec->sec_info_type) 874089860Sobrien { 874189860Sobrien case ELF_INFO_TYPE_STABS: 8742218822Sdim return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info, 8743218822Sdim offset); 874489860Sobrien case ELF_INFO_TYPE_EH_FRAME: 8745218822Sdim return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset); 874689860Sobrien default: 874789860Sobrien return offset; 874889860Sobrien } 874989860Sobrien} 8750130563Sobrien 8751130563Sobrien/* Create a new BFD as if by bfd_openr. Rather than opening a file, 8752130563Sobrien reconstruct an ELF file by reading the segments out of remote memory 8753130563Sobrien based on the ELF file header at EHDR_VMA and the ELF program headers it 8754130563Sobrien points to. If not null, *LOADBASEP is filled in with the difference 8755130563Sobrien between the VMAs from which the segments were read, and the VMAs the 8756130563Sobrien file headers (and hence BFD's idea of each section's VMA) put them at. 8757130563Sobrien 8758130563Sobrien The function TARGET_READ_MEMORY is called to copy LEN bytes from the 8759130563Sobrien remote memory at target address VMA into the local buffer at MYADDR; it 8760130563Sobrien should return zero on success or an `errno' code on failure. TEMPL must 8761130563Sobrien be a BFD for an ELF target with the word size and byte order found in 8762130563Sobrien the remote memory. */ 8763130563Sobrien 8764130563Sobrienbfd * 8765130563Sobrienbfd_elf_bfd_from_remote_memory 8766130563Sobrien (bfd *templ, 8767130563Sobrien bfd_vma ehdr_vma, 8768130563Sobrien bfd_vma *loadbasep, 8769218822Sdim int (*target_read_memory) (bfd_vma, bfd_byte *, int)) 8770130563Sobrien{ 8771130563Sobrien return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory) 8772130563Sobrien (templ, ehdr_vma, loadbasep, target_read_memory); 8773130563Sobrien} 8774218822Sdim 8775218822Sdimlong 8776218822Sdim_bfd_elf_get_synthetic_symtab (bfd *abfd, 8777218822Sdim long symcount ATTRIBUTE_UNUSED, 8778218822Sdim asymbol **syms ATTRIBUTE_UNUSED, 8779218822Sdim long dynsymcount, 8780218822Sdim asymbol **dynsyms, 8781218822Sdim asymbol **ret) 8782218822Sdim{ 8783218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 8784218822Sdim asection *relplt; 8785218822Sdim asymbol *s; 8786218822Sdim const char *relplt_name; 8787218822Sdim bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean); 8788218822Sdim arelent *p; 8789218822Sdim long count, i, n; 8790218822Sdim size_t size; 8791218822Sdim Elf_Internal_Shdr *hdr; 8792218822Sdim char *names; 8793218822Sdim asection *plt; 8794218822Sdim 8795218822Sdim *ret = NULL; 8796218822Sdim 8797218822Sdim if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0) 8798218822Sdim return 0; 8799218822Sdim 8800218822Sdim if (dynsymcount <= 0) 8801218822Sdim return 0; 8802218822Sdim 8803218822Sdim if (!bed->plt_sym_val) 8804218822Sdim return 0; 8805218822Sdim 8806218822Sdim relplt_name = bed->relplt_name; 8807218822Sdim if (relplt_name == NULL) 8808218822Sdim relplt_name = bed->default_use_rela_p ? ".rela.plt" : ".rel.plt"; 8809218822Sdim relplt = bfd_get_section_by_name (abfd, relplt_name); 8810218822Sdim if (relplt == NULL) 8811218822Sdim return 0; 8812218822Sdim 8813218822Sdim hdr = &elf_section_data (relplt)->this_hdr; 8814218822Sdim if (hdr->sh_link != elf_dynsymtab (abfd) 8815218822Sdim || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA)) 8816218822Sdim return 0; 8817218822Sdim 8818218822Sdim plt = bfd_get_section_by_name (abfd, ".plt"); 8819218822Sdim if (plt == NULL) 8820218822Sdim return 0; 8821218822Sdim 8822218822Sdim slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; 8823218822Sdim if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE)) 8824218822Sdim return -1; 8825218822Sdim 8826218822Sdim count = relplt->size / hdr->sh_entsize; 8827218822Sdim size = count * sizeof (asymbol); 8828218822Sdim p = relplt->relocation; 8829218822Sdim for (i = 0; i < count; i++, s++, p++) 8830218822Sdim size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt"); 8831218822Sdim 8832218822Sdim s = *ret = bfd_malloc (size); 8833218822Sdim if (s == NULL) 8834218822Sdim return -1; 8835218822Sdim 8836218822Sdim names = (char *) (s + count); 8837218822Sdim p = relplt->relocation; 8838218822Sdim n = 0; 8839218822Sdim for (i = 0; i < count; i++, s++, p++) 8840218822Sdim { 8841218822Sdim size_t len; 8842218822Sdim bfd_vma addr; 8843218822Sdim 8844218822Sdim addr = bed->plt_sym_val (i, plt, p); 8845218822Sdim if (addr == (bfd_vma) -1) 8846218822Sdim continue; 8847218822Sdim 8848218822Sdim *s = **p->sym_ptr_ptr; 8849218822Sdim /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since 8850218822Sdim we are defining a symbol, ensure one of them is set. */ 8851218822Sdim if ((s->flags & BSF_LOCAL) == 0) 8852218822Sdim s->flags |= BSF_GLOBAL; 8853218822Sdim s->section = plt; 8854218822Sdim s->value = addr - plt->vma; 8855218822Sdim s->name = names; 8856218822Sdim len = strlen ((*p->sym_ptr_ptr)->name); 8857218822Sdim memcpy (names, (*p->sym_ptr_ptr)->name, len); 8858218822Sdim names += len; 8859218822Sdim memcpy (names, "@plt", sizeof ("@plt")); 8860218822Sdim names += sizeof ("@plt"); 8861218822Sdim ++n; 8862218822Sdim } 8863218822Sdim 8864218822Sdim return n; 8865218822Sdim} 8866218822Sdim 8867218822Sdimstruct elf_symbuf_symbol 8868218822Sdim{ 8869218822Sdim unsigned long st_name; /* Symbol name, index in string tbl */ 8870218822Sdim unsigned char st_info; /* Type and binding attributes */ 8871218822Sdim unsigned char st_other; /* Visibilty, and target specific */ 8872218822Sdim}; 8873218822Sdim 8874218822Sdimstruct elf_symbuf_head 8875218822Sdim{ 8876218822Sdim struct elf_symbuf_symbol *ssym; 8877218822Sdim bfd_size_type count; 8878218822Sdim unsigned int st_shndx; 8879218822Sdim}; 8880218822Sdim 8881218822Sdimstruct elf_symbol 8882218822Sdim{ 8883218822Sdim union 8884218822Sdim { 8885218822Sdim Elf_Internal_Sym *isym; 8886218822Sdim struct elf_symbuf_symbol *ssym; 8887218822Sdim } u; 8888218822Sdim const char *name; 8889218822Sdim}; 8890218822Sdim 8891218822Sdim/* Sort references to symbols by ascending section number. */ 8892218822Sdim 8893218822Sdimstatic int 8894218822Sdimelf_sort_elf_symbol (const void *arg1, const void *arg2) 8895218822Sdim{ 8896218822Sdim const Elf_Internal_Sym *s1 = *(const Elf_Internal_Sym **) arg1; 8897218822Sdim const Elf_Internal_Sym *s2 = *(const Elf_Internal_Sym **) arg2; 8898218822Sdim 8899218822Sdim return s1->st_shndx - s2->st_shndx; 8900218822Sdim} 8901218822Sdim 8902218822Sdimstatic int 8903218822Sdimelf_sym_name_compare (const void *arg1, const void *arg2) 8904218822Sdim{ 8905218822Sdim const struct elf_symbol *s1 = (const struct elf_symbol *) arg1; 8906218822Sdim const struct elf_symbol *s2 = (const struct elf_symbol *) arg2; 8907218822Sdim return strcmp (s1->name, s2->name); 8908218822Sdim} 8909218822Sdim 8910218822Sdimstatic struct elf_symbuf_head * 8911218822Sdimelf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf) 8912218822Sdim{ 8913218822Sdim Elf_Internal_Sym **ind, **indbufend, **indbuf 8914218822Sdim = bfd_malloc2 (symcount, sizeof (*indbuf)); 8915218822Sdim struct elf_symbuf_symbol *ssym; 8916218822Sdim struct elf_symbuf_head *ssymbuf, *ssymhead; 8917218822Sdim bfd_size_type i, shndx_count; 8918218822Sdim 8919218822Sdim if (indbuf == NULL) 8920218822Sdim return NULL; 8921218822Sdim 8922218822Sdim for (ind = indbuf, i = 0; i < symcount; i++) 8923218822Sdim if (isymbuf[i].st_shndx != SHN_UNDEF) 8924218822Sdim *ind++ = &isymbuf[i]; 8925218822Sdim indbufend = ind; 8926218822Sdim 8927218822Sdim qsort (indbuf, indbufend - indbuf, sizeof (Elf_Internal_Sym *), 8928218822Sdim elf_sort_elf_symbol); 8929218822Sdim 8930218822Sdim shndx_count = 0; 8931218822Sdim if (indbufend > indbuf) 8932218822Sdim for (ind = indbuf, shndx_count++; ind < indbufend - 1; ind++) 8933218822Sdim if (ind[0]->st_shndx != ind[1]->st_shndx) 8934218822Sdim shndx_count++; 8935218822Sdim 8936218822Sdim ssymbuf = bfd_malloc ((shndx_count + 1) * sizeof (*ssymbuf) 8937296437Sdim + (indbufend - indbuf) * sizeof (*ssym)); 8938218822Sdim if (ssymbuf == NULL) 8939218822Sdim { 8940218822Sdim free (indbuf); 8941218822Sdim return NULL; 8942218822Sdim } 8943218822Sdim 8944296437Sdim ssym = (struct elf_symbuf_symbol *) (ssymbuf + shndx_count + 1); 8945218822Sdim ssymbuf->ssym = NULL; 8946218822Sdim ssymbuf->count = shndx_count; 8947218822Sdim ssymbuf->st_shndx = 0; 8948218822Sdim for (ssymhead = ssymbuf, ind = indbuf; ind < indbufend; ssym++, ind++) 8949218822Sdim { 8950218822Sdim if (ind == indbuf || ssymhead->st_shndx != (*ind)->st_shndx) 8951218822Sdim { 8952218822Sdim ssymhead++; 8953218822Sdim ssymhead->ssym = ssym; 8954218822Sdim ssymhead->count = 0; 8955218822Sdim ssymhead->st_shndx = (*ind)->st_shndx; 8956218822Sdim } 8957218822Sdim ssym->st_name = (*ind)->st_name; 8958218822Sdim ssym->st_info = (*ind)->st_info; 8959218822Sdim ssym->st_other = (*ind)->st_other; 8960218822Sdim ssymhead->count++; 8961218822Sdim } 8962218822Sdim BFD_ASSERT ((bfd_size_type) (ssymhead - ssymbuf) == shndx_count); 8963218822Sdim 8964218822Sdim free (indbuf); 8965218822Sdim return ssymbuf; 8966218822Sdim} 8967218822Sdim 8968218822Sdim/* Check if 2 sections define the same set of local and global 8969218822Sdim symbols. */ 8970218822Sdim 8971218822Sdimbfd_boolean 8972218822Sdimbfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, 8973218822Sdim struct bfd_link_info *info) 8974218822Sdim{ 8975218822Sdim bfd *bfd1, *bfd2; 8976218822Sdim const struct elf_backend_data *bed1, *bed2; 8977218822Sdim Elf_Internal_Shdr *hdr1, *hdr2; 8978218822Sdim bfd_size_type symcount1, symcount2; 8979218822Sdim Elf_Internal_Sym *isymbuf1, *isymbuf2; 8980218822Sdim struct elf_symbuf_head *ssymbuf1, *ssymbuf2; 8981218822Sdim Elf_Internal_Sym *isym, *isymend; 8982218822Sdim struct elf_symbol *symtable1 = NULL, *symtable2 = NULL; 8983218822Sdim bfd_size_type count1, count2, i; 8984218822Sdim int shndx1, shndx2; 8985218822Sdim bfd_boolean result; 8986218822Sdim 8987218822Sdim bfd1 = sec1->owner; 8988218822Sdim bfd2 = sec2->owner; 8989218822Sdim 8990218822Sdim /* If both are .gnu.linkonce sections, they have to have the same 8991218822Sdim section name. */ 8992218822Sdim if (CONST_STRNEQ (sec1->name, ".gnu.linkonce") 8993218822Sdim && CONST_STRNEQ (sec2->name, ".gnu.linkonce")) 8994218822Sdim return strcmp (sec1->name + sizeof ".gnu.linkonce", 8995218822Sdim sec2->name + sizeof ".gnu.linkonce") == 0; 8996218822Sdim 8997218822Sdim /* Both sections have to be in ELF. */ 8998218822Sdim if (bfd_get_flavour (bfd1) != bfd_target_elf_flavour 8999218822Sdim || bfd_get_flavour (bfd2) != bfd_target_elf_flavour) 9000218822Sdim return FALSE; 9001218822Sdim 9002218822Sdim if (elf_section_type (sec1) != elf_section_type (sec2)) 9003218822Sdim return FALSE; 9004218822Sdim 9005218822Sdim if ((elf_section_flags (sec1) & SHF_GROUP) != 0 9006218822Sdim && (elf_section_flags (sec2) & SHF_GROUP) != 0) 9007218822Sdim { 9008218822Sdim /* If both are members of section groups, they have to have the 9009218822Sdim same group name. */ 9010218822Sdim if (strcmp (elf_group_name (sec1), elf_group_name (sec2)) != 0) 9011218822Sdim return FALSE; 9012218822Sdim } 9013218822Sdim 9014218822Sdim shndx1 = _bfd_elf_section_from_bfd_section (bfd1, sec1); 9015218822Sdim shndx2 = _bfd_elf_section_from_bfd_section (bfd2, sec2); 9016218822Sdim if (shndx1 == -1 || shndx2 == -1) 9017218822Sdim return FALSE; 9018218822Sdim 9019218822Sdim bed1 = get_elf_backend_data (bfd1); 9020218822Sdim bed2 = get_elf_backend_data (bfd2); 9021218822Sdim hdr1 = &elf_tdata (bfd1)->symtab_hdr; 9022218822Sdim symcount1 = hdr1->sh_size / bed1->s->sizeof_sym; 9023218822Sdim hdr2 = &elf_tdata (bfd2)->symtab_hdr; 9024218822Sdim symcount2 = hdr2->sh_size / bed2->s->sizeof_sym; 9025218822Sdim 9026218822Sdim if (symcount1 == 0 || symcount2 == 0) 9027218822Sdim return FALSE; 9028218822Sdim 9029218822Sdim result = FALSE; 9030218822Sdim isymbuf1 = NULL; 9031218822Sdim isymbuf2 = NULL; 9032218822Sdim ssymbuf1 = elf_tdata (bfd1)->symbuf; 9033218822Sdim ssymbuf2 = elf_tdata (bfd2)->symbuf; 9034218822Sdim 9035218822Sdim if (ssymbuf1 == NULL) 9036218822Sdim { 9037218822Sdim isymbuf1 = bfd_elf_get_elf_syms (bfd1, hdr1, symcount1, 0, 9038218822Sdim NULL, NULL, NULL); 9039218822Sdim if (isymbuf1 == NULL) 9040218822Sdim goto done; 9041218822Sdim 9042218822Sdim if (!info->reduce_memory_overheads) 9043218822Sdim elf_tdata (bfd1)->symbuf = ssymbuf1 9044218822Sdim = elf_create_symbuf (symcount1, isymbuf1); 9045218822Sdim } 9046218822Sdim 9047218822Sdim if (ssymbuf1 == NULL || ssymbuf2 == NULL) 9048218822Sdim { 9049218822Sdim isymbuf2 = bfd_elf_get_elf_syms (bfd2, hdr2, symcount2, 0, 9050218822Sdim NULL, NULL, NULL); 9051218822Sdim if (isymbuf2 == NULL) 9052218822Sdim goto done; 9053218822Sdim 9054218822Sdim if (ssymbuf1 != NULL && !info->reduce_memory_overheads) 9055218822Sdim elf_tdata (bfd2)->symbuf = ssymbuf2 9056218822Sdim = elf_create_symbuf (symcount2, isymbuf2); 9057218822Sdim } 9058218822Sdim 9059218822Sdim if (ssymbuf1 != NULL && ssymbuf2 != NULL) 9060218822Sdim { 9061218822Sdim /* Optimized faster version. */ 9062218822Sdim bfd_size_type lo, hi, mid; 9063218822Sdim struct elf_symbol *symp; 9064218822Sdim struct elf_symbuf_symbol *ssym, *ssymend; 9065218822Sdim 9066218822Sdim lo = 0; 9067218822Sdim hi = ssymbuf1->count; 9068218822Sdim ssymbuf1++; 9069218822Sdim count1 = 0; 9070218822Sdim while (lo < hi) 9071218822Sdim { 9072218822Sdim mid = (lo + hi) / 2; 9073218822Sdim if ((unsigned int) shndx1 < ssymbuf1[mid].st_shndx) 9074218822Sdim hi = mid; 9075218822Sdim else if ((unsigned int) shndx1 > ssymbuf1[mid].st_shndx) 9076218822Sdim lo = mid + 1; 9077218822Sdim else 9078218822Sdim { 9079218822Sdim count1 = ssymbuf1[mid].count; 9080218822Sdim ssymbuf1 += mid; 9081218822Sdim break; 9082218822Sdim } 9083218822Sdim } 9084218822Sdim 9085218822Sdim lo = 0; 9086218822Sdim hi = ssymbuf2->count; 9087218822Sdim ssymbuf2++; 9088218822Sdim count2 = 0; 9089218822Sdim while (lo < hi) 9090218822Sdim { 9091218822Sdim mid = (lo + hi) / 2; 9092218822Sdim if ((unsigned int) shndx2 < ssymbuf2[mid].st_shndx) 9093218822Sdim hi = mid; 9094218822Sdim else if ((unsigned int) shndx2 > ssymbuf2[mid].st_shndx) 9095218822Sdim lo = mid + 1; 9096218822Sdim else 9097218822Sdim { 9098218822Sdim count2 = ssymbuf2[mid].count; 9099218822Sdim ssymbuf2 += mid; 9100218822Sdim break; 9101218822Sdim } 9102218822Sdim } 9103218822Sdim 9104218822Sdim if (count1 == 0 || count2 == 0 || count1 != count2) 9105218822Sdim goto done; 9106218822Sdim 9107218822Sdim symtable1 = bfd_malloc (count1 * sizeof (struct elf_symbol)); 9108218822Sdim symtable2 = bfd_malloc (count2 * sizeof (struct elf_symbol)); 9109218822Sdim if (symtable1 == NULL || symtable2 == NULL) 9110218822Sdim goto done; 9111218822Sdim 9112218822Sdim symp = symtable1; 9113218822Sdim for (ssym = ssymbuf1->ssym, ssymend = ssym + count1; 9114218822Sdim ssym < ssymend; ssym++, symp++) 9115218822Sdim { 9116218822Sdim symp->u.ssym = ssym; 9117218822Sdim symp->name = bfd_elf_string_from_elf_section (bfd1, 9118218822Sdim hdr1->sh_link, 9119218822Sdim ssym->st_name); 9120218822Sdim } 9121218822Sdim 9122218822Sdim symp = symtable2; 9123218822Sdim for (ssym = ssymbuf2->ssym, ssymend = ssym + count2; 9124218822Sdim ssym < ssymend; ssym++, symp++) 9125218822Sdim { 9126218822Sdim symp->u.ssym = ssym; 9127218822Sdim symp->name = bfd_elf_string_from_elf_section (bfd2, 9128218822Sdim hdr2->sh_link, 9129218822Sdim ssym->st_name); 9130218822Sdim } 9131218822Sdim 9132218822Sdim /* Sort symbol by name. */ 9133218822Sdim qsort (symtable1, count1, sizeof (struct elf_symbol), 9134218822Sdim elf_sym_name_compare); 9135218822Sdim qsort (symtable2, count1, sizeof (struct elf_symbol), 9136218822Sdim elf_sym_name_compare); 9137218822Sdim 9138218822Sdim for (i = 0; i < count1; i++) 9139218822Sdim /* Two symbols must have the same binding, type and name. */ 9140218822Sdim if (symtable1 [i].u.ssym->st_info != symtable2 [i].u.ssym->st_info 9141218822Sdim || symtable1 [i].u.ssym->st_other != symtable2 [i].u.ssym->st_other 9142218822Sdim || strcmp (symtable1 [i].name, symtable2 [i].name) != 0) 9143218822Sdim goto done; 9144218822Sdim 9145218822Sdim result = TRUE; 9146218822Sdim goto done; 9147218822Sdim } 9148218822Sdim 9149218822Sdim symtable1 = bfd_malloc (symcount1 * sizeof (struct elf_symbol)); 9150218822Sdim symtable2 = bfd_malloc (symcount2 * sizeof (struct elf_symbol)); 9151218822Sdim if (symtable1 == NULL || symtable2 == NULL) 9152218822Sdim goto done; 9153218822Sdim 9154218822Sdim /* Count definitions in the section. */ 9155218822Sdim count1 = 0; 9156218822Sdim for (isym = isymbuf1, isymend = isym + symcount1; isym < isymend; isym++) 9157218822Sdim if (isym->st_shndx == (unsigned int) shndx1) 9158218822Sdim symtable1[count1++].u.isym = isym; 9159218822Sdim 9160218822Sdim count2 = 0; 9161218822Sdim for (isym = isymbuf2, isymend = isym + symcount2; isym < isymend; isym++) 9162218822Sdim if (isym->st_shndx == (unsigned int) shndx2) 9163218822Sdim symtable2[count2++].u.isym = isym; 9164218822Sdim 9165218822Sdim if (count1 == 0 || count2 == 0 || count1 != count2) 9166218822Sdim goto done; 9167218822Sdim 9168218822Sdim for (i = 0; i < count1; i++) 9169218822Sdim symtable1[i].name 9170218822Sdim = bfd_elf_string_from_elf_section (bfd1, hdr1->sh_link, 9171218822Sdim symtable1[i].u.isym->st_name); 9172218822Sdim 9173218822Sdim for (i = 0; i < count2; i++) 9174218822Sdim symtable2[i].name 9175218822Sdim = bfd_elf_string_from_elf_section (bfd2, hdr2->sh_link, 9176218822Sdim symtable2[i].u.isym->st_name); 9177218822Sdim 9178218822Sdim /* Sort symbol by name. */ 9179218822Sdim qsort (symtable1, count1, sizeof (struct elf_symbol), 9180218822Sdim elf_sym_name_compare); 9181218822Sdim qsort (symtable2, count1, sizeof (struct elf_symbol), 9182218822Sdim elf_sym_name_compare); 9183218822Sdim 9184218822Sdim for (i = 0; i < count1; i++) 9185218822Sdim /* Two symbols must have the same binding, type and name. */ 9186218822Sdim if (symtable1 [i].u.isym->st_info != symtable2 [i].u.isym->st_info 9187218822Sdim || symtable1 [i].u.isym->st_other != symtable2 [i].u.isym->st_other 9188218822Sdim || strcmp (symtable1 [i].name, symtable2 [i].name) != 0) 9189218822Sdim goto done; 9190218822Sdim 9191218822Sdim result = TRUE; 9192218822Sdim 9193218822Sdimdone: 9194218822Sdim if (symtable1) 9195218822Sdim free (symtable1); 9196218822Sdim if (symtable2) 9197218822Sdim free (symtable2); 9198218822Sdim if (isymbuf1) 9199218822Sdim free (isymbuf1); 9200218822Sdim if (isymbuf2) 9201218822Sdim free (isymbuf2); 9202218822Sdim 9203218822Sdim return result; 9204218822Sdim} 9205218822Sdim 9206218822Sdim/* It is only used by x86-64 so far. */ 9207218822Sdimasection _bfd_elf_large_com_section 9208218822Sdim = BFD_FAKE_SECTION (_bfd_elf_large_com_section, 9209218822Sdim SEC_IS_COMMON, NULL, "LARGE_COMMON", 0); 9210218822Sdim 9211218822Sdim/* Return TRUE if 2 section types are compatible. */ 9212218822Sdim 9213218822Sdimbfd_boolean 9214218822Sdim_bfd_elf_match_sections_by_type (bfd *abfd, const asection *asec, 9215218822Sdim bfd *bbfd, const asection *bsec) 9216218822Sdim{ 9217218822Sdim if (asec == NULL 9218218822Sdim || bsec == NULL 9219218822Sdim || abfd->xvec->flavour != bfd_target_elf_flavour 9220218822Sdim || bbfd->xvec->flavour != bfd_target_elf_flavour) 9221218822Sdim return TRUE; 9222218822Sdim 9223218822Sdim return elf_section_type (asec) == elf_section_type (bsec); 9224218822Sdim} 9225218822Sdim 9226218822Sdimvoid 9227218822Sdim_bfd_elf_set_osabi (bfd * abfd, 9228218822Sdim struct bfd_link_info * link_info ATTRIBUTE_UNUSED) 9229218822Sdim{ 9230218822Sdim Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */ 9231218822Sdim 9232218822Sdim i_ehdrp = elf_elfheader (abfd); 9233218822Sdim 9234218822Sdim i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi; 9235218822Sdim} 9236218822Sdim 9237218822Sdim 9238218822Sdim/* Return TRUE for ELF symbol types that represent functions. 9239218822Sdim This is the default version of this function, which is sufficient for 9240218822Sdim most targets. It returns true if TYPE is STT_FUNC. */ 9241218822Sdim 9242218822Sdimbfd_boolean 9243218822Sdim_bfd_elf_is_function_type (unsigned int type) 9244218822Sdim{ 9245218822Sdim return (type == STT_FUNC); 9246218822Sdim} 9247